From e9e026ac2e06273c5d682b8da5356dfc82a9ec1e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 8 Sep 2023 12:41:48 +0200 Subject: [PATCH] Initial commit --- .editorconfig | 24 - .github/CONTRIBUTING.md | 45 - .github/ISSUE_TEMPLATE.md | 20 - .github/ISSUE_TEMPLATE/bug_report.md | 17 - .github/ISSUE_TEMPLATE/feature_request.md | 20 - .github/workflows/deploy-docs.yml | 53 + .github/workflows/maven.yml | 42 - .gitignore | 38 +- .java-version | 1 - .mvn/maven.config | 1 - .sdkmanrc | 3 - .settings.xml | 68 -- .springformat | 0 LICENSE.txt | 202 ---- README.adoc | 340 +----- ...antora-playbook.yml => antora-playbook.yml | 30 +- docs/.github/workflows/deploy-docs.yml | 32 - docs/antora.yml | 12 - docs/modules/ROOT/nav.adoc | 19 - docs/modules/ROOT/pages/README.adoc | 12 - docs/modules/ROOT/pages/_attributes.adoc | 14 - docs/modules/ROOT/pages/_configprops.adoc | 83 -- docs/modules/ROOT/pages/_observability.adoc | 9 - docs/modules/ROOT/pages/appendix.adoc | 14 - docs/modules/ROOT/pages/index.adoc | 0 docs/modules/ROOT/pages/intro.adoc | 9 - docs/modules/ROOT/pages/jce.adoc | 8 - docs/modules/ROOT/pages/sagan-boot.adoc | 0 docs/modules/ROOT/pages/sagan-index.adoc | 16 - .../pages/spring-cloud-circuitbreaker.adoc | 110 -- .../ROOT/pages/spring-cloud-commons.adoc | 10 - .../cachedrandompropertysource.adoc | 17 - .../spring-cloud-commons/circuit-breaker.adoc | 6 - .../commons:-common-abstractions.adoc | 623 ---------- .../configuration-properties.adoc | 5 - ...context:-application-context-services.adoc | 255 ----- .../spring-cloud-commons/loadbalancer.adoc | 517 --------- .../pages/spring-cloud-commons/security.adoc | 89 -- docs/pom.xml | 105 -- docs/src/main/asciidoc/ghpages.sh | 330 ------ eclipse/eclipse-code-formatter.xml | 804 ------------- eclipse/org.eclipse.jdt.core.prefs | 412 ------- eclipse/org.eclipse.jdt.ui.prefs | 125 -- pom.xml | 232 +--- spring-cloud-commons-dependencies/pom.xml | 129 --- spring-cloud-commons/README.md | 3 - .../eclipse/eclipse-code-formatter.xml | 754 ------------ .../eclipse/org.eclipse.jdt.core.prefs | 389 ------- .../eclipse/org.eclipse.jdt.ui.prefs | 125 -- spring-cloud-commons/pom.xml | 191 ---- .../CommonsClientAutoConfiguration.java | 101 -- ...ConditionalOnBlockingDiscoveryEnabled.java | 42 - .../client/ConditionalOnDiscoveryEnabled.java | 41 - ...onalOnDiscoveryHealthIndicatorEnabled.java | 42 - ...ConditionalOnReactiveDiscoveryEnabled.java | 45 - .../cloud/client/DefaultServiceInstance.java | 186 --- .../HostInfoEnvironmentPostProcessor.java | 65 -- ...eactiveCommonsClientAutoConfiguration.java | 70 -- .../cloud/client/ServiceInstance.java | 74 -- .../client/actuator/FeaturesEndpoint.java | 179 --- .../cloud/client/actuator/HasFeatures.java | 62 - .../cloud/client/actuator/NamedFeature.java | 41 - .../AbstractCircuitBreakerFactory.java | 68 -- .../client/circuitbreaker/CircuitBreaker.java | 37 - .../circuitbreaker/CircuitBreakerFactory.java | 34 - .../client/circuitbreaker/ConfigBuilder.java | 28 - .../client/circuitbreaker/Customizer.java | 53 - .../NoFallbackAvailableException.java | 30 - .../ReactiveCircuitBreaker.java | 47 - .../ReactiveCircuitBreakerFactory.java | 34 - .../CircuitBreakerObservationContext.java | 64 -- .../CircuitBreakerObservationConvention.java | 35 - ...ircuitBreakerObservationDocumentation.java | 83 -- ...ltCircuitBreakerObservationConvention.java | 55 - .../observation/ObservedCircuitBreaker.java | 67 -- .../observation/ObservedFunction.java | 51 - .../observation/ObservedSupplier.java | 51 - .../client/discovery/DiscoveryClient.java | 79 -- .../discovery/EnableDiscoveryClient.java | 45 - .../EnableDiscoveryClientImportSelector.java | 77 -- .../discovery/ManagementServerPortUtils.java | 144 --- .../discovery/ReactiveDiscoveryClient.java | 107 -- .../composite/CompositeDiscoveryClient.java | 90 -- ...ositeDiscoveryClientAutoConfiguration.java | 44 - .../ReactiveCompositeDiscoveryClient.java | 73 -- ...ositeDiscoveryClientAutoConfiguration.java | 46 - .../discovery/event/HeartbeatEvent.java | 57 - .../discovery/event/HeartbeatMonitor.java | 43 - .../event/InstancePreRegisteredEvent.java | 49 - .../event/InstanceRegisteredEvent.java | 47 - .../discovery/event/ParentHeartbeatEvent.java | 45 - .../DiscoveryClientHealthIndicator.java | 106 -- ...coveryClientHealthIndicatorProperties.java | 70 -- .../DiscoveryCompositeHealthContributor.java | 83 -- .../health/DiscoveryHealthIndicator.java | 35 - ...eactiveDiscoveryClientHealthIndicator.java | 134 --- ...veDiscoveryCompositeHealthContributor.java | 76 -- .../ReactiveDiscoveryHealthIndicator.java | 43 - .../simple/SimpleDiscoveryClient.java | 68 -- ...impleDiscoveryClientAutoConfiguration.java | 96 -- .../simple/SimpleDiscoveryProperties.java | 90 -- .../SimpleReactiveDiscoveryClient.java | 58 - ...ctiveDiscoveryClientAutoConfiguration.java | 116 -- .../SimpleReactiveDiscoveryProperties.java | 91 -- .../CloudHypermediaAutoConfiguration.java | 104 -- .../client/hypermedia/DiscoveredResource.java | 153 --- .../DynamicServiceInstanceProvider.java | 61 - .../client/hypermedia/RemoteResource.java | 42 - .../hypermedia/RemoteResourceRefresher.java | 63 - .../hypermedia/ServiceInstanceProvider.java | 37 - .../StaticServiceInstanceProvider.java | 45 - .../hypermedia/TraversalDefinition.java | 34 - .../BlockingLoadBalancerRequest.java | 79 -- ...ClientHttpResponseStatusCodeException.java | 93 -- .../loadbalancer/CompletionContext.java | 111 -- .../client/loadbalancer/DefaultRequest.java | 73 -- .../loadbalancer/DefaultRequestContext.java | 76 -- .../client/loadbalancer/DefaultResponse.java | 69 -- .../client/loadbalancer/EmptyResponse.java | 36 - .../loadbalancer/HintRequestContext.java | 86 -- .../HttpRequestLoadBalancerRequest.java | 31 - .../loadbalancer/InterceptorRetryPolicy.java | 122 -- .../client/loadbalancer/LoadBalanced.java | 40 - .../LoadBalancedRecoveryCallback.java | 58 - .../LoadBalancedRetryContext.java | 89 -- .../LoadBalancedRetryFactory.java | 58 - .../loadbalancer/LoadBalancedRetryPolicy.java | 76 -- .../LoadBalancerAutoConfiguration.java | 169 --- .../loadbalancer/LoadBalancerClient.java | 69 -- .../LoadBalancerClientsProperties.java | 43 - ...aultMappingsProviderAutoConfiguration.java | 46 - .../LoadBalancerEagerLoadProperties.java | 40 - .../loadbalancer/LoadBalancerInterceptor.java | 59 - .../loadbalancer/LoadBalancerLifecycle.java | 64 -- .../LoadBalancerLifecycleValidator.java | 49 - .../loadbalancer/LoadBalancerProperties.java | 493 -------- .../loadbalancer/LoadBalancerRequest.java | 32 - .../LoadBalancerRequestAdapter.java | 46 - .../LoadBalancerRequestFactory.java | 58 - .../LoadBalancerRequestTransformer.java | 39 - .../loadbalancer/LoadBalancerUriTools.java | 118 -- .../cloud/client/loadbalancer/Request.java | 34 - .../client/loadbalancer/RequestData.java | 156 --- .../loadbalancer/RequestDataContext.java | 49 - .../cloud/client/loadbalancer/Response.java | 31 - .../client/loadbalancer/ResponseData.java | 131 --- .../loadbalancer/RestTemplateCustomizer.java | 28 - .../RetryLoadBalancerInterceptor.java | 170 --- .../loadbalancer/RetryableRequestContext.java | 83 -- .../RetryableStatusCodeException.java | 49 - .../loadbalancer/ServiceInstanceChooser.java | 47 - .../loadbalancer/ServiceRequestWrapper.java | 46 - .../loadbalancer/TimedRequestContext.java | 31 - ...ingLoadBalancerExchangeFilterFunction.java | 68 -- .../reactive/ExchangeFilterFunctionUtils.java | 71 -- .../LoadBalancedExchangeFilterFunction.java | 29 - ...cerBeanPostProcessorAutoConfiguration.java | 86 -- .../LoadBalancerClientRequestTransformer.java | 39 - .../reactive/LoadBalancerRetryContext.java | 128 --- .../reactive/LoadBalancerRetryPolicy.java | 70 -- ...ncerWebClientBuilderBeanPostProcessor.java | 56 - .../reactive/ReactiveLoadBalancer.java | 87 -- ...orLoadBalancerClientAutoConfiguration.java | 79 -- ...torLoadBalancerExchangeFilterFunction.java | 131 --- ...FilterFunctionLoadBalancerRetryPolicy.java | 83 -- ...bleLoadBalancerExchangeFilterFunction.java | 219 ---- .../RetryableStatusCodeException.java | 28 - .../reactive/WebClientCustomizer.java | 43 - .../AbstractAutoServiceRegistration.java | 315 ----- .../AutoServiceRegistration.java | 24 - ...oServiceRegistrationAutoConfiguration.java | 47 - .../AutoServiceRegistrationConfiguration.java | 31 - .../AutoServiceRegistrationProperties.java | 67 -- .../client/serviceregistry/Registration.java | 29 - .../RegistrationLifecycle.java | 66 -- .../RegistrationManagementLifecycle.java | 55 - .../serviceregistry/ServiceRegistry.java | 64 -- .../ServiceRegistryAutoConfiguration.java | 51 - .../endpoint/ServiceRegistryEndpoint.java | 70 -- ...igDataMissingEnvironmentPostProcessor.java | 144 --- .../CommonsConfigAutoConfiguration.java | 47 - .../config/DefaultsBindHandlerAdvisor.java | 90 -- .../cloud/commons/publisher/CloudFlux.java | 62 - .../publisher/FluxFirstNonEmptyEmitting.java | 336 ------ .../security/AccessTokenContextRelay.java | 56 - ...urceServerTokenRelayAutoConfiguration.java | 117 -- .../cloud/commons/util/IdUtils.java | 112 -- .../cloud/commons/util/InetUtils.java | 240 ---- .../commons/util/InetUtilsProperties.java | 123 -- .../util/SpringFactoryImportSelector.java | 119 -- .../commons/util/TaskSchedulerWrapper.java | 58 - .../commons/util/UtilAutoConfiguration.java | 46 - .../CompatibilityNotMetException.java | 39 - .../CompatibilityNotMetFailureAnalyzer.java | 64 -- .../configuration/CompatibilityPredicate.java | 28 - .../configuration/CompatibilityVerifier.java | 30 - ...ompatibilityVerifierAutoConfiguration.java | 58 - .../CompatibilityVerifierProperties.java | 57 - .../CompositeCompatibilityVerifier.java | 61 - .../configuration/SSLContextFactory.java | 117 -- .../configuration/SleuthPresentVerifier.java | 48 - .../SpringBootVersionVerifier.java | 173 --- .../cloud/configuration/TlsProperties.java | 149 --- .../configuration/VerificationResult.java | 82 -- ...itional-spring-configuration-metadata.json | 175 --- .../main/resources/META-INF/spring.factories | 6 - ...ot.autoconfigure.AutoConfiguration.imports | 17 - .../CommonsClientAutoConfigurationTests.java | 159 --- ...HostInfoEnvironmentPostProcessorTests.java | 49 - ...veCommonsClientAutoConfigurationTests.java | 157 --- .../actuator/FeaturesEndpointTests.java | 113 -- .../circuitbreaker/CustomizerTests.java | 41 - .../ObservedCircuitBreakerTests.java | 122 -- .../AutoRegisterPropertyFalseTests.java | 64 -- ...DiscoveryClientAutoRegisterFalseTests.java | 65 -- ...bleDiscoveryClientImportSelectorTests.java | 79 -- ...EnableDiscoveryClientMissingImplTests.java | 60 - .../ManagementServerPortUtilsTests.java | 48 - ...DiscoveryClientAutoConfigurationTests.java | 89 -- .../CompositeDiscoveryClientOrderTest.java | 70 -- .../CompositeDiscoveryClientTests.java | 83 -- .../CompositeDiscoveryClientTestsConfig.java | 90 -- .../CompositeDiscoveryClientUnitTests.java | 101 -- ...DiscoveryClientAutoConfigurationTests.java | 84 -- ...ReactiveCompositeDiscoveryClientTests.java | 117 -- .../event/HeartbeatMonitorTests.java | 53 - .../DiscoveryClientHealthIndicatorTests.java | 113 -- ...scoveryClientHealthIndicatorUnitTests.java | 139 --- ...coveryCompositeHealthContributorTests.java | 103 -- ...veDiscoveryClientHealthIndicatorTests.java | 188 --- ...coveryCompositeHealthContributorTests.java | 77 -- ...ryClientAutoConfigurationDefaultTests.java | 52 - ...overyPropertiesAutoConfigurationTests.java | 54 - ...overyPropertiesAutoConfigurationTests.java | 53 - ...DiscoveryClientPropertiesMappingTests.java | 95 -- .../simple/SimpleDiscoveryClientTests.java | 82 -- ...DiscoveryClientAutoConfigurationTests.java | 83 -- .../SimpleReactiveDiscoveryClientTests.java | 78 -- ...ediaAutoConfigurationIntegrationTests.java | 103 -- .../DiscoveredResourceUnitTests.java | 122 -- ...namicServiceInstanceProviderUnitTests.java | 59 - ...actLoadBalancerAutoConfigurationTests.java | 207 ---- ...ntHttpResponseStatusCodeExceptionTest.java | 90 -- .../InterceptorRetryPolicyTest.java | 158 --- .../LoadBalancedRetryContextTest.java | 76 -- .../LoadBalancerAutoConfigurationTests.java | 41 - ...ancerRequestFactoryConfigurationTests.java | 171 --- .../LoadBalancerRequestFactoryTests.java | 134 --- .../LoadBalancerUriToolsTests.java | 248 ---- ...tryLoadBalancerAutoConfigurationTests.java | 61 - .../RetryLoadBalancerInterceptorTests.java | 600 ---------- ...coveryClientBasedReactiveLoadBalancer.java | 82 -- ...dBalancerClientRequestTransformerTest.java | 117 -- .../reactive/LoadBalancerTestUtils.java | 69 -- ...dBalancerClientAutoConfigurationTests.java | 249 ---- ...adBalancerExchangeFilterFunctionTests.java | 262 ----- ...xchangeFilterFunctionIntegrationTests.java | 328 ------ ...adBalancerExchangeFilterFunctionTests.java | 211 ---- .../reactive/TestReactiveLoadBalancer.java | 52 - ...oServiceRegistrationMgmtDisabledTests.java | 206 ---- ...egistrationRegistrationLifecycleTests.java | 258 ----- .../AbstractAutoServiceRegistrationTests.java | 286 ----- ...iceRegistrationAutoConfigurationTests.java | 99 -- ...ServiceRegistryAutoConfigurationTests.java | 54 - ...ceRegistryEndpointNoRegistrationTests.java | 79 -- .../ServiceRegistryEndpointTests.java | 169 --- ...aMissingEnvironmentPostProcessorTests.java | 128 --- .../FluxFirstNonEmptyEmittingTests.java | 185 --- ...erverTokenRelayAutoConfigurationTests.java | 99 -- .../ResourceServerTokenRelayTests.java | 136 --- .../cloud/commons/util/IdUtilsTests.java | 187 --- .../cloud/commons/util/InetUtilsTests.java | 136 --- .../SpringFactoryImportSelectorTests.java | 47 - ...ibilityVerifierAutoConfigurationTests.java | 88 -- ...erifierDisabledAutoConfigurationTests.java | 48 - ...VerifierFailureAutoConfigurationTests.java | 54 - .../CompatibilityVerifierTests.java | 62 - .../configuration/SSHContextFactoryTests.java | 93 -- .../SleuthPresentVerifierTests.java | 49 - .../SpringBootDependencyTests.java | 258 ----- .../src/test/resources/MyCA.p12 | Bin 822 -> 0 bytes .../src/test/resources/MyCert.p12 | Bin 1736 -> 0 bytes .../resources/application-encrypt.properties | 2 - .../src/test/resources/application.properties | 12 - .../resources/bootstrap-encrypt.properties | 1 - .../resources/bootstrap-parent.properties | 1 - .../src/test/resources/bootstrap.properties | 3 - .../external-properties/bootstrap.properties | 1 - .../src/test/resources/other.properties | 1 - .../src/test/resources/plain.properties | 1 - .../src/test/resources/server.jks | Bin 2239 -> 0 bytes .../pom.xml | 92 -- .../integration/JdbcConfigurationTests.java | 53 - .../RefreshScopeIntegrationTests.java | 264 ----- .../src/test/resources/application.properties | 8 - .../src/test/resources/bootstrap.properties | 1 - .../src/test/resources/data.sql | 7 - .../src/test/resources/schema.sql | 4 - .../pom.xml | 62 - ...ebfluxRefreshEndpointIntegrationTests.java | 66 -- .../src/test/resources/application.properties | 1 - .../src/test/resources/bootstrap.properties | 1 - spring-cloud-context/README.md | 3 - .../eclipse/eclipse-code-formatter.xml | 754 ------------ .../eclipse/org.eclipse.jdt.core.prefs | 389 ------- .../eclipse/org.eclipse.jdt.ui.prefs | 125 -- spring-cloud-context/pom.xml | 86 -- ...onPropertiesRebinderAutoConfiguration.java | 78 -- ...LifecycleMvcEndpointAutoConfiguration.java | 45 - .../RefreshAutoConfiguration.java | 259 ----- .../RefreshEndpointAutoConfiguration.java | 166 --- ...eEnvironmentEndpointAutoConfiguration.java | 78 -- .../BootstrapApplicationListener.java | 509 --------- ...ootstrapConfigFileApplicationListener.java | 1011 ----------------- .../bootstrap/BootstrapConfiguration.java | 43 - .../bootstrap/BootstrapImportSelector.java | 140 --- .../BootstrapImportSelectorConfiguration.java | 31 - .../LoggingSystemShutdownListener.java | 64 -- .../RefreshBootstrapRegistryInitializer.java | 42 - .../bootstrap/TextEncryptorBindHandler.java | 86 -- .../TextEncryptorConfigBootstrapper.java | 88 -- .../config/BootstrapPropertySource.java | 59 - .../PropertySourceBootstrapConfiguration.java | 338 ------ .../PropertySourceBootstrapProperties.java | 86 -- .../config/PropertySourceLocator.java | 69 -- .../config/SimpleBootstrapPropertySource.java | 46 - .../encrypt/AbstractEnvironmentDecrypt.java | 164 --- .../DecryptEnvironmentPostProcessor.java | 78 -- .../EncryptionBootstrapConfiguration.java | 159 --- ...ironmentDecryptApplicationInitializer.java | 160 --- .../bootstrap/encrypt/KeyProperties.java | 162 --- .../bootstrap/encrypt/RsaProperties.java | 79 -- .../bootstrap/encrypt/TextEncryptorUtils.java | 194 ---- .../OriginTrackedCompositePropertySource.java | 48 - .../ContextRefreshedWithApplicationEvent.java | 52 - .../config/annotation/RefreshScope.java | 53 - .../context/encrypt/EncryptorFactory.java | 54 - .../context/encrypt/KeyFormatException.java | 35 - .../environment/EnvironmentChangeEvent.java | 52 - .../environment/EnvironmentManager.java | 108 -- .../WritableEnvironmentEndpoint.java | 38 - ...itableEnvironmentEndpointWebExtension.java | 62 - .../named/ClientFactoryObjectProvider.java | 120 -- .../context/named/NamedContextFactory.java | 256 ----- .../ConfigurationPropertiesBeans.java | 109 -- .../ConfigurationPropertiesRebinder.java | 174 --- .../refresh/ConfigDataContextRefresher.java | 144 --- .../context/refresh/ContextRefresher.java | 205 ---- .../refresh/LegacyContextRefresher.java | 128 --- .../cloud/context/restart/PauseHandler.java | 28 - .../context/restart/RestartEndpoint.java | 259 ----- .../context/restart/RestartListener.java | 80 -- .../cloud/context/scope/GenericScope.java | 504 -------- .../cloud/context/scope/ScopeCache.java | 62 - .../context/scope/StandardScopeCache.java | 60 - .../context/scope/refresh/RefreshScope.java | 176 --- .../refresh/RefreshScopeRefreshedEvent.java | 47 - .../scope/thread/ThreadLocalScopeCache.java | 61 - .../context/scope/thread/ThreadScope.java | 37 - .../cloud/endpoint/RefreshEndpoint.java | 45 - .../cloud/endpoint/event/RefreshEvent.java | 48 - .../endpoint/event/RefreshEventListener.java | 77 -- .../cloud/env/EnvironmentUtils.java | 40 - .../health/RefreshScopeHealthIndicator.java | 69 -- .../cloud/logging/LoggingRebinder.java | 95 -- .../util/ConditionalOnBootstrapDisabled.java | 63 - .../util/ConditionalOnBootstrapEnabled.java | 62 - .../cloud/util/PropertyUtils.java | 56 - .../cloud/util/ProxyUtils.java | 49 - .../random/CachedRandomPropertySource.java | 105 -- ...ropertySourceEnvironmentPostProcessor.java | 60 - ...itional-spring-configuration-metadata.json | 59 - .../main/resources/META-INF/spring.factories | 20 - .../resources/META-INF/spring/aot.factories | 2 - ...ot.autoconfigure.AutoConfiguration.imports | 5 - .../LifecycleMvcAutoConfigurationTests.java | 162 --- ...efreshAutoConfigurationClassPathTests.java | 56 - ...shAutoConfigurationMoreClassPathTests.java | 61 - .../RefreshAutoConfigurationTests.java | 143 --- ...bledAutoConfigurationIntegrationTests.java | 47 - ...ringAutoConfigurationIntegrationTests.java | 61 - ...rrideSystemPropertiesIntegrationTests.java | 90 -- ...gCustomPropertySourceIntegrationTests.java | 79 -- ...SpringApplicationJsonIntegrationTests.java | 59 - .../BootstrapSourcesOrderingTests.java | 45 - .../MessageSourceConfigurationTests.java | 54 - .../bootstrap/TestBootstrapConfiguration.java | 70 -- ...tHigherPriorityBootstrapConfiguration.java | 39 - .../config/BootstrapConfigurationTests.java | 799 ------------- ...trapListenerHierarchyIntegrationTests.java | 98 -- ...EncryptionBootstrapConfigurationTests.java | 106 -- .../encrypt/EncryptionIntegrationTests.java | 173 --- .../encrypt/EncryptorFactoryTests.java | 57 - ...entDecryptApplicationInitializerTests.java | 265 ----- .../bootstrap/encrypt/RsaDisabledTests.java | 60 - .../EnvironmentManagerIntegrationTests.java | 156 --- .../environment/EnvironmentManagerTest.java | 60 - .../named/NamedContextFactoryTests.java | 253 ----- ...ionPropertiesRebinderIntegrationTests.java | 206 ---- ...tiesRebinderLifecycleIntegrationTests.java | 119 -- ...ropertiesRebinderListIntegrationTests.java | 147 --- ...opertiesRebinderProxyIntegrationTests.java | 121 -- ...sRebinderRefreshScopeIntegrationTests.java | 135 --- ...gDataContextRefresherIntegrationTests.java | 188 --- .../ContextRefresherIntegrationTests.java | 146 --- ...textRefresherOrderingIntegrationTests.java | 119 -- .../refresh/ContextRefresherTests.java | 224 ---- .../restart/RestartIntegrationTests.java | 79 -- .../ImportRefreshScopeIntegrationTests.java | 69 -- .../MoreRefreshScopeIntegrationTests.java | 233 ---- .../RefreshEndpointIntegrationTests.java | 121 -- .../refresh/RefreshScopeConcurrencyTests.java | 192 ---- .../RefreshScopeConfigurationScaleTests.java | 201 ---- .../RefreshScopeConfigurationTests.java | 174 --- .../refresh/RefreshScopeIntegrationTests.java | 262 ----- .../RefreshScopeLazyIntegrationTests.java | 252 ---- ...freshScopeListBindingIntegrationTests.java | 119 -- .../RefreshScopeNullBeanIntegrationTests.java | 90 -- .../refresh/RefreshScopePureScaleTests.java | 159 --- .../scope/refresh/RefreshScopeScaleTests.java | 195 ---- .../RefreshScopeSerializationTests.java | 78 -- .../RefreshScopeWebIntegrationTests.java | 101 -- .../context/test/TestConfigDataLoader.java | 36 - .../test/TestConfigDataLocationResolver.java | 64 -- .../context/test/TestConfigDataResource.java | 49 - .../context/test/TestEnvPostProcessor.java | 51 - .../cloud/endpoint/RefreshEndpointTests.java | 200 ---- .../RefreshScopeHealthIndicatorTests.java | 86 -- .../cloud/logging/LoggingRebinderTests.java | 85 -- .../CachedRandomPropertySourceTests.java | 111 -- .../test/resources/META-INF/spring.factories | 15 - .../resources/application-config.properties | 1 - .../resources/application-encrypt.properties | 1 - .../resources/application-local.properties | 1 - .../resources/application-override.properties | 1 - .../src/test/resources/application.properties | 10 - .../resources/bootstrap-config.properties | 2 - .../resources/bootstrap-encrypt.properties | 1 - .../resources/bootstrap-epptests.properties | 1 - .../resources/bootstrap-parent.properties | 1 - .../resources/bootstrap-refresh.properties | 2 - .../src/test/resources/bootstrap.properties | 5 - .../src/test/resources/custom.properties | 1 - .../resources/example-test-rsa-private-key | 25 - .../external-properties/bootstrap.properties | 2 - .../src/test/resources/local.properties | 1 - .../src/test/resources/messages.properties | 1 - .../test/resources/nonenumerable.properties | 1 - .../src/test/resources/ordering.properties | 1 - .../src/test/resources/other.properties | 1 - .../src/test/resources/plain.properties | 1 - .../src/test/resources/server.jks | Bin 2239 -> 0 bytes .../src/test/resources/server.p12 | Bin 2421 -> 0 bytes spring-cloud-loadbalancer/pom.xml | 147 --- .../annotation/LoadBalancerClient.java | 70 -- .../LoadBalancerClientConfiguration.java | 356 ------ ...dBalancerClientConfigurationRegistrar.java | 82 -- .../LoadBalancerClientSpecification.java | 90 -- .../annotation/LoadBalancerClients.java | 54 - .../LoadBalancerChildContextInitializer.java | 137 --- .../XForwardedHeadersTransformer.java | 59 - .../client/BlockingLoadBalancerClient.java | 177 --- .../BlockingLoadBalancedRetryFactory.java | 46 - .../BlockingLoadBalancedRetryPolicy.java | 104 -- ...CaffeineBasedLoadBalancerCacheManager.java | 54 - .../cache/DefaultLoadBalancerCache.java | 171 --- .../DefaultLoadBalancerCacheManager.java | 93 -- .../cache/LoadBalancerCacheManager.java | 29 - .../cache/LoadBalancerCacheProperties.java | 95 -- ...ngLoadBalancerClientAutoConfiguration.java | 94 -- .../config/LoadBalancerAutoConfiguration.java | 80 -- .../LoadBalancerCacheAutoConfiguration.java | 212 ---- .../LoadBalancerStatsAutoConfiguration.java | 45 - .../config/LoadBalancerZoneConfig.java | 42 - .../CachingServiceInstanceListSupplier.java | 88 -- ...DelegatingServiceInstanceListSupplier.java | 72 -- ...veryClientServiceInstanceListSupplier.java | 117 -- ...ealthCheckServiceInstanceListSupplier.java | 160 --- .../HintBasedServiceInstanceListSupplier.java | 103 -- .../core/LazyWeightedServiceInstanceList.java | 147 --- ...ancerServiceInstanceCookieTransformer.java | 70 -- .../core/NoopServiceInstanceListSupplier.java | 49 - .../loadbalancer/core/RandomLoadBalancer.java | 90 -- .../core/ReactorLoadBalancer.java | 45 - .../ReactorServiceInstanceLoadBalancer.java | 30 - ...ckySessionServiceInstanceListSupplier.java | 102 -- ...RetryAwareServiceInstanceListSupplier.java | 84 -- .../core/RoundRobinLoadBalancer.java | 118 -- ...PreferenceServiceInstanceListSupplier.java | 101 -- .../core/SelectedInstanceCallback.java | 36 - .../core/ServiceInstanceListSupplier.java | 45 - .../ServiceInstanceListSupplierBuilder.java | 389 ------- .../loadbalancer/core/WeightFunction.java | 41 - .../WeightedServiceInstanceListSupplier.java | 128 --- .../core/XForwardedHeadersTransformer.java | 59 - ...PreferenceServiceInstanceListSupplier.java | 107 -- ...h2LoadBalancerClientAutoConfiguration.java | 70 -- .../loadbalancer/stats/LoadBalancerTags.java | 159 --- .../MicrometerStatsLoadBalancerLifecycle.java | 121 -- .../support/LoadBalancerClientFactory.java | 111 -- .../LoadBalancerEagerContextInitializer.java | 43 - .../LoadBalancerEnvironmentPropertyUtils.java | 70 -- .../support/ServiceInstanceListSuppliers.java | 59 - .../support/SimpleObjectProvider.java | 56 - ...itional-spring-configuration-metadata.json | 49 - .../resources/META-INF/spring/aot.factories | 2 - ...ot.autoconfigure.AutoConfiguration.imports | 5 - .../LoadBalancerClientConfigurationTests.java | 240 ---- ...dBalancerChildContextInitializerTests.java | 158 --- .../XForwardedHeadersTransformerTests.java | 85 -- .../BlockingLoadBalancerClientTests.java | 320 ------ .../BlockingLoadBalancedRetryPolicyTests.java | 124 -- .../DefaultLoadBalancerCacheManagerTests.java | 69 -- .../cache/DefaultLoadBalancerCacheTests.java | 72 -- ...dBalancerClientAutoConfigurationTests.java | 63 - ...adBalancerCacheAutoConfigurationTests.java | 202 ---- ...chingServiceInstanceListSupplierTests.java | 156 --- ...lientServiceInstanceListSupplierTests.java | 168 --- ...CheckServiceInstanceListSupplierTests.java | 706 ------------ ...BasedServiceInstanceListSupplierTests.java | 147 --- .../LazyWeightedServiceInstanceListTest.java | 140 --- ...ServiceInstanceCookieTransformerTests.java | 97 -- .../core/LoadBalancerTestUtils.java | 39 - .../loadbalancer/core/LoadBalancerTests.java | 197 ---- .../core/RandomLoadBalancerTests.java | 92 -- ...ssionServiceInstanceListSupplierTests.java | 124 -- ...AwareServiceInstanceListSupplierTests.java | 95 -- .../core/RoundRobinLoadBalancerTests.java | 108 -- ...renceServiceInstanceListSupplierTests.java | 124 -- ...rviceInstanceListSupplierBuilderTests.java | 104 -- ...ServiceInstanceListSuppliersTestUtils.java | 64 -- .../TestSelectedServiceInstanceSupplier.java | 28 - ...ghtedServiceInstanceListSupplierTests.java | 220 ---- .../XForwardedHeadersTransformerTests.java | 86 -- ...renceServiceInstanceListSupplierTests.java | 143 --- ...dBalancerClientAutoConfigurationTests.java | 94 -- ...ometerStatsLoadBalancerLifecycleTests.java | 182 --- ...adBalancerEagerContextInitializerTest.java | 87 -- ...BalancerEnvironmentPropertyUtilsTests.java | 85 -- .../src/test/resources/application.yml | 31 - .../src/test/resources/logback-test.xml | 11 - spring-cloud-starter-bootstrap/pom.xml | 41 - .../cloud/bootstrap/marker/Marker.java | 29 - .../cloud/bootstrap/marker/MarkerTests.java | 46 - .../src/test/resources/bootstrap.properties | 1 - spring-cloud-starter-loadbalancer/pom.xml | 43 - spring-cloud-starter/pom.xml | 44 - spring-cloud-test-support/README.md | 3 - .../eclipse/eclipse-code-formatter.xml | 754 ------------ .../eclipse/org.eclipse.jdt.core.prefs | 389 ------- .../eclipse/org.eclipse.jdt.ui.prefs | 125 -- spring-cloud-test-support/pom.xml | 100 -- .../cloud/test/ClassPathExclusions.java | 45 - .../cloud/test/ClassPathOverrides.java | 45 - .../test/ModifiedClassPathClassLoader.java | 310 ----- .../test/ModifiedClassPathExtension.java | 140 --- .../cloud/test/ModifiedClassPathRunner.java | 366 ------ .../cloud/test/TestSocketUtils.java | 303 ----- ...odifiedClassPathRunnerExclusionsTests.java | 51 - ...ModifiedClassPathRunnerOverridesTests.java | 46 - .../cloud/test/TestSocketUtilsTests.java | 220 ---- src/checkstyle/checkstyle-suppressions.xml | 22 - supplemental-ui/partials/nav-search.hbs | 11 + supplemental-ui/partials/search.hbs | 27 + 564 files changed, 187 insertions(+), 57745 deletions(-) delete mode 100644 .editorconfig delete mode 100644 .github/CONTRIBUTING.md delete mode 100644 .github/ISSUE_TEMPLATE.md delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/workflows/deploy-docs.yml delete mode 100644 .github/workflows/maven.yml delete mode 100644 .java-version delete mode 100644 .mvn/maven.config delete mode 100644 .sdkmanrc delete mode 100644 .settings.xml delete mode 100644 .springformat delete mode 100644 LICENSE.txt rename docs/antora-playbook.yml => antora-playbook.yml (62%) delete mode 100644 docs/.github/workflows/deploy-docs.yml delete mode 100644 docs/antora.yml delete mode 100644 docs/modules/ROOT/nav.adoc delete mode 100644 docs/modules/ROOT/pages/README.adoc delete mode 100644 docs/modules/ROOT/pages/_attributes.adoc delete mode 100644 docs/modules/ROOT/pages/_configprops.adoc delete mode 100644 docs/modules/ROOT/pages/_observability.adoc delete mode 100644 docs/modules/ROOT/pages/appendix.adoc delete mode 100644 docs/modules/ROOT/pages/index.adoc delete mode 100644 docs/modules/ROOT/pages/intro.adoc delete mode 100644 docs/modules/ROOT/pages/jce.adoc delete mode 100644 docs/modules/ROOT/pages/sagan-boot.adoc delete mode 100644 docs/modules/ROOT/pages/sagan-index.adoc delete mode 100755 docs/modules/ROOT/pages/spring-cloud-circuitbreaker.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons/cachedrandompropertysource.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons/circuit-breaker.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons/commons:-common-abstractions.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons/configuration-properties.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons/context:-application-context-services.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc delete mode 100644 docs/modules/ROOT/pages/spring-cloud-commons/security.adoc delete mode 100644 docs/pom.xml delete mode 100755 docs/src/main/asciidoc/ghpages.sh delete mode 100644 eclipse/eclipse-code-formatter.xml delete mode 100644 eclipse/org.eclipse.jdt.core.prefs delete mode 100644 eclipse/org.eclipse.jdt.ui.prefs delete mode 100644 spring-cloud-commons-dependencies/pom.xml delete mode 100644 spring-cloud-commons/README.md delete mode 100644 spring-cloud-commons/eclipse/eclipse-code-formatter.xml delete mode 100644 spring-cloud-commons/eclipse/org.eclipse.jdt.core.prefs delete mode 100644 spring-cloud-commons/eclipse/org.eclipse.jdt.ui.prefs delete mode 100644 spring-cloud-commons/pom.xml delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnBlockingDiscoveryEnabled.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryEnabled.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryHealthIndicatorEnabled.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnReactiveDiscoveryEnabled.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/DefaultServiceInstance.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/ServiceInstance.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/FeaturesEndpoint.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/HasFeatures.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/NamedFeature.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/AbstractCircuitBreakerFactory.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreaker.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreakerFactory.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ConfigBuilder.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/Customizer.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/NoFallbackAvailableException.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreaker.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreakerFactory.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationConvention.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationDocumentation.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/DefaultCircuitBreakerObservationConvention.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreaker.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedFunction.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedSupplier.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ManagementServerPortUtils.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ReactiveDiscoveryClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatEvent.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstancePreRegisteredEvent.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstanceRegisteredEvent.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/ParentHeartbeatEvent.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryHealthIndicator.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicator.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryHealthIndicator.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DiscoveredResource.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProvider.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResource.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResourceRefresher.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/ServiceInstanceProvider.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/StaticServiceInstanceProvider.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/TraversalDefinition.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/BlockingLoadBalancerRequest.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeException.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/CompletionContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequest.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequestContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultResponse.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/EmptyResponse.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HintRequestContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HttpRequestLoadBalancerRequest.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicy.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalanced.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRecoveryCallback.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryFactory.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClient.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClientsProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerDefaultMappingsProviderAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerEagerLoadProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerInterceptor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycle.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycleValidator.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequest.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestAdapter.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactory.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestTransformer.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Request.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestData.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestDataContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Response.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ResponseData.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RestTemplateCustomizer.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableRequestContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableStatusCodeException.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceInstanceChooser.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceRequestWrapper.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/TimedRequestContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/DeferringLoadBalancerExchangeFilterFunction.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancedExchangeFilterFunction.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformer.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryContext.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryPolicy.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientBuilderBeanPostProcessor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactiveLoadBalancer.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableExchangeFilterFunctionLoadBalancerRetryPolicy.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableStatusCodeException.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/WebClientCustomizer.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationLifecycle.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationManagementLifecycle.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpoint.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/CommonsConfigAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/DefaultsBindHandlerAdvisor.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/CloudFlux.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmitting.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/AccessTokenContextRelay.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/IdUtils.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/SpringFactoryImportSelector.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/TaskSchedulerWrapper.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/UtilAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SSLContextFactory.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SleuthPresentVerifier.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/TlsProperties.java delete mode 100644 spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java delete mode 100644 spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-commons/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/CommonsClientAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/actuator/FeaturesEndpointTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/CustomizerTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreakerTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/AutoRegisterPropertyFalseTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientAutoRegisterFalseTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelectorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientMissingImplTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/ManagementServerPortUtilsTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientOrderTest.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTestsConfig.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientUnitTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorUnitTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicatorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ReactiveSimpleDiscoveryPropertiesAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ServletSimpleDiscoveryPropertiesAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfigurationIntegrationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DiscoveredResourceUnitTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProviderUnitTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/AbstractLoadBalancerAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeExceptionTest.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicyTest.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContextTest.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriToolsTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/DiscoveryClientBasedReactiveLoadBalancer.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformerTest.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerTestUtils.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunctionTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/TestReactiveLoadBalancer.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationMgmtDisabledTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationRegistrationLifecycleTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointNoRegistrationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmittingTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/tokenrelay/ResourceServerTokenRelayTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/IdUtilsTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/SpringFactoryImportSelectorTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SSHContextFactoryTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SleuthPresentVerifierTests.java delete mode 100644 spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java delete mode 100644 spring-cloud-commons/src/test/resources/MyCA.p12 delete mode 100644 spring-cloud-commons/src/test/resources/MyCert.p12 delete mode 100644 spring-cloud-commons/src/test/resources/application-encrypt.properties delete mode 100644 spring-cloud-commons/src/test/resources/application.properties delete mode 100644 spring-cloud-commons/src/test/resources/bootstrap-encrypt.properties delete mode 100644 spring-cloud-commons/src/test/resources/bootstrap-parent.properties delete mode 100644 spring-cloud-commons/src/test/resources/bootstrap.properties delete mode 100644 spring-cloud-commons/src/test/resources/external-properties/bootstrap.properties delete mode 100644 spring-cloud-commons/src/test/resources/other.properties delete mode 100644 spring-cloud-commons/src/test/resources/plain.properties delete mode 100644 spring-cloud-commons/src/test/resources/server.jks delete mode 100644 spring-cloud-context-integration-tests/pom.xml delete mode 100644 spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/JdbcConfigurationTests.java delete mode 100644 spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/RefreshScopeIntegrationTests.java delete mode 100644 spring-cloud-context-integration-tests/src/test/resources/application.properties delete mode 100644 spring-cloud-context-integration-tests/src/test/resources/bootstrap.properties delete mode 100644 spring-cloud-context-integration-tests/src/test/resources/data.sql delete mode 100644 spring-cloud-context-integration-tests/src/test/resources/schema.sql delete mode 100644 spring-cloud-context-webflux-integration-tests/pom.xml delete mode 100644 spring-cloud-context-webflux-integration-tests/src/test/java/org/springframework/cloud/context/integration/webflux/WebfluxRefreshEndpointIntegrationTests.java delete mode 100644 spring-cloud-context-webflux-integration-tests/src/test/resources/application.properties delete mode 100644 spring-cloud-context-webflux-integration-tests/src/test/resources/bootstrap.properties delete mode 100644 spring-cloud-context/README.md delete mode 100644 spring-cloud-context/eclipse/eclipse-code-formatter.xml delete mode 100644 spring-cloud-context/eclipse/org.eclipse.jdt.core.prefs delete mode 100644 spring-cloud-context/eclipse/org.eclipse.jdt.ui.prefs delete mode 100644 spring-cloud-context/pom.xml delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebinderAutoConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/WritableEnvironmentEndpointAutoConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfigFileApplicationListener.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelectorConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/LoggingSystemShutdownListener.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/RefreshBootstrapRegistryInitializer.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorBindHandler.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorConfigBootstrapper.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapProperties.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceLocator.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/SimpleBootstrapPropertySource.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/DecryptEnvironmentPostProcessor.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/KeyProperties.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/RsaProperties.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/TextEncryptorUtils.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/support/OriginTrackedCompositePropertySource.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/config/ContextRefreshedWithApplicationEvent.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/EncryptorFactory.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/KeyFormatException.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpoint.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpointWebExtension.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/named/ClientFactoryObjectProvider.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/named/NamedContextFactory.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesBeans.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/LegacyContextRefresher.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/PauseHandler.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartListener.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/GenericScope.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/ScopeCache.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/StandardScopeCache.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScopeRefreshedEvent.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadLocalScopeCache.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadScope.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEvent.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/env/EnvironmentUtils.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/health/RefreshScopeHealthIndicator.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapDisabled.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapEnabled.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/util/PropertyUtils.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/util/ProxyUtils.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySource.java delete mode 100644 spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySourceEnvironmentPostProcessor.java delete mode 100644 spring-cloud-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-context/src/main/resources/META-INF/spring.factories delete mode 100644 spring-cloud-context/src/main/resources/META-INF/spring/aot.factories delete mode 100644 spring-cloud-context/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationMoreClassPathTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapDisabledAutoConfigurationIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingAutoConfigurationIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomOverrideSystemPropertiesIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomPropertySourceIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingSpringApplicationJsonIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapSourcesOrderingTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/MessageSourceConfigurationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestBootstrapConfiguration.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestHigherPriorityBootstrapConfiguration.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapListenerHierarchyIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptorFactoryTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/RsaDisabledTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerTest.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/named/NamedContextFactoryTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderLifecycleIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderListIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderProxyIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderRefreshScopeIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherOrderingIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/ImportRefreshScopeIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/MoreRefreshScopeIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshEndpointIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConcurrencyTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationScaleTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeLazyIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeListBindingIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeNullBeanIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopePureScaleTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeScaleTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeSerializationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeWebIntegrationTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLoader.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLocationResolver.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataResource.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestEnvPostProcessor.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/health/RefreshScopeHealthIndicatorTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/logging/LoggingRebinderTests.java delete mode 100644 spring-cloud-context/src/test/java/org/springframework/cloud/util/random/CachedRandomPropertySourceTests.java delete mode 100644 spring-cloud-context/src/test/resources/META-INF/spring.factories delete mode 100644 spring-cloud-context/src/test/resources/application-config.properties delete mode 100644 spring-cloud-context/src/test/resources/application-encrypt.properties delete mode 100644 spring-cloud-context/src/test/resources/application-local.properties delete mode 100644 spring-cloud-context/src/test/resources/application-override.properties delete mode 100644 spring-cloud-context/src/test/resources/application.properties delete mode 100644 spring-cloud-context/src/test/resources/bootstrap-config.properties delete mode 100644 spring-cloud-context/src/test/resources/bootstrap-encrypt.properties delete mode 100644 spring-cloud-context/src/test/resources/bootstrap-epptests.properties delete mode 100644 spring-cloud-context/src/test/resources/bootstrap-parent.properties delete mode 100644 spring-cloud-context/src/test/resources/bootstrap-refresh.properties delete mode 100644 spring-cloud-context/src/test/resources/bootstrap.properties delete mode 100644 spring-cloud-context/src/test/resources/custom.properties delete mode 100644 spring-cloud-context/src/test/resources/example-test-rsa-private-key delete mode 100644 spring-cloud-context/src/test/resources/external-properties/bootstrap.properties delete mode 100644 spring-cloud-context/src/test/resources/local.properties delete mode 100644 spring-cloud-context/src/test/resources/messages.properties delete mode 100644 spring-cloud-context/src/test/resources/nonenumerable.properties delete mode 100644 spring-cloud-context/src/test/resources/ordering.properties delete mode 100644 spring-cloud-context/src/test/resources/other.properties delete mode 100644 spring-cloud-context/src/test/resources/plain.properties delete mode 100644 spring-cloud-context/src/test/resources/server.jks delete mode 100644 spring-cloud-context/src/test/resources/server.p12 delete mode 100644 spring-cloud-loadbalancer/pom.xml delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClient.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationRegistrar.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientSpecification.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClients.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClient.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryFactory.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicy.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/CaffeineBasedLoadBalancerCacheManager.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCache.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManager.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheManager.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheProperties.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerAutoConfiguration.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerZoneConfig.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DelegatingServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceList.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/NoopServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorLoadBalancer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorServiceInstanceLoadBalancer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SelectedInstanceCallback.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightFunction.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfiguration.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycle.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerClientFactory.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializer.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtils.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/ServiceInstanceListSuppliers.java delete mode 100644 spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/SimpleObjectProvider.java delete mode 100644 spring-cloud-loadbalancer/src/main/resources/META-INF/additional-spring-configuration-metadata.json delete mode 100644 spring-cloud-loadbalancer/src/main/resources/META-INF/spring/aot.factories delete mode 100644 spring-cloud-loadbalancer/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClientTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicyTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManagerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceListTest.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTestUtils.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliersTestUtils.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/TestSelectedServiceInstanceSupplier.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplierTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfigurationTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializerTest.java delete mode 100644 spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtilsTests.java delete mode 100644 spring-cloud-loadbalancer/src/test/resources/application.yml delete mode 100644 spring-cloud-loadbalancer/src/test/resources/logback-test.xml delete mode 100644 spring-cloud-starter-bootstrap/pom.xml delete mode 100644 spring-cloud-starter-bootstrap/src/main/java/org/springframework/cloud/bootstrap/marker/Marker.java delete mode 100644 spring-cloud-starter-bootstrap/src/test/java/org/springframework/cloud/bootstrap/marker/MarkerTests.java delete mode 100644 spring-cloud-starter-bootstrap/src/test/resources/bootstrap.properties delete mode 100644 spring-cloud-starter-loadbalancer/pom.xml delete mode 100644 spring-cloud-starter/pom.xml delete mode 100644 spring-cloud-test-support/README.md delete mode 100644 spring-cloud-test-support/eclipse/eclipse-code-formatter.xml delete mode 100644 spring-cloud-test-support/eclipse/org.eclipse.jdt.core.prefs delete mode 100644 spring-cloud-test-support/eclipse/org.eclipse.jdt.ui.prefs delete mode 100644 spring-cloud-test-support/pom.xml delete mode 100644 spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathExclusions.java delete mode 100644 spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathOverrides.java delete mode 100644 spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathClassLoader.java delete mode 100644 spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathExtension.java delete mode 100644 spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java delete mode 100644 spring-cloud-test-support/src/main/java/org/springframework/cloud/test/TestSocketUtils.java delete mode 100644 spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerExclusionsTests.java delete mode 100644 spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerOverridesTests.java delete mode 100644 spring-cloud-test-support/src/test/java/org/springframework/cloud/test/TestSocketUtilsTests.java delete mode 100644 src/checkstyle/checkstyle-suppressions.xml create mode 100644 supplemental-ui/partials/nav-search.hbs create mode 100644 supplemental-ui/partials/search.hbs diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index ddda9782..00000000 --- a/.editorconfig +++ /dev/null @@ -1,24 +0,0 @@ -root = true - -[*.java] -indent_style = tab -indent_size = 4 -continuation_indent_size = 8 - -[*.groovy] -indent_style = tab -indent_size = 4 -continuation_indent_size = 8 - -[*.xml] -indent_style = tab -indent_size = 4 -continuation_indent_size = 8 - -[*.yml] -indent_style = space -indent_size = 2 - -[*.yaml] -indent_style = space -indent_size = 2 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index b44059e7..00000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,45 +0,0 @@ - -# Contributing - -Spring Cloud is released under the non-restrictive Apache 2.0 license, -and follows a very standard Github development process, using Github -tracker for issues and merging pull requests into main. If you want -to contribute even something trivial please do not hesitate, but -follow the guidelines below. - -## Sign the Contributor License Agreement -Before we accept a non-trivial patch or pull request we will need you to sign the -[Contributor License Agreement](https://cla.pivotal.io/sign/spring). -Signing the contributor's agreement does not grant anyone commit rights to the main -repository, but it does mean that we can accept your contributions, and you will get an -author credit if we do. Active contributors might be asked to join the core team, and -given the ability to merge pull requests. - -## Code of Conduct -This project adheres to the Contributor Covenant [code of -conduct](https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report -unacceptable behavior to spring-code-of-conduct@pivotal.io. - -## Code Conventions and Housekeeping -None of these is essential for a pull request, but they will all help. They can also be -added after the original pull request but before a merge. - -* Use the Spring Framework code format conventions. If you use Eclipse - you can import formatter settings using the - `eclipse-code-formatter.xml` file from the - [Spring Cloud Build](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/spring-cloud-dependencies-parent/eclipse-code-formatter.xml) project. If using IntelliJ, you can use the - [Eclipse Code Formatter Plugin](https://plugins.jetbrains.com/plugin/6546) to import the same file. -* Make sure all new `.java` files to have a simple Javadoc class comment with at least an - `@author` tag identifying you, and preferably at least a paragraph on what the class is - for. -* Add the ASF license header comment to all new `.java` files (copy from existing files - in the project) -* Add yourself as an `@author` to the .java files that you modify substantially (more - than cosmetic changes). -* Add some Javadocs and, if you change the namespace, some XSD doc elements. -* A few unit tests would help a lot as well -- someone has to do it. -* If no-one else is using your branch, please rebase it against the current main (or - other target branch in the main project). -* When writing a commit message please follow [these conventions](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html), - if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit - message (where XXXX is the issue number). diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 0bc5ef4f..00000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,20 +0,0 @@ - diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index aeafef9d..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: '' -assignees: '' - ---- - -**Describe the bug** -Please provide details of the problem, including the version of Spring Cloud that you -are using. - -**Sample** -If possible, please provide a test case or sample application that reproduces -the problem. This makes it much easier for us to diagnose the problem and to verify that -we have fixed it. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7d..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 00000000..2e20c341 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,53 @@ +name: Deploy Docs +run-name: ${{ format('{0} ({1})', github.workflow, github.event.inputs.build-refname || 'all') }} +on: + workflow_dispatch: + inputs: + build-refname: + description: Enter git refname to build (e.g., 5.7.x). + required: false + push: + branches: docs-build +env: + GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} +permissions: + contents: write +jobs: + build: + if: github.repository_owner == 'spring-cloud' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 5 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Set up refname build + if: github.event.inputs.build-refname + run: | + git fetch --depth 1 https://github.com/$GITHUB_REPOSITORY ${{ github.event.inputs.build-refname }} + export BUILD_REFNAME=${{ github.event.inputs.build-refname }} + echo "BUILD_REFNAME=$BUILD_REFNAME" >> $GITHUB_ENV + export BUILD_VERSION=$(git cat-file --textconv FETCH_HEAD:pom.xml | python3 -c "import xml.etree.ElementTree as xml; from sys import stdin; print(xml.parse(stdin).getroot().find('{http://maven.apache.org/POM/4.0.0}version').text)") + echo BUILD_VERSION=$BUILD_VERSION >> $GITHUB_ENV + - name: Run Antora + run: | + ./mvnw antora + - name: Publish Docs + uses: rwinch/spring-doc-actions/rsync-antora-reference@httpdocs-path + with: + docs-username: ${{ secrets.DOCS_USERNAME }} + docs-host: ${{ secrets.DOCS_HOST }} + docs-ssh-key: ${{ secrets.DOCS_SSH_KEY }} + docs-ssh-host-key: ${{ secrets.DOCS_SSH_HOST_KEY }} + site-path: docs/target/antora/site + - name: Bust Cloudflare Cache + uses: spring-io/spring-doc-actions/bust-cloudflare-antora-cache@v0.0.11 + with: + context-root: spring-cloud-commons + cloudflare-zone-id: ${{ secrets.CLOUDFLARE_ZONE_ID }} + cloudflare-cache-token: ${{ secrets.CLOUDFLARE_CACHE_TOKEN }} diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml deleted file mode 100644 index 9b781b39..00000000 --- a/.github/workflows/maven.yml +++ /dev/null @@ -1,42 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Build - -on: - push: - branches: [ main, 4.0.x, 3.1.x ] - pull_request: - branches: [ main, 4.0.x, 3.1.x ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Set up JDK - uses: actions/setup-java@v2 - with: - distribution: 'temurin' - java-version: '17' - - name: Cache local Maven repository - uses: actions/cache@v2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - name: Build with Maven - run: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - name: Publish Test Report - uses: mikepenz/action-junit-report@v2 - if: always() # always run even if the previous step fails - with: - report_paths: '**/surefire-reports/TEST-*.xml' - - name: Archive code coverage results - uses: actions/upload-artifact@v2 - with: - name: surefire-reports - path: '**/surefire-reports/*' diff --git a/.gitignore b/.gitignore index 14b99f27..abc7d179 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,21 @@ -/application.yml -/application.properties -asciidoctor.css -*~ -.#* -*# -target -bin -_site/ -.classpath +target/ +.settings/ .project -.settings +.classpath +*.orig .springBeans -.sts4-cache/ -.DS_Store -*.sw* -*.iml -.idea .factorypath -/spring-cloud-release-tools*.jar -antrun -.vscode/ -.flattened-pom.xml +.sts4-cache +.ant-targets-build.xml +src/ant/.ant-targets-upload-dist.xml +*.sonar4clipse* +.DS_Store +*.iml +*.ipr +*.iws +/.idea/ +*.graphml +node_modules +node/ +package-lock.json +package.json diff --git a/.java-version b/.java-version deleted file mode 100644 index 98d9bcb7..00000000 --- a/.java-version +++ /dev/null @@ -1 +0,0 @@ -17 diff --git a/.mvn/maven.config b/.mvn/maven.config deleted file mode 100644 index 3b8cf46e..00000000 --- a/.mvn/maven.config +++ /dev/null @@ -1 +0,0 @@ --DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring diff --git a/.sdkmanrc b/.sdkmanrc deleted file mode 100644 index 415f9083..00000000 --- a/.sdkmanrc +++ /dev/null @@ -1,3 +0,0 @@ -# Enable auto-env through the sdkman_auto_env config -# Add key=value pairs of SDKs to use below -java=17.0.1-tem diff --git a/.settings.xml b/.settings.xml deleted file mode 100644 index 03645e8c..00000000 --- a/.settings.xml +++ /dev/null @@ -1,68 +0,0 @@ - - - - - repo.spring.io - ${env.CI_DEPLOY_USERNAME} - ${env.CI_DEPLOY_PASSWORD} - - - - - - spring - - true - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - - 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 - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - - - diff --git a/.springformat b/.springformat deleted file mode 100644 index e69de29b..00000000 diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 62589edd..00000000 --- a/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.adoc b/README.adoc index 5932161f..e4f50619 100644 --- a/README.adoc +++ b/README.adoc @@ -1,339 +1,23 @@ -//// -DO NOT EDIT THIS FILE. IT WAS GENERATED. -Manual changes to this file will be lost when it is generated again. -Edit the files in the src/main/asciidoc/ directory instead. -//// += Spring Cloud Commons Docs Build +You're currently viewing the Antora playbook branch. +The playbook branch hosts the docs build that is used to build and publish the production docs site. +The Spring Cloud Commons reference docs are built using https://antora.org[Antora]. +This README covers how to build the docs in a software branch as well as how to build the production docs site locally. -https://pivotal.io/platform-as-a-service/migrating-to-cloud-native-application-architectures-ebook[Cloud Native] is a style of application development that encourages easy adoption of best practices in the areas of continuous delivery and value-driven development. -A related discipline is that of building https://12factor.net/[12-factor Applications], in which development practices are aligned with delivery and operations goals -- for instance, by using declarative programming and management and monitoring. -Spring Cloud facilitates these styles of development in a number of specific ways. - The starting point is a set of features to which all components in a distributed system need easy access. +== Building the Site -Many of those features are covered by https://projects.spring.io/spring-boot[Spring Boot], on which Spring Cloud builds. Some more features are delivered by Spring Cloud as two libraries: Spring Cloud Context and Spring Cloud Commons. -Spring Cloud Context provides utilities and special services for the `ApplicationContext` of a Spring Cloud application (bootstrap context, encryption, refresh scope, and environment endpoints). Spring Cloud Commons is a set of abstractions and common classes used in different Spring Cloud implementations (such as Spring Cloud Netflix and Spring Cloud Consul). - -If you get an exception due to "Illegal key size" and you use Sun's JDK, you need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. -See the following links for more information: - -* https://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html[Java 6 JCE] -* https://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html[Java 7 JCE] -* https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html[Java 8 JCE] - -Extract the files into the JDK/jre/lib/security folder for whichever version of JRE/JDK x64/x86 you use. - -== Building - -:jdkversion: 17 - -=== Basic Compile and Test - -To build the source you will need to install JDK {jdkversion}. - -Spring Cloud uses Maven for most build-related activities, and you -should be able to get off the ground quite quickly by cloning the -project you are interested in and typing +You can build the entire site by invoking the following on the docs-build branch and then viewing the site at `target/site/index.html` +[source,bash] ---- -$ ./mvnw install +mvn exec:exec@antora ---- -NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command -in place of `./mvnw` in the examples below. If you do that you also -might need to add `-P spring` if your local Maven settings do not -contain repository declarations for spring pre-release artifacts. +== Building a Specific Branch -NOTE: Be aware that you might need to increase the amount of memory -available to Maven by setting a `MAVEN_OPTS` environment variable with -a value like `-Xmx512m -XX:MaxPermSize=128m`. We try to cover this in -the `.mvn` configuration, so if you find you have to do it to make a -build succeed, please raise a ticket to get the settings added to -source control. - -The projects that require middleware (i.e. Redis) for testing generally -require that a local instance of [Docker](https://www.docker.com/get-started) is installed and running. - - -=== Documentation - -The spring-cloud-build module has a "docs" profile, and if you switch -that on it will try to build asciidoc sources from -`src/main/asciidoc`. As part of that process it will look for a -`README.adoc` and process it by loading all the includes, but not -parsing or rendering it, just copying it to `${main.basedir}` -(defaults to `${basedir}`, i.e. the root of the project). If there are -any changes in the README it will then show up after a Maven build as -a modified file in the correct place. Just commit it and push the change. - -=== Working with the code -If you don't have an IDE preference we would recommend that you use -https://www.springsource.com/developer/sts[Spring Tools Suite] or -https://eclipse.org[Eclipse] when working with the code. We use the -https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools -should also work without issue as long as they use Maven 3.3.3 or better. - -==== Activate the Spring Maven profile -Spring Cloud projects require the 'spring' Maven profile to be activated to resolve -the spring milestone and snapshot repositories. Use your preferred IDE to set this -profile to be active, or you may experience build errors. - -==== Importing into eclipse with m2eclipse -We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with -eclipse. If you don't already have m2eclipse installed it is available from the "eclipse -marketplace". - -NOTE: Older versions of m2e do not support Maven 3.3, so once the -projects are imported into Eclipse you will also need to tell -m2eclipse to use the right profile for the projects. If you -see many different errors related to the POMs in the projects, check -that you have an up to date installation. If you can't upgrade m2e, -add the "spring" profile to your `settings.xml`. Alternatively you can -copy the repository settings from the "spring" profile of the parent -pom into your `settings.xml`. - -==== Importing into eclipse without m2eclipse -If you prefer not to use m2eclipse you can generate eclipse project metadata using the -following command: - -[indent=0] +[source,bash] ---- - $ ./mvnw eclipse:eclipse +mvn exec:exec@antora ---- - -The generated eclipse projects can be imported by selecting `import existing projects` -from the `file` menu. - - -== Contributing - -:spring-cloud-build-branch: master - -Spring Cloud is released under the non-restrictive Apache 2.0 license, -and follows a very standard Github development process, using Github -tracker for issues and merging pull requests into master. If you want -to contribute even something trivial please do not hesitate, but -follow the guidelines below. - -=== Sign the Contributor License Agreement -Before we accept a non-trivial patch or pull request we will need you to sign the -https://cla.pivotal.io/sign/spring[Contributor License Agreement]. -Signing the contributor's agreement does not grant anyone commit rights to the main -repository, but it does mean that we can accept your contributions, and you will get an -author credit if we do. Active contributors might be asked to join the core team, and -given the ability to merge pull requests. - -=== Code of Conduct -This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of -conduct]. By participating, you are expected to uphold this code. Please report -unacceptable behavior to spring-code-of-conduct@pivotal.io. - -=== Code Conventions and Housekeeping -None of these is essential for a pull request, but they will all help. They can also be -added after the original pull request but before a merge. - -* Use the Spring Framework code format conventions. If you use Eclipse - you can import formatter settings using the - `eclipse-code-formatter.xml` file from the - https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring - Cloud Build] project. If using IntelliJ, you can use the - https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter - Plugin] to import the same file. -* Make sure all new `.java` files to have a simple Javadoc class comment with at least an - `@author` tag identifying you, and preferably at least a paragraph on what the class is - for. -* Add the ASF license header comment to all new `.java` files (copy from existing files - in the project) -* Add yourself as an `@author` to the .java files that you modify substantially (more - than cosmetic changes). -* Add some Javadocs and, if you change the namespace, some XSD doc elements. -* A few unit tests would help a lot as well -- someone has to do it. -* If no-one else is using your branch, please rebase it against the current master (or - other target branch in the main project). -* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], - if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit - message (where XXXX is the issue number). - -=== Checkstyle - -Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are: - -.spring-cloud-build-tools/ ----- -└── src -    ├── checkstyle -    │   └── checkstyle-suppressions.xml <3> -    └── main -    └── resources -    ├── checkstyle-header.txt <2> -    └── checkstyle.xml <1> ----- -<1> Default Checkstyle rules -<2> File header setup -<3> Default suppression rules - -==== Checkstyle configuration - -Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins. - -.pom.xml ----- - -true <1> - true - <2> - true - <3> - - - - - <4> - io.spring.javaformat - spring-javaformat-maven-plugin - - <5> - org.apache.maven.plugins - maven-checkstyle-plugin - - - - - - <5> - org.apache.maven.plugins - maven-checkstyle-plugin - - - - ----- -<1> Fails the build upon Checkstyle errors -<2> Fails the build upon Checkstyle violations -<3> Checkstyle analyzes also the test sources -<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules -<5> Add checkstyle plugin to your build and reporting phases - -If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example: - -.projectRoot/src/checkstyle/checkstyle-suppresions.xml ----- - - - - - - ----- - -It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script: - -```bash -$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig -$ touch .springformat -``` - -=== IDE setup - -==== Intellij IDEA - -In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin. -The following files can be found in the https://github.com/spring-cloud/spring-cloud-build/tree/master/spring-cloud-build-tools[Spring Cloud Build] project. - -.spring-cloud-build-tools/ ----- -└── src -    ├── checkstyle -    │   └── checkstyle-suppressions.xml <3> -    └── main -    └── resources -    ├── checkstyle-header.txt <2> -    ├── checkstyle.xml <1> -    └── intellij -       ├── Intellij_Project_Defaults.xml <4> -       └── Intellij_Spring_Boot_Java_Conventions.xml <5> ----- -<1> Default Checkstyle rules -<2> File header setup -<3> Default suppression rules -<4> Project defaults for Intellij that apply most of Checkstyle rules -<5> Project style conventions for Intellij that apply most of Checkstyle rules - -.Code style - -image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style] - -Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file. - -.Inspection profiles - -image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style] - -Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file. - -.Checkstyle - -To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions - -image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle] - -Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables: - -- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL. -- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL. -- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`. - -IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources. - -=== Duplicate Finder - -Spring Cloud Build brings along the `basepom:duplicate-finder-maven-plugin`, that enables flagging duplicate and conflicting classes and resources on the java classpath. - -==== Duplicate Finder configuration - -Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst's `pom.xml`. - -.pom.xml -[source,xml] ----- - - - - org.basepom.maven - duplicate-finder-maven-plugin - - - ----- - -For other properties, we have set defaults as listed in the https://github.com/basepom/duplicate-finder-maven-plugin/wiki[plugin documentation]. - -You can easily override them but setting the value of the selected property prefixed with `duplicate-finder-maven-plugin`. For example, set `duplicate-finder-maven-plugin.skip` to `true` in order to skip duplicates check in your build. - -If you need to add `ignoredClassPatterns` or `ignoredResourcePatterns` to your setup, make sure to add them in the plugin configuration section of your project: - -[source,xml] ----- - - - - org.basepom.maven - duplicate-finder-maven-plugin - - - org.joda.time.base.BaseDateTime - .*module-info - - - changelog.txt - - - - - - - ----- - diff --git a/docs/antora-playbook.yml b/antora-playbook.yml similarity index 62% rename from docs/antora-playbook.yml rename to antora-playbook.yml index 8540130e..420e9476 100644 --- a/docs/antora-playbook.yml +++ b/antora-playbook.yml @@ -4,40 +4,42 @@ antora: - require: '@springio/antora-extensions/latest-version-extension' - require: '@springio/antora-extensions/inject-collector-cache-config-extension' - '@antora/collector-extension' + - './antora/lib/version-fix.js' - '@antora/atlas-extension' - require: '@springio/antora-extensions/root-component-extension' root_component_name: 'cloud-commons' - # FIXME: Run antora once using this extension to migrate to the Asciidoc Tabs syntax - # and then remove this extension - - require: '@springio/antora-extensions/tabs-migration-extension' - unwrap_example_block: always - save_result: true site: title: Spring Cloud Commons - url: https://docs.spring.io/spring-cloud-commons/reference/ + url: https://docs.spring.io/spring-cloud-commons/reference + robots: allow +git: + ensure_git_suffix: false content: sources: - - url: ./.. - branches: HEAD + - url: https://github.com/spring-cloud/spring-cloud-commons + # Refname matching: + # https://docs.antora.org/antora/latest/playbook/content-refname-matching/ + branches: [ main ] + tags: [ '({4..9}).+({1..9}).+({0..9})?(-{RC,M}+({0..9}))', '!4.1.0-M1' ] start_path: docs - worktrees: true asciidoc: attributes: page-stackoverflow-url: https://stackoverflow.com/tags/spring-cloud page-pagination: '' hide-uri-scheme: '@' tabs-sync-option: '@' - chomp: 'all' extensions: - '@asciidoctor/tabs' - '@springio/asciidoctor-extensions' - sourcemap: true urls: + latest_version_segment_strategy: redirect:to latest_version_segment: '' + redirect_facility: httpd +ui: + bundle: + url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip + snapshot: true runtime: log: failure_level: warn format: pretty -ui: - bundle: - url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.4/ui-bundle.zip \ No newline at end of file diff --git a/docs/.github/workflows/deploy-docs.yml b/docs/.github/workflows/deploy-docs.yml deleted file mode 100644 index be4b92df..00000000 --- a/docs/.github/workflows/deploy-docs.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Deploy Docs -on: - push: - branches-ignore: [ gh-pages ] - tags: '**' - repository_dispatch: - types: request-build-reference # legacy - #schedule: - #- cron: '0 10 * * *' # Once per day at 10am UTC - workflow_dispatch: -permissions: - actions: write -jobs: - build: - runs-on: ubuntu-latest - # if: github.repository_owner == 'spring-cloud' - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - ref: docs-build - fetch-depth: 1 - - name: Dispatch (partial build) - if: github.ref_type == 'branch' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }} - - name: Dispatch (full build) - if: github.ref_type == 'tag' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) diff --git a/docs/antora.yml b/docs/antora.yml deleted file mode 100644 index ba878062..00000000 --- a/docs/antora.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: cloud-commons -version: true -title: Spring Cloud Commons -nav: - - modules/ROOT/nav.adoc -ext: - collector: - run: - command: ./mvnw validate process-resources -Pdocs -pl docs - local: true - scan: - dir: ./target/classes/antora-resources/ diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc deleted file mode 100644 index 6a95ffe6..00000000 --- a/docs/modules/ROOT/nav.adoc +++ /dev/null @@ -1,19 +0,0 @@ -* xref:index.adoc[] -* xref:spring-cloud-commons.adoc[] -** xref:spring-cloud-commons/context:-application-context-services.adoc[] -** xref:spring-cloud-commons/commons:-common-abstractions.adoc[] -** xref:spring-cloud-commons/loadbalancer.adoc[] -** xref:spring-cloud-commons/circuit-breaker.adoc[] -** xref:spring-cloud-commons/cachedrandompropertysource.adoc[] -** xref:spring-cloud-commons/security.adoc[] -** xref:spring-cloud-commons/configuration-properties.adoc[] -* xref:_attributes.adoc[] -* xref:intro.adoc[] -* xref:jce.adoc[] -* xref:spring-cloud-circuitbreaker.adoc[] -* xref:README.adoc[] -* xref:_configprops.adoc[] -* xref:_observability.adoc[] -* xref:appendix.adoc[] -* xref:sagan-boot.adoc[] -* xref:sagan-index.adoc[] diff --git a/docs/modules/ROOT/pages/README.adoc b/docs/modules/ROOT/pages/README.adoc deleted file mode 100644 index 56db1c9d..00000000 --- a/docs/modules/ROOT/pages/README.adoc +++ /dev/null @@ -1,12 +0,0 @@ - -[[building]] -= Building -:page-section-summary-toc: 1 - -include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/src/main/asciidoc/building.adoc[] - -[[contributing]] -= Contributing -:page-section-summary-toc: 1 - -include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/src/main/asciidoc/contributing.adoc[] diff --git a/docs/modules/ROOT/pages/_attributes.adoc b/docs/modules/ROOT/pages/_attributes.adoc deleted file mode 100644 index 5a78784c..00000000 --- a/docs/modules/ROOT/pages/_attributes.adoc +++ /dev/null @@ -1,14 +0,0 @@ -:doctype: book -:idprefix: -:idseparator: - -:tabsize: 4 -:numbered: -:sectanchors: -:sectnums: -:icons: font -:hide-uri-scheme: -:docinfo: shared,private - -:sc-ext: java -:project-full-name: Spring Cloud Commons -:all: {asterisk}{asterisk} diff --git a/docs/modules/ROOT/pages/_configprops.adoc b/docs/modules/ROOT/pages/_configprops.adoc deleted file mode 100644 index aeb71c3f..00000000 --- a/docs/modules/ROOT/pages/_configprops.adoc +++ /dev/null @@ -1,83 +0,0 @@ -|=== -|Name | Default | Description - -|spring.cloud.compatibility-verifier.compatible-boot-versions | `+++3.2.x+++` | Default accepted versions for the Spring Boot dependency. You can set {@code x} for the patch version if you don't want to specify a concrete value. Example: {@code 3.4.x} -|spring.cloud.compatibility-verifier.enabled | `+++false+++` | Enables creation of Spring Cloud compatibility verification. -|spring.cloud.config.allow-override | `+++true+++` | Flag to indicate that {@link #isOverrideSystemProperties() systemPropertiesOverride} can be used. Set to false to prevent users from changing the default accidentally. Default true. -|spring.cloud.config.initialize-on-context-refresh | `+++false+++` | Flag to initialize bootstrap configuration on context refresh event. Default false. -|spring.cloud.config.override-none | `+++false+++` | Flag to indicate that when {@link #setAllowOverride(boolean) allowOverride} is true, external properties should take lowest priority and should not override any existing property sources (including local config files). Default false. -|spring.cloud.config.override-system-properties | `+++true+++` | Flag to indicate that the external properties should override system properties. Default true. -|spring.cloud.decrypt-environment-post-processor.enabled | `+++true+++` | Enable the DecryptEnvironmentPostProcessor. -|spring.cloud.discovery.client.composite-indicator.enabled | `+++true+++` | Enables discovery client composite health indicator. -|spring.cloud.discovery.client.health-indicator.enabled | `+++true+++` | -|spring.cloud.discovery.client.health-indicator.include-description | `+++false+++` | -|spring.cloud.discovery.client.health-indicator.use-services-query | `+++true+++` | Whether or not the indicator should use {@link DiscoveryClient#getServices} to check its health. When set to {@code false} the indicator instead uses the lighter {@link DiscoveryClient#probe()}. This can be helpful in large deployments where the number of services returned makes the operation unnecessarily heavy. -|spring.cloud.discovery.client.simple.instances | | -|spring.cloud.discovery.client.simple.local.host | | -|spring.cloud.discovery.client.simple.local.instance-id | | -|spring.cloud.discovery.client.simple.local.metadata | | -|spring.cloud.discovery.client.simple.local.port | `+++0+++` | -|spring.cloud.discovery.client.simple.local.secure | `+++false+++` | -|spring.cloud.discovery.client.simple.local.service-id | | -|spring.cloud.discovery.client.simple.local.uri | | -|spring.cloud.discovery.client.simple.order | | -|spring.cloud.discovery.enabled | `+++true+++` | Enables discovery client health indicators. -|spring.cloud.features.enabled | `+++true+++` | Enables the features endpoint. -|spring.cloud.httpclientfactories.apache.enabled | `+++true+++` | Enables creation of Apache Http Client factory beans. -|spring.cloud.httpclientfactories.ok.enabled | `+++true+++` | Enables creation of OK Http Client factory beans. -|spring.cloud.hypermedia.refresh.fixed-delay | `+++5000+++` | -|spring.cloud.hypermedia.refresh.initial-delay | `+++10000+++` | -|spring.cloud.inetutils.default-hostname | `+++localhost+++` | The default hostname. Used in case of errors. -|spring.cloud.inetutils.default-ip-address | `+++127.0.0.1+++` | The default IP address. Used in case of errors. -|spring.cloud.inetutils.ignored-interfaces | | List of Java regular expressions for network interfaces that will be ignored. -|spring.cloud.inetutils.preferred-networks | | List of Java regular expressions for network addresses that will be preferred. -|spring.cloud.inetutils.timeout-seconds | `+++1+++` | Timeout, in seconds, for calculating hostname. -|spring.cloud.inetutils.use-only-site-local-interfaces | `+++false+++` | Whether to use only interfaces with site local addresses. See {@link InetAddress#isSiteLocalAddress()} for more details. -|spring.cloud.loadbalancer.cache.caffeine.spec | | The spec to use to create caches. See CaffeineSpec for more details on the spec format. -|spring.cloud.loadbalancer.cache.capacity | `+++256+++` | Initial cache capacity expressed as int. -|spring.cloud.loadbalancer.cache.enabled | `+++true+++` | Enables Spring Cloud LoadBalancer caching mechanism. -|spring.cloud.loadbalancer.cache.ttl | `+++35s+++` | Time To Live - time counted from writing of the record, after which cache entries are expired, expressed as a {@link Duration}. The property {@link String} has to be in keeping with the appropriate syntax as specified in Spring Boot StringToDurationConverter. @see StringToDurationConverter.java -|spring.cloud.loadbalancer.call-get-with-request-on-delegates | `+++true+++` | If this flag is set to {@code true}, {@code ServiceInstanceListSupplier#get(Request request)} method will be implemented to call {@code delegate.get(request)} in classes assignable from {@code DelegatingServiceInstanceListSupplier} that don't already implement that method, with the exclusion of {@code CachingServiceInstanceListSupplier} and {@code HealthCheckServiceInstanceListSupplier}, which should be placed in the instance supplier hierarchy directly after the supplier performing instance retrieval over the network, before any request-based filtering is done, {@code true} by default. -|spring.cloud.loadbalancer.clients | | -|spring.cloud.loadbalancer.configurations | `+++default+++` | Enables a predefined LoadBalancer configuration. -|spring.cloud.loadbalancer.eager-load.clients | | Names of the clients. -|spring.cloud.loadbalancer.enabled | `+++true+++` | Enables Spring Cloud LoadBalancer. -|spring.cloud.loadbalancer.health-check.initial-delay | `+++0+++` | Initial delay value for the HealthCheck scheduler. -|spring.cloud.loadbalancer.health-check.interval | `+++25s+++` | Interval for rerunning the HealthCheck scheduler. -|spring.cloud.loadbalancer.health-check.interval | `+++25s+++` | Interval for rerunning the HealthCheck scheduler. -|spring.cloud.loadbalancer.health-check.path | | Path at which the health-check request should be made. Can be set up per `serviceId`. A `default` value can be set up as well. If none is set up, `/actuator/health` will be used. -|spring.cloud.loadbalancer.health-check.port | | Path at which the health-check request should be made. If none is set, the port under which the requested service is available at the service instance. -|spring.cloud.loadbalancer.health-check.refetch-instances | `+++false+++` | Indicates whether the instances should be refetched by the `HealthCheckServiceInstanceListSupplier`. This can be used if the instances can be updated and the underlying delegate does not provide an ongoing flux. -|spring.cloud.loadbalancer.health-check.refetch-instances-interval | `+++25s+++` | Interval for refetching available service instances. -|spring.cloud.loadbalancer.health-check.repeat-health-check | `+++true+++` | Indicates whether health checks should keep repeating. It might be useful to set it to `false` if periodically refetching the instances, as every refetch will also trigger a healthcheck. -|spring.cloud.loadbalancer.health-check.update-results-list | `+++true+++` | Indicates whether the {@code healthCheckFlux} should emit on each alive {@link ServiceInstance} that has been retrieved. If set to {@code false}, the entire alive instances sequence is first collected into a list and only then emitted. -|spring.cloud.loadbalancer.hint | | Allows setting the value of hint that is passed on to the LoadBalancer request and can subsequently be used in {@link ReactiveLoadBalancer} implementations. -|spring.cloud.loadbalancer.hint-header-name | `+++X-SC-LB-Hint+++` | Allows setting the name of the header used for passing the hint for hint-based service instance filtering. -|spring.cloud.loadbalancer.retry.avoid-previous-instance | `+++true+++` | Enables wrapping ServiceInstanceListSupplier beans with `RetryAwareServiceInstanceListSupplier` if Spring-Retry is in the classpath. -|spring.cloud.loadbalancer.retry.backoff.enabled | `+++false+++` | Indicates whether Reactor Retry backoffs should be applied. -|spring.cloud.loadbalancer.retry.backoff.jitter | `+++0.5+++` | Used to set `RetryBackoffSpec.jitter`. -|spring.cloud.loadbalancer.retry.backoff.max-backoff | `+++Long.MAX ms+++` | Used to set `RetryBackoffSpec.maxBackoff`. -|spring.cloud.loadbalancer.retry.backoff.min-backoff | `+++5 ms+++` | Used to set `RetryBackoffSpec#minBackoff`. -|spring.cloud.loadbalancer.retry.enabled | `+++true+++` | Enables LoadBalancer retries. -|spring.cloud.loadbalancer.retry.max-retries-on-next-service-instance | `+++1+++` | Number of retries to be executed on the next `ServiceInstance`. A `ServiceInstance` is chosen before each retry call. -|spring.cloud.loadbalancer.retry.max-retries-on-same-service-instance | `+++0+++` | Number of retries to be executed on the same `ServiceInstance`. -|spring.cloud.loadbalancer.retry.retry-on-all-exceptions | `+++false+++` | Indicates retries should be attempted for all exceptions, not only those specified in `retryableExceptions`. -|spring.cloud.loadbalancer.retry.retry-on-all-operations | `+++false+++` | Indicates retries should be attempted on operations other than `HttpMethod.GET`. -|spring.cloud.loadbalancer.retry.retryable-exceptions | `+++{}+++` | A `Set` of `Throwable` classes that should trigger a retry. -|spring.cloud.loadbalancer.retry.retryable-status-codes | `+++{}+++` | A `Set` of status codes that should trigger a retry. -|spring.cloud.loadbalancer.service-discovery.timeout | | String representation of Duration of the timeout for calls to service discovery. -|spring.cloud.loadbalancer.stats.micrometer.enabled | `+++false+++` | Enables Spring Cloud LoadBalancer Micrometer stats. -|spring.cloud.loadbalancer.sticky-session.add-service-instance-cookie | `+++false+++` | Indicates whether a cookie with the newly selected instance should be added by LoadBalancer. -|spring.cloud.loadbalancer.sticky-session.instance-id-cookie-name | `+++sc-lb-instance-id+++` | The name of the cookie holding the preferred instance id. -|spring.cloud.loadbalancer.x-forwarded.enabled | `+++false+++` | To Enable X-Forwarded Headers. -|spring.cloud.loadbalancer.zone | | Spring Cloud LoadBalancer zone. -|spring.cloud.refresh.additional-property-sources-to-retain | | Additional property sources to retain during a refresh. Typically only system property sources are retained. This property allows property sources, such as property sources created by EnvironmentPostProcessors to be retained as well. -|spring.cloud.refresh.enabled | `+++true+++` | Enables autoconfiguration for the refresh scope and associated features. -|spring.cloud.refresh.extra-refreshable | `+++true+++` | Additional class names for beans to post process into refresh scope. -|spring.cloud.refresh.never-refreshable | `+++true+++` | Comma separated list of class names for beans to never be refreshed or rebound. -|spring.cloud.service-registry.auto-registration.enabled | `+++true+++` | Whether service auto-registration is enabled. Defaults to true. -|spring.cloud.service-registry.auto-registration.fail-fast | `+++false+++` | Whether startup fails if there is no AutoServiceRegistration. Defaults to false. -|spring.cloud.service-registry.auto-registration.register-management | `+++true+++` | Whether to register the management as a service. Defaults to true. -|spring.cloud.util.enabled | `+++true+++` | Enables creation of Spring Cloud utility beans. - -|=== diff --git a/docs/modules/ROOT/pages/_observability.adoc b/docs/modules/ROOT/pages/_observability.adoc deleted file mode 100644 index 5eac1efb..00000000 --- a/docs/modules/ROOT/pages/_observability.adoc +++ /dev/null @@ -1,9 +0,0 @@ -:root-target: ../../../target/ - -[[observability]] -= Observability metadata -:page-section-summary-toc: 1 - -include::{root-target}_metrics.adoc[] - -include::{root-target}_spans.adoc[] diff --git a/docs/modules/ROOT/pages/appendix.adoc b/docs/modules/ROOT/pages/appendix.adoc deleted file mode 100644 index 281e4c1d..00000000 --- a/docs/modules/ROOT/pages/appendix.adoc +++ /dev/null @@ -1,14 +0,0 @@ -:numbered!: -[appendix] -[[common-application-properties]] -= Common application properties -:page-section-summary-toc: 1 - - -Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. -This appendix provides a list of common {project-full-name} properties and references to the underlying classes that consume them. - -NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. -Also, you can define your own properties. - - diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/modules/ROOT/pages/intro.adoc b/docs/modules/ROOT/pages/intro.adoc deleted file mode 100644 index 05ef0f68..00000000 --- a/docs/modules/ROOT/pages/intro.adoc +++ /dev/null @@ -1,9 +0,0 @@ - -https://pivotal.io/platform-as-a-service/migrating-to-cloud-native-application-architectures-ebook[Cloud Native] is a style of application development that encourages easy adoption of best practices in the areas of continuous delivery and value-driven development. -A related discipline is that of building https://12factor.net/[12-factor Applications], in which development practices are aligned with delivery and operations goals -- for instance, by using declarative programming and management and monitoring. -Spring Cloud facilitates these styles of development in a number of specific ways. - The starting point is a set of features to which all components in a distributed system need easy access. - -Many of those features are covered by https://projects.spring.io/spring-boot[Spring Boot], on which Spring Cloud builds. Some more features are delivered by Spring Cloud as two libraries: Spring Cloud Context and Spring Cloud Commons. -Spring Cloud Context provides utilities and special services for the `ApplicationContext` of a Spring Cloud application (bootstrap context, encryption, refresh scope, and environment endpoints). Spring Cloud Commons is a set of abstractions and common classes used in different Spring Cloud implementations (such as Spring Cloud Netflix and Spring Cloud Consul). - diff --git a/docs/modules/ROOT/pages/jce.adoc b/docs/modules/ROOT/pages/jce.adoc deleted file mode 100644 index c167f626..00000000 --- a/docs/modules/ROOT/pages/jce.adoc +++ /dev/null @@ -1,8 +0,0 @@ -If you get an exception due to "Illegal key size" and you use Sun's JDK, you need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. -See the following links for more information: - -* https://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html[Java 6 JCE] -* https://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html[Java 7 JCE] -* https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html[Java 8 JCE] - -Extract the files into the JDK/jre/lib/security folder for whichever version of JRE/JDK x64/x86 you use. diff --git a/docs/modules/ROOT/pages/sagan-boot.adoc b/docs/modules/ROOT/pages/sagan-boot.adoc deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/modules/ROOT/pages/sagan-index.adoc b/docs/modules/ROOT/pages/sagan-index.adoc deleted file mode 100644 index b13ae53d..00000000 --- a/docs/modules/ROOT/pages/sagan-index.adoc +++ /dev/null @@ -1,16 +0,0 @@ -Spring Cloud Commons delivers features as two libraries: Spring Cloud Context and Spring Cloud Commons. Spring Cloud Context provides utilities and special services for the ApplicationContext of a Spring Cloud application (bootstrap context, encryption, refresh scope and environment endpoints). Spring Cloud Commons is a set of abstractions and common classes used in different Spring Cloud implementations (eg. Spring Cloud Netflix vs. Spring Cloud Consul). - -## Features - -### Spring Cloud Context features: - -* Bootstrap Context -* `TextEncryptor` beans -* Refresh Scope -* Spring Boot Actuator endpoints for manipulating the `Environment` - -### Spring Cloud Commons features: - -* `DiscoveryClient` interface -* `ServiceRegistry` interface -* Instrumentation for `RestTemplate` to resolve hostnames using `DiscoveryClient` diff --git a/docs/modules/ROOT/pages/spring-cloud-circuitbreaker.adoc b/docs/modules/ROOT/pages/spring-cloud-circuitbreaker.adoc deleted file mode 100755 index 7b0cc3e6..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-circuitbreaker.adoc +++ /dev/null @@ -1,110 +0,0 @@ -[[introduction]] -= Introduction - -Spring Cloud Circuit breaker provides an abstraction across different circuit breaker implementations. -It provides a consistent API to use in your applications, letting you, the developer, choose the circuit breaker implementation that best fits your needs for your application. - -[[supported-implementations]] -== Supported Implementations - -Spring Cloud supports the following circuit-breaker implementations: - -* https://github.com/resilience4j/resilience4j[Resilience4J] -* https://github.com/alibaba/Sentinel[Sentinel] -* https://github.com/spring-projects/spring-retry[Spring Retry] - -[[core-concepts]] -= Core Concepts - -To create a circuit breaker in your code, you can use the `CircuitBreakerFactory` API. When you include a Spring Cloud Circuit Breaker starter on your classpath, a bean that implements this API is automatically created for you. -The following example shows a simple example of how to use this API: - -==== -[source,java] ----- -@Service -public static class DemoControllerService { - private RestTemplate rest; - private CircuitBreakerFactory cbFactory; - - public DemoControllerService(RestTemplate rest, CircuitBreakerFactory cbFactory) { - this.rest = rest; - this.cbFactory = cbFactory; - } - - public String slow() { - return cbFactory.create("slow").run(() -> rest.getForObject("/slow", String.class), throwable -> "fallback"); - } - -} ----- -==== - -The `CircuitBreakerFactory.create` API creates an instance of a class called `CircuitBreaker`. -The `run` method takes a `Supplier` and a `Function`. -The `Supplier` is the code that you are going to wrap in a circuit breaker. -The `Function` is the fallback that is run if the circuit breaker is tripped. -The function is passed the `Throwable` that caused the fallback to be triggered. -You can optionally exclude the fallback if you do not want to provide one. - -[[circuit-breakers-in-reactive-code]] -== Circuit Breakers In Reactive Code - -If Project Reactor is on the class path, you can also use `ReactiveCircuitBreakerFactory` for your reactive code. -The following example shows how to do so: - -==== -[source,java] ----- -@Service -public static class DemoControllerService { - private ReactiveCircuitBreakerFactory cbFactory; - private WebClient webClient; - - - public DemoControllerService(WebClient webClient, ReactiveCircuitBreakerFactory cbFactory) { - this.webClient = webClient; - this.cbFactory = cbFactory; - } - - public Mono slow() { - return webClient.get().uri("/slow").retrieve().bodyToMono(String.class).transform( - it -> cbFactory.create("slow").run(it, throwable -> return Mono.just("fallback"))); - } -} ----- -==== - -The `ReactiveCircuitBreakerFactory.create` API creates an instance of a class called `ReactiveCircuitBreaker`. -The `run` method takes a `Mono` or a `Flux` and wraps it in a circuit breaker. -You can optionally profile a fallback `Function`, which will be called if the circuit breaker is tripped and is passed the `Throwable` -that caused the failure. - -[[configuration]] -= Configuration - -You can configure your circuit breakers by creating beans of type `Customizer`. -The `Customizer` interface has a single method (called `customize`) that takes the `Object` to customize. - -For detailed information on how to customize a given implementation see -the following documentation: - -* link:../../../../spring-cloud-circuitbreaker/current/reference/html/spring-cloud-circuitbreaker.html#configuring-resilience4j-circuit-breakers[Resilience4J] -* link:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-docs/src/main/asciidoc/circuitbreaker-sentinel.adoc#circuit-breaker-spring-cloud-circuit-breaker-with-sentinel--configuring-sentinel-circuit-breakers[Sentinel] -* link:../../../../../spring-cloud-circuitbreaker/docs/current/reference/html/spring-cloud-circuitbreaker.html#configuring-spring-retry-circuit-breakers[Spring Retry] - -Some `CircuitBreaker` implementations such as `Resilience4JCircuitBreaker` call `customize` method every time `CircuitBreaker#run` is called. -It can be inefficient. In that case, you can use `CircuitBreaker#once` method. It is useful where calling `customize` many times doesn't make sense, -for example, in case of https://resilience4j.readme.io/docs/circuitbreaker#section-consume-emitted-circuitbreakerevents[consuming Resilience4j's events]. - -The following example shows the way for each `io.github.resilience4j.circuitbreaker.CircuitBreaker` to consume events. - -==== -[source,java] ----- -Customizer.once(circuitBreaker -> { - circuitBreaker.getEventPublisher() - .onStateTransition(event -> log.info("{}: {}", event.getCircuitBreakerName(), event.getStateTransition())); -}, CircuitBreaker::getName) ----- -==== diff --git a/docs/modules/ROOT/pages/spring-cloud-commons.adoc b/docs/modules/ROOT/pages/spring-cloud-commons.adoc deleted file mode 100644 index f82b6e7b..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons.adoc +++ /dev/null @@ -1,10 +0,0 @@ -[[cloud-native-applications]] -= Cloud Native Applications -:page-section-summary-toc: 1 - - -// TODO: figure out remote includes in docs and replace pasted text -// include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing-docs.adoc[] -NOTE: Spring Cloud is released under the non-restrictive Apache 2.0 license. -If you would like to contribute to this section of the documentation or if you find an error, you can find the source code and issue trackers for the project at {docslink}[github]. - diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/cachedrandompropertysource.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/cachedrandompropertysource.adoc deleted file mode 100644 index 78e0b9cf..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons/cachedrandompropertysource.adoc +++ /dev/null @@ -1,17 +0,0 @@ -[[cachedrandompropertysource]] -= CachedRandomPropertySource -:page-section-summary-toc: 1 - -Spring Cloud Context provides a `PropertySource` that caches random values based on a key. Outside of the caching -functionality it works the same as Spring Boot's https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/env/RandomValuePropertySource.java[`RandomValuePropertySource`]. -This random value might be useful in the case where you want a random value that is consistent even after the Spring Application -context restarts. The property value takes the form of `cachedrandom.[yourkey].[type]` where `yourkey` is the key in the cache. The `type` value can -be any type supported by Spring Boot's `RandomValuePropertySource`. - -==== -[source,properties,indent=0] ----- -myrandom=${cachedrandom.appname.value} ----- -==== - diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/circuit-breaker.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/circuit-breaker.adoc deleted file mode 100644 index 0ad5e20b..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons/circuit-breaker.adoc +++ /dev/null @@ -1,6 +0,0 @@ -[[spring-cloud-circuit-breaker]] -= Spring Cloud Circuit Breaker -:page-section-summary-toc: 1 - -include:../:spring-cloud-circuitbreaker.adoc[leveloffset=+1] - diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/commons:-common-abstractions.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/commons:-common-abstractions.adoc deleted file mode 100644 index fffec0c3..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons/commons:-common-abstractions.adoc +++ /dev/null @@ -1,623 +0,0 @@ -[[spring-cloud-commons:-common-abstractions]] -= Spring Cloud Commons: Common Abstractions - -Patterns such as service discovery, load balancing, and circuit breakers lend themselves to a common abstraction layer that can be consumed by all Spring Cloud clients, independent of the implementation (for example, discovery with Eureka or Consul). - -[[discovery-client]] -== The `@EnableDiscoveryClient` Annotation - -Spring Cloud Commons provides the `@EnableDiscoveryClient` annotation. -This looks for implementations of the `DiscoveryClient` and `ReactiveDiscoveryClient` interfaces with `META-INF/spring.factories`. -Implementations of the discovery client add a configuration class to `spring.factories` under the `org.springframework.cloud.client.discovery.EnableDiscoveryClient` key. -Examples of `DiscoveryClient` implementations include https://cloud.spring.io/spring-cloud-netflix/[Spring Cloud Netflix Eureka], https://cloud.spring.io/spring-cloud-consul/[Spring Cloud Consul Discovery], and https://cloud.spring.io/spring-cloud-zookeeper/[Spring Cloud Zookeeper Discovery]. - -Spring Cloud will provide both the blocking and reactive service discovery clients by default. -You can disable the blocking and/or reactive clients easily by setting `spring.cloud.discovery.blocking.enabled=false` or `spring.cloud.discovery.reactive.enabled=false`. -To completely disable service discovery you just need to set `spring.cloud.discovery.enabled=false`. - -By default, implementations of `DiscoveryClient` auto-register the local Spring Boot server with the remote discovery server. -This behavior can be disabled by setting `autoRegister=false` in `@EnableDiscoveryClient`. - -NOTE: `@EnableDiscoveryClient` is no longer required. -You can put a `DiscoveryClient` implementation on the classpath to cause the Spring Boot application to register with the service discovery server. - -[[health-indicators]] -=== Health Indicators - -Commons auto-configures the following Spring Boot health indicators. - -[[discoveryclienthealthindicator]] -==== DiscoveryClientHealthIndicator -This health indicator is based on the currently registered `DiscoveryClient` implementation. - -* To disable entirely, set `spring.cloud.discovery.client.health-indicator.enabled=false`. -* To disable the description field, set `spring.cloud.discovery.client.health-indicator.include-description=false`. -Otherwise, it can bubble up as the `description` of the rolled up `HealthIndicator`. -* To disable service retrieval, set `spring.cloud.discovery.client.health-indicator.use-services-query=false`. -By default, the indicator invokes the client's `getServices` method. In deployments with many registered services it may too -costly to retrieve all services during every check. This will skip the service retrieval and instead use the client's `probe` method. - -[[discoverycompositehealthcontributor]] -==== DiscoveryCompositeHealthContributor -This composite health indicator is based on all registered `DiscoveryHealthIndicator` beans. To disable, -set `spring.cloud.discovery.client.composite-indicator.enabled=false`. - -[[ordering-discoveryclient-instances]] -=== Ordering `DiscoveryClient` instances -`DiscoveryClient` interface extends `Ordered`. This is useful when using multiple discovery - clients, as it allows you to define the order of the returned discovery clients, similar to -how you can order the beans loaded by a Spring application. By default, the order of any `DiscoveryClient` is set to -`0`. If you want to set a different order for your custom `DiscoveryClient` implementations, you just need to override -the `getOrder()` method so that it returns the value that is suitable for your setup. Apart from this, you can use -properties to set the order of the `DiscoveryClient` -implementations provided by Spring Cloud, among others `ConsulDiscoveryClient`, `EurekaDiscoveryClient` and -`ZookeeperDiscoveryClient`. In order to do it, you just need to set the -`spring.cloud.{clientIdentifier}.discovery.order` (or `eureka.client.order` for Eureka) property to the desired value. - -[[simplediscoveryclient]] -=== SimpleDiscoveryClient - -If there is no Service-Registry-backed `DiscoveryClient` in the classpath, `SimpleDiscoveryClient` -instance, that uses properties to get information on service and instances, will be used. - -The information about the available instances should be passed to via properties in the following format: -`spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s11:8080`, where -`spring.cloud.discovery.client.simple.instances` is the common prefix, then `service1` stands -for the ID of the service in question, while `[0]` indicates the index number of the instance -(as visible in the example, indexes start with `0`), and then the value of `uri` is -the actual URI under which the instance is available. - -[[serviceregistry]] -== ServiceRegistry - -Commons now provides a `ServiceRegistry` interface that provides methods such as `register(Registration)` and `deregister(Registration)`, which let you provide custom registered services. -`Registration` is a marker interface. - -The following example shows the `ServiceRegistry` in use: - -==== -[source,java,indent=0] ----- -@Configuration -@EnableDiscoveryClient(autoRegister=false) -public class MyConfiguration { - private ServiceRegistry registry; - - public MyConfiguration(ServiceRegistry registry) { - this.registry = registry; - } - - // called through some external process, such as an event or a custom actuator endpoint - public void register() { - Registration registration = constructRegistration(); - this.registry.register(registration); - } -} ----- -==== - -Each `ServiceRegistry` implementation has its own `Registry` implementation. - -* `ZookeeperRegistration` used with `ZookeeperServiceRegistry` -* `EurekaRegistration` used with `EurekaServiceRegistry` -* `ConsulRegistration` used with `ConsulServiceRegistry` - -If you are using the `ServiceRegistry` interface, you are going to need to pass the -correct `Registry` implementation for the `ServiceRegistry` implementation you -are using. - - -[[serviceregistry-auto-registration]] -=== ServiceRegistry Auto-Registration - -By default, the `ServiceRegistry` implementation auto-registers the running service. -To disable that behavior, you can set: -* `@EnableDiscoveryClient(autoRegister=false)` to permanently disable auto-registration. -* `spring.cloud.service-registry.auto-registration.enabled=false` to disable the behavior through configuration. - -[[serviceregistry-auto-registration-events]] -==== ServiceRegistry Auto-Registration Events - -There are two events that will be fired when a service auto-registers. The first event, called -`InstancePreRegisteredEvent`, is fired before the service is registered. The second -event, called `InstanceRegisteredEvent`, is fired after the service is registered. You can register an -`ApplicationListener`(s) to listen to and react to these events. - -NOTE: These events will not be fired if the `spring.cloud.service-registry.auto-registration.enabled` property is set to `false`. - -[[service-registry-actuator-endpoint]] -=== Service Registry Actuator Endpoint - -Spring Cloud Commons provides a `/service-registry` actuator endpoint. -This endpoint relies on a `Registration` bean in the Spring Application Context. -Calling `/service-registry` with GET returns the status of the `Registration`. -Using POST to the same endpoint with a JSON body changes the status of the current `Registration` to the new value. -The JSON body has to include the `status` field with the preferred value. -Please see the documentation of the `ServiceRegistry` implementation you use for the allowed values when updating the status and the values returned for the status. -For instance, Eureka's supported statuses are `UP`, `DOWN`, `OUT_OF_SERVICE`, and `UNKNOWN`. - -[[rest-template-loadbalancer-client]] -== Spring RestTemplate as a Load Balancer Client - -You can configure a `RestTemplate` to use a Load-balancer client. -To create a load-balanced `RestTemplate`, create a `RestTemplate` `@Bean` and use the `@LoadBalanced` qualifier, as the following example shows: - -==== -[source,java,indent=0] ----- -@Configuration -public class MyConfiguration { - - @LoadBalanced - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } -} - -public class MyClass { - @Autowired - private RestTemplate restTemplate; - - public String doOtherStuff() { - String results = restTemplate.getForObject("http://stores/stores", String.class); - return results; - } -} ----- -==== - -CAUTION: A `RestTemplate` bean is no longer created through auto-configuration. -Individual applications must create it. - -The URI needs to use a virtual host name (that is, a service name, not a host name). -The BlockingLoadBalancerClient is used to create a full physical address. - -IMPORTANT: To use a load-balanced `RestTemplate`, you need to have a load-balancer implementation in your classpath. -Add xref:spring-cloud-commons/loadbalancer.adoc#spring-cloud-loadbalancer-starter[Spring Cloud LoadBalancer starter] to your project in order to use it. - -[[webclinet-loadbalancer-client]] -== Spring WebClient as a Load Balancer Client - -You can configure `WebClient` to automatically use a load-balancer client. -To create a load-balanced `WebClient`, create a `WebClient.Builder` `@Bean` and use the `@LoadBalanced` qualifier, as follows: - -==== -[source,java,indent=0] ----- -@Configuration -public class MyConfiguration { - - @Bean - @LoadBalanced - public WebClient.Builder loadBalancedWebClientBuilder() { - return WebClient.builder(); - } -} - -public class MyClass { - @Autowired - private WebClient.Builder webClientBuilder; - - public Mono doOtherStuff() { - return webClientBuilder.build().get().uri("http://stores/stores") - .retrieve().bodyToMono(String.class); - } -} ----- -==== - -The URI needs to use a virtual host name (that is, a service name, not a host name). -The Spring Cloud LoadBalancer is used to create a full physical address. - -IMPORTANT: If you want to use a `@LoadBalanced WebClient.Builder`, you need to have a load balancer -implementation in the classpath. We recommend that you add the -xref:spring-cloud-commons/loadbalancer.adoc#spring-cloud-loadbalancer-starter[Spring Cloud LoadBalancer starter] to your project. -Then, `ReactiveLoadBalancer` is used underneath. - -[[retrying-failed-requests]] -=== Retrying Failed Requests - -A load-balanced `RestTemplate` can be configured to retry failed requests. -By default, this logic is disabled. -For the non-reactive version (with `RestTemplate`), you can enable it by adding link:https://github.com/spring-projects/spring-retry[Spring Retry] to your application's classpath. For the reactive version (with `WebTestClient`), you need to set `spring.cloud.loadbalancer.retry.enabled=true`. - -If you would like to disable the retry logic with Spring Retry or Reactive Retry on the classpath, you can set `spring.cloud.loadbalancer.retry.enabled=false`. - -For the non-reactive implementation, if you would like to implement a `BackOffPolicy` in your retries, you need to create a bean of type `LoadBalancedRetryFactory` and override the `createBackOffPolicy()` method. - -For the reactive implementation, you just need to enable it by setting `spring.cloud.loadbalancer.retry.backoff.enabled` to `false`. - -You can set: - -- `spring.cloud.loadbalancer.retry.maxRetriesOnSameServiceInstance` - indicates how many times a request should be retried on the same `ServiceInstance` (counted separately for every selected instance) -- `spring.cloud.loadbalancer.retry.maxRetriesOnNextServiceInstance` - indicates how many times a request should be retried a newly selected `ServiceInstance` -- `spring.cloud.loadbalancer.retry.retryableStatusCodes` - the status codes on which to always retry a failed request. - -For the reactive implementation, you can additionally set: - - `spring.cloud.loadbalancer.retry.backoff.minBackoff` - Sets the minimum backoff duration (by default, 5 milliseconds) - - `spring.cloud.loadbalancer.retry.backoff.maxBackoff` - Sets the maximum backoff duration (by default, max long value of milliseconds) - - `spring.cloud.loadbalancer.retry.backoff.jitter` - Sets the jitter used for calculating the actual backoff duration for each call (by default, 0.5). - -For the reactive implementation, you can also implement your own `LoadBalancerRetryPolicy` to have more detailed control over the load-balanced call retries. - -For both implementations, you can also set the exceptions that trigger the replies by adding a list of values under the `spring.cloud.loadbalancer.[serviceId].retry.retryable-exceptions` property. If you do, we make sure to add `RetryableStatusCodeExceptions` to the list of exceptions provided by you, so that we also retry on retryable status codes. If you do not specify any exceptions via properties, the exceptions we use by default are `IOException`, `TimeoutException` and `RetryableStatusCodeException`. You can also enable retrying on all exceptions by setting `spring.cloud.loadbalancer.[serviceId].retry.retry-on-all-exceptions` to `true`. - -WARNING: If you use the blocking implementation with Spring Retries, if you want to keep the behaviour from previous releases, set `spring.cloud.loadbalancer.[serviceId].retry.retry-on-all-exceptions` to `true` as that used to be the default mode for the blocking implementation. - -NOTE: Individual Loadbalancer clients may be configured individually with the same properties as above except the prefix is `spring.cloud.loadbalancer.clients..*` where `clientId` is the name of the loadbalancer. - -NOTE: For load-balanced retries, by default, we wrap the `ServiceInstanceListSupplier` bean with `RetryAwareServiceInstanceListSupplier` to select a different instance from the one previously chosen, if available. You can disable this behavior by setting the value of `spring.cloud.loadbalancer.retry.avoidPreviousInstance` to `false`. - -==== -[source,java,indent=0] ----- -@Configuration -public class MyConfiguration { - @Bean - LoadBalancedRetryFactory retryFactory() { - return new LoadBalancedRetryFactory() { - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return new ExponentialBackOffPolicy(); - } - }; - } -} ----- -==== - -If you want to add one or more `RetryListener` implementations to your retry functionality, you need to -create a bean of type `LoadBalancedRetryListenerFactory` and return the `RetryListener` array -you would like to use for a given service, as the following example shows: - -==== -[source,java,indent=0] ----- -@Configuration -public class MyConfiguration { - @Bean - LoadBalancedRetryListenerFactory retryListenerFactory() { - return new LoadBalancedRetryListenerFactory() { - @Override - public RetryListener[] createRetryListeners(String service) { - return new RetryListener[]{new RetryListener() { - @Override - public boolean open(RetryContext context, RetryCallback callback) { - //TODO Do you business... - return true; - } - - @Override - public void close(RetryContext context, RetryCallback callback, Throwable throwable) { - //TODO Do you business... - } - - @Override - public void onError(RetryContext context, RetryCallback callback, Throwable throwable) { - //TODO Do you business... - } - }}; - } - }; - } -} ----- -==== - -[[multiple-resttemplate-objects]] -== Multiple `RestTemplate` Objects - -If you want a `RestTemplate` that is not load-balanced, create a `RestTemplate` bean and inject it. -To access the load-balanced `RestTemplate`, use the `@LoadBalanced` qualifier when you create your `@Bean`, as the following example shows: - -==== -[source,java,indent=0] ----- -@Configuration -public class MyConfiguration { - - @LoadBalanced - @Bean - RestTemplate loadBalanced() { - return new RestTemplate(); - } - - @Primary - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } -} - -public class MyClass { - @Autowired - private RestTemplate restTemplate; - - @Autowired - @LoadBalanced - private RestTemplate loadBalanced; - - public String doOtherStuff() { - return loadBalanced.getForObject("http://stores/stores", String.class); - } - - public String doStuff() { - return restTemplate.getForObject("http://example.com", String.class); - } -} ----- -==== - -IMPORTANT: Notice the use of the `@Primary` annotation on the plain `RestTemplate` declaration in the preceding example to disambiguate the unqualified `@Autowired` injection. - -TIP: If you see errors such as `java.lang.IllegalArgumentException: Can not set org.springframework.web.client.RestTemplate field com.my.app.Foo.restTemplate to com.sun.proxy.$Proxy89`, try injecting `RestOperations` or setting `spring.aop.proxyTargetClass=true`. - -[[multiple-webclient-objects]] -== Multiple WebClient Objects - -If you want a `WebClient` that is not load-balanced, create a `WebClient` bean and inject it. -To access the load-balanced `WebClient`, use the `@LoadBalanced` qualifier when you create your `@Bean`, as the following example shows: - -==== -[source,java,indent=0] ----- -@Configuration -public class MyConfiguration { - - @LoadBalanced - @Bean - WebClient.Builder loadBalanced() { - return WebClient.builder(); - } - - @Primary - @Bean - WebClient.Builder webClient() { - return WebClient.builder(); - } -} - -public class MyClass { - @Autowired - private WebClient.Builder webClientBuilder; - - @Autowired - @LoadBalanced - private WebClient.Builder loadBalanced; - - public Mono doOtherStuff() { - return loadBalanced.build().get().uri("http://stores/stores") - .retrieve().bodyToMono(String.class); - } - - public Mono doStuff() { - return webClientBuilder.build().get().uri("http://example.com") - .retrieve().bodyToMono(String.class); - } -} ----- -==== - -[[loadbalanced-webclient]] -== Spring WebFlux `WebClient` as a Load Balancer Client - -The Spring WebFlux can work with both reactive and non-reactive `WebClient` configurations, as the topics describe: - -* xref:spring-cloud-commons/commons:-common-abstractions.adoc#webflux-with-reactive-loadbalancer[Spring WebFlux `WebClient` with `ReactorLoadBalancerExchangeFilterFunction`] -* xref:spring-cloud-commons/commons:-common-abstractions.adoc#load-balancer-exchange-filter-function[Spring WebFlux `WebClient` with a Non-reactive Load Balancer Client] - -[[webflux-with-reactive-loadbalancer]] -=== Spring WebFlux `WebClient` with `ReactorLoadBalancerExchangeFilterFunction` - -You can configure `WebClient` to use the `ReactiveLoadBalancer`. -If you add xref:spring-cloud-commons/loadbalancer.adoc#spring-cloud-loadbalancer-starter[Spring Cloud LoadBalancer starter] to your project -and if `spring-webflux` is on the classpath, `ReactorLoadBalancerExchangeFilterFunction` is auto-configured. -The following example shows how to configure a `WebClient` to use reactive load-balancer: - -==== -[source,java,indent=0] ----- -public class MyClass { - @Autowired - private ReactorLoadBalancerExchangeFilterFunction lbFunction; - - public Mono doOtherStuff() { - return WebClient.builder().baseUrl("http://stores") - .filter(lbFunction) - .build() - .get() - .uri("/stores") - .retrieve() - .bodyToMono(String.class); - } -} ----- -==== - -The URI needs to use a virtual host name (that is, a service name, not a host name). -The `ReactorLoadBalancer` is used to create a full physical address. - -[[load-balancer-exchange-filter-function]] -=== Spring WebFlux `WebClient` with a Non-reactive Load Balancer Client - -If `spring-webflux` is on the classpath, `LoadBalancerExchangeFilterFunction` -is auto-configured. Note, however, that this -uses a non-reactive client under the hood. -The following example shows how to configure a `WebClient` to use load-balancer: - -==== -[source,java,indent=0] ----- -public class MyClass { - @Autowired - private LoadBalancerExchangeFilterFunction lbFunction; - - public Mono doOtherStuff() { - return WebClient.builder().baseUrl("http://stores") - .filter(lbFunction) - .build() - .get() - .uri("/stores") - .retrieve() - .bodyToMono(String.class); - } -} ----- -==== - -The URI needs to use a virtual host name (that is, a service name, not a host name). -The `LoadBalancerClient` is used to create a full physical address. - -WARN: This approach is now deprecated. -We suggest that you use xref:spring-cloud-commons/commons:-common-abstractions.adoc#webflux-with-reactive-loadbalancer[WebFlux with reactive Load-Balancer] -instead. - -[[ignore-network-interfaces]] -== Ignore Network Interfaces - -Sometimes, it is useful to ignore certain named network interfaces so that they can be excluded from Service Discovery registration (for example, when running in a Docker container). -A list of regular expressions can be set to cause the desired network interfaces to be ignored. -The following configuration ignores the `docker0` interface and all interfaces that start with `veth`: - -.application.yml -==== ----- -spring: - cloud: - inetutils: - ignoredInterfaces: - - docker0 - - veth.* ----- -==== - -You can also force the use of only specified network addresses by using a list of regular expressions, as the following example shows: - -.bootstrap.yml -==== ----- -spring: - cloud: - inetutils: - preferredNetworks: - - 192.168 - - 10.0 ----- -==== - -You can also force the use of only site-local addresses, as the following example shows: - -.application.yml -==== ----- -spring: - cloud: - inetutils: - useOnlySiteLocalInterfaces: true ----- -==== - -See https://docs.oracle.com/javase/8/docs/api/java/net/Inet4Address.html#isSiteLocalAddress--[Inet4Address.html.isSiteLocalAddress()] for more details about what constitutes a site-local address. - -[[http-clients]] -== HTTP Client Factories - -Spring Cloud Commons provides beans for creating both Apache HTTP clients (`ApacheHttpClientFactory`) and OK HTTP clients (`OkHttpClientFactory`). -The `OkHttpClientFactory` bean is created only if the OK HTTP jar is on the classpath. -In addition, Spring Cloud Commons provides beans for creating the connection managers used by both clients: `ApacheHttpClientConnectionManagerFactory` for the Apache HTTP client and `OkHttpClientConnectionPoolFactory` for the OK HTTP client. -If you would like to customize how the HTTP clients are created in downstream projects, you can provide your own implementation of these beans. -In addition, if you provide a bean of type `HttpClientBuilder` or `OkHttpClient.Builder`, the default factories use these builders as the basis for the builders returned to downstream projects. -You can also disable the creation of these beans by setting `spring.cloud.httpclientfactories.apache.enabled` or `spring.cloud.httpclientfactories.ok.enabled` to `false`. - -[[enabled-features]] -== Enabled Features - -Spring Cloud Commons provides a `/features` actuator endpoint. -This endpoint returns features available on the classpath and whether they are enabled. -The information returned includes the feature type, name, version, and vendor. - -[[feature-types]] -=== Feature types - -There are two types of 'features': abstract and named. - -Abstract features are features where an interface or abstract class is defined and that an implementation the creates, such as `DiscoveryClient`, `LoadBalancerClient`, or `LockService`. -The abstract class or interface is used to find a bean of that type in the context. -The version displayed is `bean.getClass().getPackage().getImplementationVersion()`. - -Named features are features that do not have a particular class they implement. These features include "`Circuit Breaker`", "`API Gateway`", "`Spring Cloud Bus`", and others. These features require a name and a bean type. - -[[declaring-features]] -=== Declaring features - -Any module can declare any number of `HasFeature` beans, as the following examples show: - -==== -[source,java,indent=0] ----- -@Bean -public HasFeatures commonsFeatures() { - return HasFeatures.abstractFeatures(DiscoveryClient.class, LoadBalancerClient.class); -} - -@Bean -public HasFeatures consulFeatures() { - return HasFeatures.namedFeatures( - new NamedFeature("Spring Cloud Bus", ConsulBusAutoConfiguration.class), - new NamedFeature("Circuit Breaker", HystrixCommandAspect.class)); -} - -@Bean -HasFeatures localFeatures() { - return HasFeatures.builder() - .abstractFeature(Something.class) - .namedFeature(new NamedFeature("Some Other Feature", Someother.class)) - .abstractFeature(Somethingelse.class) - .build(); -} ----- -==== - -Each of these beans should go in an appropriately guarded `@Configuration`. - - -[[spring-cloud-compatibility-verification]] -== Spring Cloud Compatibility Verification - -Due to the fact that some users have problem with setting up Spring Cloud application, we've decided -to add a compatibility verification mechanism. It will break if your current setup is not compatible -with Spring Cloud requirements, together with a report, showing what exactly went wrong. - -At the moment we verify which version of Spring Boot is added to your classpath. - -Example of a report - -==== ----- -*************************** -APPLICATION FAILED TO START -*************************** - -Description: - -Your project setup is incompatible with our requirements due to following reasons: - -- Spring Boot [2.1.0.RELEASE] is not compatible with this Spring Cloud release train - - -Action: - -Consider applying the following actions: - -- Change Spring Boot version to one of the following versions [1.2.x, 1.3.x] . -You can find the latest Spring Boot versions here [https://spring.io/projects/spring-boot#learn]. -If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [https://spring.io/projects/spring-cloud#overview] and check the [Release Trains] section. ----- -==== - -In order to disable this feature, set `spring.cloud.compatibility-verifier.enabled` to `false`. -If you want to override the compatible Spring Boot versions, just set the -`spring.cloud.compatibility-verifier.compatible-boot-versions` property with a comma separated list -of compatible Spring Boot versions. - diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/configuration-properties.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/configuration-properties.adoc deleted file mode 100644 index 1be43fb7..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons/configuration-properties.adoc +++ /dev/null @@ -1,5 +0,0 @@ -[[configuration-properties]] -= Configuration Properties -:page-section-summary-toc: 1 - -To see the list of all Spring Cloud Commons related configuration properties please check link:appendix.html[the Appendix page]. diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/context:-application-context-services.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/context:-application-context-services.adoc deleted file mode 100644 index 7f2e858f..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons/context:-application-context-services.adoc +++ /dev/null @@ -1,255 +0,0 @@ -[[spring-cloud-context:-application-context-services]] -= Spring Cloud Context: Application Context Services - -Spring Boot has an opinionated view of how to build an application with Spring. -For instance, it has conventional locations for common configuration files and has endpoints for common management and monitoring tasks. -Spring Cloud builds on top of that and adds a few features that many components in a system would use or occasionally need. - -[[the-bootstrap-application-context]] -== The Bootstrap Application Context - -A Spring Cloud application operates by creating a "`bootstrap`" context, which is a parent context for the main application. -This context is responsible for loading configuration properties from the external sources and for decrypting properties in the local external configuration files. -The two contexts share an `Environment`, which is the source of external properties for any Spring application. -By default, bootstrap properties (not `bootstrap.properties` but properties that are loaded during the bootstrap phase) are added with high precedence, so they cannot be overridden by local configuration. - -The bootstrap context uses a different convention for locating external configuration than the main application context. -Instead of `application.yml` (or `.properties`), you can use `bootstrap.yml`, keeping the external configuration for bootstrap and main context nicely separate. -The following listing shows an example: - -.bootstrap.yml -==== ----- -spring: - application: - name: foo - cloud: - config: - uri: ${SPRING_CONFIG_URI:http://localhost:8888} ----- -==== - -If your application needs any application-specific configuration from the server, it is a good idea to set the `spring.application.name` (in `bootstrap.yml` or `application.yml`). -For the property `spring.application.name` to be used as the application's context ID, you must set it in `bootstrap.[properties | yml]`. - -If you want to retrieve specific profile configuration, you should also set `spring.profiles.active` in `bootstrap.[properties | yml]`. - -You can disable the bootstrap process completely by setting `spring.cloud.bootstrap.enabled=false` (for example, in system properties). - -[[application-context-hierarchies]] -== Application Context Hierarchies - -If you build an application context from `SpringApplication` or `SpringApplicationBuilder`, the Bootstrap context is added as a parent to that context. -It is a feature of Spring that child contexts inherit property sources and profiles from their parent, so the "`main`" application context contains additional property sources, compared to building the same context without Spring Cloud Config. -The additional property sources are: - -* "`bootstrap`": If any `PropertySourceLocators` are found in the bootstrap context and if they have non-empty properties, an optional `CompositePropertySource` appears with high priority. -An example would be properties from the Spring Cloud Config Server. -See "`xref:spring-cloud-commons/context:-application-context-services.adoc#customizing-bootstrap-property-sources[Customizing the Bootstrap Property Sources]`" for how to customize the contents of this property source. - -NOTE: Prior to Spring Cloud 2022.0.3 `PropertySourceLocators` (including the ones for Spring Cloud Config) were run during -the main application context and not in the Bootstrap context. You can force `PropertySourceLocators` to be run during the -Bootstrap context by setting `spring.cloud.config.initialize-on-context-refresh=true` in `bootstrap.[properties | yaml]`. - -* "`applicationConfig: [classpath:bootstrap.yml]`" (and related files if Spring profiles are active): If you have a `bootstrap.yml` (or `.properties`), those properties are used to configure the bootstrap context. -Then they get added to the child context when its parent is set. -They have lower precedence than the `application.yml` (or `.properties`) and any other property sources that are added to the child as a normal part of the process of creating a Spring Boot application. -See "`xref:spring-cloud-commons/context:-application-context-services.adoc#customizing-bootstrap-properties[Changing the Location of Bootstrap Properties]`" for how to customize the contents of these property sources. - -Because of the ordering rules of property sources, the "`bootstrap`" entries take precedence. -However, note that these do not contain any data from `bootstrap.yml`, which has very low precedence but can be used to set defaults. - -You can extend the context hierarchy by setting the parent context of any `ApplicationContext` you create -- for example, by using its own interface or with the `SpringApplicationBuilder` convenience methods (`parent()`, `child()` and `sibling()`). -The bootstrap context is the parent of the most senior ancestor that you create yourself. -Every context in the hierarchy has its own "`bootstrap`" (possibly empty) property source to avoid promoting values inadvertently from parents down to their descendants. -If there is a config server, every context in the hierarchy can also (in principle) have a different `spring.application.name` and, hence, a different remote property source. -Normal Spring application context behavior rules apply to property resolution: properties from a child context override those in -the parent, by name and also by property source name. -(If the child has a property source with the same name as the parent, the value from the parent is not included in the child). - -Note that the `SpringApplicationBuilder` lets you share an `Environment` amongst the whole hierarchy, but that is not the default. -Thus, sibling contexts (in particular) do not need to have the same profiles or property sources, even though they may share common values with their parent. - -[[customizing-bootstrap-properties]] -== Changing the Location of Bootstrap Properties - -The `bootstrap.yml` (or `.properties`) location can be specified by setting `spring.cloud.bootstrap.name` (default: `bootstrap`), `spring.cloud.bootstrap.location` (default: empty) or `spring.cloud.bootstrap.additional-location` (default: empty) -- for example, in System properties. - -Those properties behave like the `spring.config.*` variants with the same name. -With `spring.cloud.bootstrap.location` the default locations are replaced and only the specified ones are used. -To add locations to the list of default ones, `spring.cloud.bootstrap.additional-location` can be used. -In fact, they are used to set up the bootstrap `ApplicationContext` by setting those properties in its `Environment`. -If there is an active profile (from `spring.profiles.active` or through the `Environment` API in the context you are building), properties in that profile get loaded as well, the same as in a regular Spring Boot app -- for example, from `bootstrap-development.properties` for a `development` profile. - -[[overriding-bootstrap-properties]] -== Overriding the Values of Remote Properties - -The property sources that are added to your application by the bootstrap context are often "`remote`" (from example, from Spring Cloud Config Server). -By default, they cannot be overridden locally. -If you want to let your applications override the remote properties with their own system properties or config files, the remote property source has to grant it permission by setting `spring.cloud.config.allowOverride=true` (it does not work to set this locally). -Once that flag is set, two finer-grained settings control the location of the remote properties in relation to system properties and the application's local configuration: - -* `spring.cloud.config.overrideNone=true`: Override from any local property source. -* `spring.cloud.config.overrideSystemProperties=false`: Only system properties, command line arguments, and environment variables (but not the local config files) should override the remote settings. - -[[customizing-the-bootstrap-configuration]] -== Customizing the Bootstrap Configuration - -The bootstrap context can be set to do anything you like by adding entries to `/META-INF/spring.factories` under a key named `org.springframework.cloud.bootstrap.BootstrapConfiguration`. -This holds a comma-separated list of Spring `@Configuration` classes that are used to create the context. -Any beans that you want to be available to the main application context for autowiring can be created here. -There is a special contract for `@Beans` of type `ApplicationContextInitializer`. -If you want to control the startup sequence, you can mark classes with the `@Order` annotation (the default order is `last`). - -WARNING: When adding custom `BootstrapConfiguration`, be careful that the classes you add are not `@ComponentScanned` by mistake into your "`main`" application context, where they might not be needed. -Use a separate package name for boot configuration classes and make sure that name is not already covered by your `@ComponentScan` or `@SpringBootApplication` annotated configuration classes. - -The bootstrap process ends by injecting initializers into the main `SpringApplication` instance (which is the normal Spring Boot startup sequence, whether it runs as a standalone application or is deployed in an application server). -First, a bootstrap context is created from the classes found in `spring.factories`. -Then, all `@Beans` of type `ApplicationContextInitializer` are added to the main `SpringApplication` before it is started. - -[[customizing-bootstrap-property-sources]] -== Customizing the Bootstrap Property Sources - -The default property source for external configuration added by the bootstrap process is the Spring Cloud Config Server, but you can add additional sources by adding beans of type `PropertySourceLocator` to the bootstrap context (through `spring.factories`). -For instance, you can insert additional properties from a different server or from a database. - -As an example, consider the following custom locator: - -==== -[source,java] ----- -@Configuration -public class CustomPropertySourceLocator implements PropertySourceLocator { - - @Override - public PropertySource locate(Environment environment) { - return new MapPropertySource("customProperty", - Collections.singletonMap("property.from.sample.custom.source", "worked as intended")); - } - -} ----- -==== - -The `Environment` that is passed in is the one for the `ApplicationContext` about to be created -- in other words, the one for which we supply additional property sources. -It already has its normal Spring Boot-provided property sources, so you can use those to locate a property source specific to this `Environment` (for example, by keying it on `spring.application.name`, as is done in the default Spring Cloud Config Server property source locator). - -If you create a jar with this class in it and then add a `META-INF/spring.factories` containing the following setting, the `customProperty` `PropertySource` appears in any application that includes that jar on its classpath: - -==== -[source] ----- -org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator ----- -==== - -As of Spring Cloud 2022.0.3, Spring Cloud will now call `PropertySourceLocators` twice. The first fetch -will retrieve any property sources without any profiles. These property sources will have the opportunity to -activate profiles using `spring.profiles.active`. After the main application context starts `PropertySourceLocators` -will be called a second time, this time with any active profiles allowing `PropertySourceLocators` to locate -any additional `PropertySources` with profiles. - -[[logging-configuration]] -== Logging Configuration - -If you use Spring Boot to configure log settings, you should place this configuration in `bootstrap.[yml | properties]` if you would like it to apply to all events. - -NOTE: For Spring Cloud to initialize logging configuration properly, you cannot use a custom prefix. -For example, using `custom.loggin.logpath` is not recognized by Spring Cloud when initializing the logging system. - -[[environment-changes]] -== Environment Changes - -The application listens for an `EnvironmentChangeEvent` and reacts to the change in a couple of standard ways (additional `ApplicationListeners` can be added as `@Beans` in the normal way). -When an `EnvironmentChangeEvent` is observed, it has a list of key values that have changed, and the application uses those to: - -* Re-bind any `@ConfigurationProperties` beans in the context. -* Set the logger levels for any properties in `logging.level.*`. - -Note that the Spring Cloud Config Client does not, by default, poll for changes in the `Environment`. -Generally, we would not recommend that approach for detecting changes (although you can set it up with a -`@Scheduled` annotation). -If you have a scaled-out client application, it is better to broadcast the `EnvironmentChangeEvent` to all the instances instead of having them polling for changes (for example, by using the https://github.com/spring-cloud/spring-cloud-bus[Spring Cloud Bus]). - -The `EnvironmentChangeEvent` covers a large class of refresh use cases, as long as you can actually make a change to the `Environment` and publish the event. -Note that those APIs are public and part of core Spring). -You can verify that the changes are bound to `@ConfigurationProperties` beans by visiting the `/configprops` endpoint (a standard Spring Boot Actuator feature). -For instance, a `DataSource` can have its `maxPoolSize` changed at runtime (the default `DataSource` created by Spring Boot is a `@ConfigurationProperties` bean) and grow capacity dynamically. -Re-binding `@ConfigurationProperties` does not cover another large class of use cases, where you need more control over the refresh and where you need a change to be atomic over the whole `ApplicationContext`. -To address those concerns, we have `@RefreshScope`. - -[[refresh-scope]] -== Refresh Scope - -When there is a configuration change, a Spring `@Bean` that is marked as `@RefreshScope` gets special treatment. -This feature addresses the problem of stateful beans that get their configuration injected only when they are initialized. -For instance, if a `DataSource` has open connections when the database URL is changed through the `Environment`, you probably want the holders of those connections to be able to complete what they are doing. -Then, the next time something borrows a connection from the pool, it gets one with the new URL. - -Sometimes, it might even be mandatory to apply the `@RefreshScope` annotation on some beans that can be only initialized once. -If a bean is "`immutable`", you have to either annotate the bean with `@RefreshScope` or specify the classname under the property key: `spring.cloud.refresh.extra-refreshable`. - -WARNING: If you hava a `DataSource` bean that is a `HikariDataSource`, it can not be -refreshed. It is the default value for `spring.cloud.refresh.never-refreshable`. Choose a -different `DataSource` implementation if you need it to be refreshed. - -Refresh scope beans are lazy proxies that initialize when they are used (that is, when a method is called), and the scope acts as a cache of initialized values. -To force a bean to re-initialize on the next method call, you must invalidate its cache entry. - -The `RefreshScope` is a bean in the context and has a public `refreshAll()` method to refresh all beans in the scope by clearing the target cache. -The `/refresh` endpoint exposes this functionality (over HTTP or JMX). -To refresh an individual bean by name, there is also a `refresh(String)` method. - -To expose the `/refresh` endpoint, you need to add following configuration to your application: - -==== -[source,yaml] ----- -management: - endpoints: - web: - exposure: - include: refresh ----- -==== - -NOTE: `@RefreshScope` works (technically) on a `@Configuration` class, but it might lead to surprising behavior. -For example, it does not mean that all the `@Beans` defined in that class are themselves in `@RefreshScope`. -Specifically, anything that depends on those beans cannot rely on them being updated when a refresh is initiated, unless it is itself in `@RefreshScope`. -In that case, it is rebuilt on a refresh and its dependencies are re-injected. -At that point, they are re-initialized from the refreshed `@Configuration`). - -NOTE: Removing a configuration value and then performing a refresh will not update the presence of the configuration value. -The configuration property must be present in order to update the value after a refresh. If you are relying on the presence of -a value in your application you might want to switch your logic to rely on its absence instead. Another option would be to rely -on the value changing rather than not being present in the application's configuration. - -[[encryption-and-decryption]] -== Encryption and Decryption - -Spring Cloud has an `Environment` pre-processor for decrypting property values locally. -It follows the same rules as the Spring Cloud Config Server and has the same external configuration through `encrypt.\*`. -Thus, you can use encrypted values in the form of `{cipher}*`, and, as long as there is a valid key, they are decrypted before the main application context gets the `Environment` settings. -To use the encryption features in an application, you need to include Spring Security RSA in your classpath (Maven co-ordinates: `org.springframework.security:spring-security-rsa`), and you also need the full strength JCE extensions in your JVM. - -include:../:jce.adoc[] - -[[endpoints]] -== Endpoints - -For a Spring Boot Actuator application, some additional management endpoints are available. You can use: - -* `POST` to `/actuator/env` to update the `Environment` and rebind `@ConfigurationProperties` and log levels. - To enabled this endpoint you must set `management.endpoint.env.post.enabled=true`. -* `/actuator/refresh` to re-load the boot strap context and refresh the `@RefreshScope` beans. -* `/actuator/restart` to close the `ApplicationContext` and restart it (disabled by default). -* `/actuator/pause` and `/actuator/resume` for calling the `Lifecycle` methods (`stop()` and `start()` on the `ApplicationContext`). - -NOTE: While enabling the `POST` method for `/actuator/env` endpoint can provide flexibility and convenience in managing your application environment variables, -it's critical to ensure that the endpoint is secured and monitored to prevent potential security risks. -Add a `spring-boot-starter-security` dependency to configure access control for the actuator’s endpoint. - -NOTE: If you disable the `/actuator/restart` endpoint then the `/actuator/pause` and `/actuator/resume` endpoints -will also be disabled since they are just a special case of `/actuator/restart`. - diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc deleted file mode 100644 index 97ad8e0f..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc +++ /dev/null @@ -1,517 +0,0 @@ -[[spring-cloud-loadbalancer]] -= Spring Cloud LoadBalancer - -Spring Cloud provides its own client-side load-balancer abstraction and implementation. For the load-balancing -mechanism, `ReactiveLoadBalancer` interface has been added and a *Round-Robin-based* and *Random* implementations -have been provided for it. In order to get instances to select from reactive `ServiceInstanceListSupplier` -is used. Currently we support a service-discovery-based implementation of `ServiceInstanceListSupplier` -that retrieves available instances from Service Discovery using a xref:spring-cloud-commons/commons:-common-abstractions.adoc#discovery-client[Discovery Client] available in the classpath. - -TIP: It is possible to disable Spring Cloud LoadBalancer by setting the value of `spring.cloud.loadbalancer.enabled` to `false`. - -[[eager-loading-of-loadbalancer-contexts]] -== Eager loading of LoadBalancer contexts - -Spring Cloud LoadBalancer creates a separate Spring child context for each service id. By default, these contexts are initialised lazily, whenever the first request for a service id is being load-balanced. - -You can choose to load those contexts eagerly. In order to do that, specify the service ids for which you want to do eager load using the `spring.cloud-loadbalancer.eager-load.clients` property. - -[[switching-between-the-load-balancing-algorithms]] -== Switching between the load-balancing algorithms - -The `ReactiveLoadBalancer` implementation that is used by default is `RoundRobinLoadBalancer`. To switch to a different implementation, either for selected services or all of them, you can use the xref:spring-cloud-commons/loadbalancer.adoc#custom-loadbalancer-configuration[custom LoadBalancer configurations mechanism]. - -For example, the following configuration can be passed via `@LoadBalancerClient` annotation to switch to using the `RandomLoadBalancer`: - -[[random-loadbalancer-configuration]] -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - ReactorLoadBalancer randomLoadBalancer(Environment environment, - LoadBalancerClientFactory loadBalancerClientFactory) { - String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); - return new RandomLoadBalancer(loadBalancerClientFactory - .getLazyProvider(name, ServiceInstanceListSupplier.class), - name); - } -} ----- - -NOTE: The classes you pass as `@LoadBalancerClient` or `@LoadBalancerClients` configuration arguments should either not be annotated with `@Configuration` or be outside component scan scope. - -[[spring-cloud-loadbalancer-integrations]] -== Spring Cloud LoadBalancer integrations - -In order to make it easy to use Spring Cloud LoadBalancer, we provide `ReactorLoadBalancerExchangeFilterFunction` that can be used with `WebClient` and `BlockingLoadBalancerClient` that works with `RestTemplate`. -You can see more information and examples of usage in the following sections: - -* xref:spring-cloud-commons/commons:-common-abstractions.adoc#rest-template-loadbalancer-client[Spring RestTemplate as a Load Balancer Client] -* xref:spring-cloud-commons/commons:-common-abstractions.adoc#webclinet-loadbalancer-client[Spring WebClient as a Load Balancer Client] -* xref:spring-cloud-commons/commons:-common-abstractions.adoc#webflux-with-reactive-loadbalancer[Spring WebFlux WebClient with `ReactorLoadBalancerExchangeFilterFunction`] - -[[loadbalancer-caching]] -== Spring Cloud LoadBalancer Caching - -Apart from the basic `ServiceInstanceListSupplier` implementation that retrieves instances via `DiscoveryClient` each time it has to choose an instance, we provide two caching implementations. - -[[https://github-com/ben-manes/caffeine[caffeine]-backed-loadbalancer-cache-implementation]] -=== https://github.com/ben-manes/caffeine[Caffeine]-backed LoadBalancer Cache Implementation - -If you have `com.github.ben-manes.caffeine:caffeine` in the classpath, Caffeine-based implementation will be used. -See the xref:spring-cloud-commons/loadbalancer.adoc#loadbalancer-cache-configuration[LoadBalancerCacheConfiguration] section for information on how to configure it. - -If you are using Caffeine, you can also override the default Caffeine Cache setup for the LoadBalancer by passing your own https://static.javadoc.io/com.github.ben-manes.caffeine/caffeine/2.2.2/com/github/benmanes/caffeine/cache/CaffeineSpec.html[Caffeine Specification] -in the `spring.cloud.loadbalancer.cache.caffeine.spec` property. - -WARN: Passing your own Caffeine specification will override any other LoadBalancerCache settings, including xref:spring-cloud-commons/loadbalancer.adoc#loadbalancer-cache-configuration[General LoadBalancer Cache Configuration] fields, such as `ttl` and `capacity`. - -[[default-loadbalancer-cache-implementation]] -=== Default LoadBalancer Cache Implementation - -If you do not have Caffeine in the classpath, the `DefaultLoadBalancerCache`, which comes automatically with `spring-cloud-starter-loadbalancer`, will be used. -See the xref:spring-cloud-commons/loadbalancer.adoc#loadbalancer-cache-configuration[LoadBalancerCacheConfiguration] section for information on how to configure it. - -TIP: To use Caffeine instead of the default cache, add the `com.github.ben-manes.caffeine:caffeine` dependency to classpath. - -[[loadbalancer-cache-configuration]] -=== LoadBalancer Cache Configuration - -You can set your own `ttl` value (the time after write after which entries should be expired), expressed as `Duration`, by passing a `String` compliant with the https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-conversion-duration[Spring Boot `String` to `Duration` converter syntax]. -as the value of the `spring.cloud.loadbalancer.cache.ttl` property. -You can also set your own LoadBalancer cache initial capacity by setting the value of the `spring.cloud.loadbalancer.cache.capacity` property. - -The default setup includes `ttl` set to 35 seconds and the default `initialCapacity` is `256`. - -You can also altogether disable loadBalancer caching by setting the value of `spring.cloud.loadbalancer.cache.enabled` -to `false`. - -WARNING: Although the basic, non-cached, implementation is useful for prototyping and testing, it's much less efficient than the cached versions, so we recommend always using the cached version in production. If the caching is already done by the `DiscoveryClient` implementation, for example `EurekaDiscoveryClient`, the load-balancer caching should be disabled to prevent double caching. - -NOTE: When you create your own configuration, if you use `CachingServiceInstanceListSupplier` make sure to place it in the hierarchy directly after the supplier that retrieves the instances over the network, for example, `DiscoveryClientServiceInstanceListSupplier`, before any other filtering suppliers. - -[[weighted-load-balancing]] -== Weighted Load-Balancing - -To enable weighted load-balancing, we provide the `WeightedServiceInstanceListSupplier`. We use `WeightFunction` to calculate the weight of each instance. -By default, we try to read and parse the weight from the metadata map (the key is `weight`). - -If the weight is not specified in the metadata map, we default the weight of this instance to be 1. - -You can configure it either by setting the value of `spring.cloud.loadbalancer.configurations` to `weighted` or by providing your own `ServiceInstanceListSupplier` bean, for example: - -[[weighted-custom-loadbalancer-configuration]] -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder() - .withDiscoveryClient() - .withWeighted() - .withCaching() - .build(context); - } -} ----- - -NOTE: You can also customize the weight calculation logic by providing `WeightFunction`. - -You can use this sample configuration to make all instances have a random weight: - -[[random-weight-weighted-custom-loadbalancer-configuration]] -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder() - .withDiscoveryClient() - .withWeighted(instance -> ThreadLocalRandom.current().nextInt(1, 101)) - .withCaching() - .build(context); - } -} ----- - -[[zone-based-load-balancing]] -== Zone-Based Load-Balancing - -To enable zone-based load-balancing, we provide the `ZonePreferenceServiceInstanceListSupplier`. -We use `DiscoveryClient`-specific `zone` configuration (for example, `eureka.instance.metadata-map.zone`) to pick the zone that the client tries to filter available service instances for. - -NOTE: You can also override `DiscoveryClient`-specific zone setup by setting the value of `spring.cloud.loadbalancer.zone` property. - -WARNING: For the time being, only Eureka Discovery Client is instrumented to set the LoadBalancer zone. For other discovery client, set the `spring.cloud.loadbalancer.zone` property. More instrumentations coming shortly. - -NOTE: To determine the zone of a retrieved `ServiceInstance`, we check the value under the `"zone"` key in its metadata map. - -The `ZonePreferenceServiceInstanceListSupplier` filters retrieved instances and only returns the ones within the same zone. -If the zone is `null` or there are no instances within the same zone, it returns all the retrieved instances. - -In order to use the zone-based load-balancing approach, you will have to instantiate a `ZonePreferenceServiceInstanceListSupplier` bean in a xref:spring-cloud-commons/loadbalancer.adoc#custom-loadbalancer-configuration[custom configuration]. - -We use delegates to work with `ServiceInstanceListSupplier` beans. -We suggest using a `DiscoveryClientServiceInstanceListSupplier` delegate, wrapping it with a `CachingServiceInstanceListSupplier` to leverage xref:spring-cloud-commons/loadbalancer.adoc#loadbalancer-caching[LoadBalancer caching mechanism], and then passing the resulting bean in the constructor of `ZonePreferenceServiceInstanceListSupplier`. - -You can use this sample configuration to set it up: - -[[zoned-based-custom-loadbalancer-configuration]] -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder() - .withDiscoveryClient() - .withCaching() - .withZonePreference() - .build(context); - } -} ----- - -[[instance-health-check-for-loadbalancer]] -== Instance Health-Check for LoadBalancer - -It is possible to enable a scheduled HealthCheck for the LoadBalancer. The `HealthCheckServiceInstanceListSupplier` -is provided for that. It regularly verifies if the instances provided by a delegate -`ServiceInstanceListSupplier` are still alive and only returns the healthy instances, -unless there are none - then it returns all the retrieved instances. - -TIP: This mechanism is particularly helpful while using the `SimpleDiscoveryClient`. For the -clients backed by an actual Service Registry, it's not necessary to use, as we already get -healthy instances after querying the external ServiceDiscovery. - -TIP: This supplier is also recommended for setups with a small number of instances per service -in order to avoid retrying calls on a failing instance. - -WARNING: If using any of the Service Discovery-backed suppliers, adding this health-check mechanism is usually not necessary, as we retrieve the health state of the instances directly -from the Service Registry. - -TIP: The `HealthCheckServiceInstanceListSupplier` relies on having updated instances provided by a delegate flux. In the rare cases when you want to use a delegate that does not refresh the instances, even though the list of instances may change (such as the `DiscoveryClientServiceInstanceListSupplier` provided by us), you can set `spring.cloud.loadbalancer.health-check.refetch-instances` to `true` to have the instance list refreshed by the `HealthCheckServiceInstanceListSupplier`. You can then also adjust the refretch intervals by modifying the value of `spring.cloud.loadbalancer.health-check.refetch-instances-interval` and opt to disable the additional healthcheck repetitions by setting `spring.cloud.loadbalancer.health-check.repeat-health-check` to `false` as every instances refetch - will also trigger a healthcheck. - -`HealthCheckServiceInstanceListSupplier` uses properties prefixed with -`spring.cloud.loadbalancer.health-check`. You can set the `initialDelay` and `interval` -for the scheduler. You can set the default path for the healthcheck URL by setting -the value of the `spring.cloud.loadbalancer.health-check.path.default` property. You can also set a specific value for any given service by setting the value of the `spring.cloud.loadbalancer.health-check.path.[SERVICE_ID]` property, substituting `[SERVICE_ID]` with the correct ID of your service. If the `[SERVICE_ID]` is not specified, `/actuator/health` is used by default. If the `[SERVICE_ID]` is set to `null` or empty as a value, then the health check will not be executed. You can also set a custom port for health-check requests by setting the value of `spring.cloud.loadbalancer.health-check.port`. If none is set, the port under which the requested service is available at the service instance. - -TIP: If you rely on the default path (`/actuator/health`), make sure you add `spring-boot-starter-actuator` to your collaborator's dependencies, unless you are planning to add such an endpoint on your own. - -TIP: By default, the `healthCheckFlux` will emit on each alive `ServiceInstance` that has been retrieved. You can modify this behaviour by setting the value of `spring.cloud.loadbalancer.health-check.update-results-list` to `false`. If this property is set to `false`, the entire alive instances sequence is first collected into a list and only then emitted, which ensures the flux does not emit values in between the health-check intervals set in properties. - -In order to use the health-check scheduler approach, you will have to instantiate a `HealthCheckServiceInstanceListSupplier` bean in a xref:spring-cloud-commons/loadbalancer.adoc#custom-loadbalancer-configuration[custom configuration]. - -We use delegates to work with `ServiceInstanceListSupplier` beans. -We suggest passing a `DiscoveryClientServiceInstanceListSupplier` delegate in the constructor of `HealthCheckServiceInstanceListSupplier`. - -You can use this sample configuration to set it up: - -[[health-check-based-custom-loadbalancer-configuration]] -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder() - .withDiscoveryClient() - .withHealthChecks() - .build(context); - } - } ----- - -TIP: For the non-reactive stack, create this supplier with the `withBlockingHealthChecks()`. -You can also pass your own `WebClient` or `RestTemplate` instance to be used for the checks. - -WARNING: `HealthCheckServiceInstanceListSupplier` has its own caching mechanism based on Reactor Flux `replay()`. Therefore, if it's being used, you may want to skip wrapping that supplier with `CachingServiceInstanceListSupplier`. - -NOTE: When you create your own configuration, `HealthCheckServiceInstanceListSupplier`, make sure to place it in the hierarchy directly after the supplier that retrieves the instances over the network, for example, `DiscoveryClientServiceInstanceListSupplier`, before any other filtering suppliers. - -[[same-instance-preference-for-loadbalancer]] -== Same instance preference for LoadBalancer - -You can set up the LoadBalancer in such a way that it prefers the instance that was previously selected, if that instance is available. - -For that, you need to use `SameInstancePreferenceServiceInstanceListSupplier`. You can configure it either by setting the value of `spring.cloud.loadbalancer.configurations` to `same-instance-preference` or by providing your own `ServiceInstanceListSupplier` bean -- for example: - -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder() - .withDiscoveryClient() - .withSameInstancePreference() - .build(context); - } - } ----- - -TIP: This is also a replacement for Zookeeper `StickyRule`. - -[[request-based-sticky-session-for-loadbalancer]] -== Request-based Sticky Session for LoadBalancer - -You can set up the LoadBalancer in such a way that it prefers the instance with `instanceId` provided in a request cookie. We currently support this if the request is being passed to the LoadBalancer through either `ClientRequestContext` or `ServerHttpRequestContext`, which are used by the SC LoadBalancer exchange filter functions and filters. - -For that, you need to use the `RequestBasedStickySessionServiceInstanceListSupplier`. You can configure it either by setting the value of `spring.cloud.loadbalancer.configurations` to `request-based-sticky-session` or by providing your own `ServiceInstanceListSupplier` bean -- for example: - -[[health-check-based-custom-loadbalancer-configuration]] -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder() - .withDiscoveryClient() - .withRequestBasedStickySession() - .build(context); - } - } ----- - -For that functionality, it is useful to have the selected service instance (which can be different from the one in the original request cookie if that one is not available) to be updated before sending the request forward. To do that, set the value of `spring.cloud.loadbalancer.sticky-session.add-service-instance-cookie` to `true`. - -By default, the name of the cookie is `sc-lb-instance-id`. You can modify it by changing the value of the `spring.cloud.loadbalancer.instance-id-cookie-name` property. - -NOTE: This feature is currently supported for WebClient-backed load-balancing. - -[[spring-cloud-loadbalancer-hints]] -== Spring Cloud LoadBalancer Hints - -Spring Cloud LoadBalancer lets you set `String` hints that are passed to the LoadBalancer within the `Request` object and that can later be used in `ReactiveLoadBalancer` implementations that can handle them. - -You can set a default hint for all services by setting the value of the `spring.cloud.loadbalancer.hint.default` property. You can also set a specific value -for any given service by setting the value of the `spring.cloud.loadbalancer.hint.[SERVICE_ID]` property, substituting `[SERVICE_ID]` with the correct ID of your service. If the hint is not set by the user, `default` is used. - -[[hints-based-loadbalancing]] -== Hint-Based Load-Balancing - -We also provide a `HintBasedServiceInstanceListSupplier`, which is a `ServiceInstanceListSupplier` implementation for hint-based instance selection. - -`HintBasedServiceInstanceListSupplier` checks for a hint request header (the default header-name is `X-SC-LB-Hint`, but you can modify it by changing the value of the `spring.cloud.loadbalancer.hint-header-name` property) and, if it finds a hint request header, uses the hint value passed in the header to filter service instances. - -If no hint header has been added, `HintBasedServiceInstanceListSupplier` uses xref:spring-cloud-commons/loadbalancer.adoc#spring-cloud-loadbalancer-hints[hint values from properties] to filter service instances. - -If no hint is set, either by the header or by properties, all service instances provided by the delegate are returned. - -While filtering, `HintBasedServiceInstanceListSupplier` looks for service instances that have a matching value set under the `hint` key in their `metadataMap`. If no matching instances are found, all instances provided by the delegate are returned. - -You can use the following sample configuration to set it up: - -[[hints-based-custom-loadbalancer-configuration]] -[source,java,indent=0] ----- -public class CustomLoadBalancerConfiguration { - - @Bean - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder() - .withDiscoveryClient() - .withCaching() - .withHints() - .build(context); - } -} ----- - -[[transform-the-load-balanced-http-request]] -== Transform the load-balanced HTTP request - -You can use the selected `ServiceInstance` to transform the load-balanced HTTP Request. - -For `RestTemplate`, you need to implement and define `LoadBalancerRequestTransformer` as follows: - -[source,java,indent=0] ----- - @Bean - public LoadBalancerRequestTransformer transformer() { - return new LoadBalancerRequestTransformer() { - @Override - public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) { - return new HttpRequestWrapper(request) { - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.putAll(super.getHeaders()); - headers.add("X-InstanceId", instance.getInstanceId()); - return headers; - } - }; - } - }; - } ----- - -For `WebClient`, you need to implement and define `LoadBalancerClientRequestTransformer` as follows: - -[source,java,indent=0] ----- - @Bean - public LoadBalancerClientRequestTransformer transformer() { - return new LoadBalancerClientRequestTransformer() { - @Override - public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { - return ClientRequest.from(request) - .header("X-InstanceId", instance.getInstanceId()) - .build(); - } - }; - } ----- - -If multiple transformers are defined, they are applied in the order in which Beans are defined. -Alternatively, you can use `LoadBalancerRequestTransformer.DEFAULT_ORDER` or `LoadBalancerClientRequestTransformer.DEFAULT_ORDER` to specify the order. - -[[spring-cloud-loadbalancer-starter]] -== Spring Cloud LoadBalancer Starter - -We also provide a starter that allows you to easily add Spring Cloud LoadBalancer in a Spring Boot app. -In order to use it, just add `org.springframework.cloud:spring-cloud-starter-loadbalancer` to your Spring Cloud dependencies in your build file. - -NOTE: Spring Cloud LoadBalancer starter includes -https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html[Spring Boot Caching] -and https://github.com/stoyanr/Evictor[Evictor]. - -[[custom-loadbalancer-configuration]] -== Passing Your Own Spring Cloud LoadBalancer Configuration - -You can also use the `@LoadBalancerClient` annotation to pass your own load-balancer client configuration, passing the name of the load-balancer client and the configuration class, as follows: - -[source,java,indent=0] ----- -@Configuration -@LoadBalancerClient(value = "stores", configuration = CustomLoadBalancerConfiguration.class) -public class MyConfiguration { - - @Bean - @LoadBalanced - public WebClient.Builder loadBalancedWebClientBuilder() { - return WebClient.builder(); - } -} ----- - -TIP: In order to make working on your own LoadBalancer configuration easier, we have added a `builder()` method to the `ServiceInstanceListSupplier` class. - -TIP: You can also use our alternative predefined configurations in place of the default ones by setting the value of `spring.cloud.loadbalancer.configurations` property to `zone-preference` to use `ZonePreferenceServiceInstanceListSupplier` with caching or to `health-check` to use `HealthCheckServiceInstanceListSupplier` with caching. - - -You can use this feature to instantiate different implementations of `ServiceInstanceListSupplier` or `ReactorLoadBalancer`, either written by you, or provided by us as alternatives (for example `ZonePreferenceServiceInstanceListSupplier`) to override the default setup. - -You can see an example of a custom configuration xref:spring-cloud-commons/loadbalancer.adoc#zoned-based-custom-loadbalancer-configuration[here]. - -NOTE: The annotation `value` arguments (`stores` in the example above) specifies the service id of the service that we should send the requests to with the given custom configuration. - -You can also pass multiple configurations (for more than one load-balancer client) through the `@LoadBalancerClients` annotation, as the following example shows: - -[source,java,indent=0] ----- -@Configuration -@LoadBalancerClients({@LoadBalancerClient(value = "stores", configuration = StoresLoadBalancerClientConfiguration.class), @LoadBalancerClient(value = "customers", configuration = CustomersLoadBalancerClientConfiguration.class)}) -public class MyConfiguration { - - @Bean - @LoadBalanced - public WebClient.Builder loadBalancedWebClientBuilder() { - return WebClient.builder(); - } -} ----- - -NOTE: The classes you pass as `@LoadBalancerClient` or `@LoadBalancerClients` configuration arguments should either not be annotated with `@Configuration` or be outside component scan scope. - -NOTE: When you create your own configuration, if you use `CachingServiceInstanceListSupplier` or `HealthCheckServiceInstanceListSupplier`, makes sure to use one of them, not both, and make sure to place it in the hierarchy directly after the supplier that retrieves the instances over the network, for example, `DiscoveryClientServiceInstanceListSupplier`, before any other filtering suppliers. - - -[[loadbalancer-lifecycle]] -== Spring Cloud LoadBalancer Lifecycle - -One type of bean that it may be useful to register using xref:spring-cloud-commons/loadbalancer.adoc#custom-loadbalancer-configuration[Custom LoadBalancer configuration] is `LoadBalancerLifecycle`. - -The `LoadBalancerLifecycle` beans provide callback methods, named `onStart(Request request)`, `onStartRequest(Request request, Response lbResponse)` and `onComplete(CompletionContext completionContext)`, that you should implement to specify what actions should take place before and after load-balancing. - -`onStart(Request request)` takes a `Request` object as a parameter. It contains data that is used to select an appropriate instance, including the downstream client request and xref:spring-cloud-commons/loadbalancer.adoc#spring-cloud-loadbalancer-hints[hint]. `onStartRequest` also takes the `Request` object and, additionally, the `Response` object as parameters. On the other hand, a `CompletionContext` object is provided to the `onComplete(CompletionContext completionContext)` method. It contains the LoadBalancer `Response`, including the selected service instance, the `Status` of the request executed against that service instance and (if available) the response returned to the downstream client, and (if an exception has occurred) the corresponding `Throwable`. - -The `supports(Class requestContextClass, Class responseClass, -Class serverTypeClass)` method can be used to determine whether the processor in question handles objects of provided types. If not overridden by the user, it returns `true`. - -NOTE: In the preceding method calls, `RC` means `RequestContext` type, `RES` means client response type, and `T` means returned server type. - -[[loadbalancer-micrometer-stats-lifecycle]] -== Spring Cloud LoadBalancer Statistics - -We provide a `LoadBalancerLifecycle` bean called `MicrometerStatsLoadBalancerLifecycle`, which uses Micrometer to provide statistics for load-balanced calls. - -In order to get this bean added to your application context, -set the value of the `spring.cloud.loadbalancer.stats.micrometer.enabled` to `true` and have a `MeterRegistry` available (for example, by adding https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html[Spring Boot Actuator] to your project). - -`MicrometerStatsLoadBalancerLifecycle` registers the following meters in `MeterRegistry`: - -* `loadbalancer.requests.active`: A gauge that allows you to monitor the number of currently active requests for any service instance (service instance data available via tags); -* `loadbalancer.requests.success`: A timer that measures the time of execution of any load-balanced requests that have ended in passing a response on to the underlying client; -* `loadbalancer.requests.failed`: A timer that measures the time of execution of any load-balanced requests that have ended with an exception; -* `loadbalancer.requests.discard`: A counter that measures the number of discarded load-balanced requests, i.e. requests where a service instance to run the request on has not been retrieved by the LoadBalancer. - -Additional information regarding the service instances, request data, and response data is added to metrics via tags whenever available. - -NOTE: For some implementations, such as `BlockingLoadBalancerClient`, request and response data might not be available, as we establish generic types from arguments and might not be able to determine the types and read the data. - -NOTE: The meters are registered in the registry when at least one record is added for a given meter. - -TIP: You can further configure the behavior of those metrics (for example, add https://micrometer.io/docs/concepts#_histograms_and_percentiles[publishing percentiles and histograms]) by https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-metrics-per-meter-properties[adding `MeterFilters`]. - -[[configuring-individual-loadbalancerclients]] -== Configuring Individual LoadBalancerClients - -Individual Loadbalancer clients may be configured individually with a different prefix `spring.cloud.loadbalancer.clients..*` where `clientId` is the name of the loadbalancer. Default configuration values may be set in the `spring.cloud.loadbalancer.*` namespace and will be merged with the client specific values taking precedence - -.application.yml -==== ----- -spring: - cloud: - loadbalancer: - health-check: - initial-delay: 1s - clients: - myclient: - health-check: - interval: 30s ----- -==== - -The above example will result in a merged health-check `@ConfigurationProperties` object with `initial-delay=1s` and `interval=30s`. - -The per-client configuration properties work for most of the properties, apart from the following global ones: - -- `spring.cloud.loadbalancer.enabled` - globally enables or disables load-balancing -- `spring.cloud.loadbalancer.retry.enabled` - globally enables or disables load-balanced retries. If you enable it globally, you can still disable retries for specific clients using the `client`-prefixed properties, but not the other way round -- `spring.cloud.loadbalancer.cache.enabled` - globally enables or disables LoadBalancer caching. If you enable it globally, you can still disable caching for specific clients by creating a xref:spring-cloud-commons/loadbalancer.adoc#custom-loadbalancer-configuration[custom configuration] that does not include the `CachingServiceInstanceListSupplier` in the `ServiceInstanceListSupplier` delegates hierarchy, but not the other way round. -- `spring.cloud.loadbalancer.stats.micrometer.enabled` - globally enables or disables LoadBalancer Micrometer metrics - -NOTE: For the properties where maps where already used, where you can specify a different value per-client without using the `clients` keyword (for example, `hints`, `health-check.path`), we have kept that behaviour in order to keep the library backwards compatible. It will be modified in the next major release. - -NOTE: Starting with `4.1.0`, we have introduced the `callGetWithRequestOnDelegates` flag in `LoadBalancerProperties`. If this flag is set to `true`, `ServiceInstanceListSupplier#get(Request request)` method will be implemented to call `delegate.get(request)` in classes assignable from `DelegatingServiceInstanceListSupplier` that don't already implement that method, with the exclusion of `CachingServiceInstanceListSupplier` and `HealthCheckServiceInstanceListSupplier`, which should be placed in the instance supplier hierarchy directly after the supplier performing instance retrieval over the network, before any request-based filtering is done. It is set to `true` by default. - -[[-aot-and-native-image-support]] -== AOT and Native Image Support - -Since `4.0.0`, Spring Cloud LoadBalancer supports Spring AOT transformations and native images. However, to use this feature, you need to explicitly define your `LoadBalancerClient` service IDs. You can do so by using the `value` or `name` attributes of the `@LoadBalancerClient` annotation or as values of the `spring.cloud.loadbalancer.eager-load.clients` property. - diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/security.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/security.adoc deleted file mode 100644 index 9dbbe85a..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-commons/security.adoc +++ /dev/null @@ -1,89 +0,0 @@ -[[spring-cloud-security]] -= Security - -[[spring-cloud-security-single-sign-on]] -== Single Sign On - -NOTE: All of the OAuth2 SSO and resource server features moved to Spring Boot -in version 1.3. You can find documentation in the -https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/[Spring Boot user guide]. - -[[spring-cloud-security-client-token-relay]] -=== Client Token Relay - -If your app is a user facing OAuth2 client (i.e. has declared -`@EnableOAuth2Sso` or `@EnableOAuth2Client`) then it has an -`OAuth2ClientContext` in request scope from Spring Boot. You can -create your own `OAuth2RestTemplate` from this context and an -autowired `OAuth2ProtectedResourceDetails`, and then the context will -always forward the access token downstream, also refreshing the access -token automatically if it expires. (These are features of Spring -Security and Spring Boot.) - -[[spring-cloud-security-resource-server-token-relay]] -=== Resource Server Token Relay - -If your app has `@EnableResourceServer` you might want to relay the -incoming token downstream to other services. If you use a -`RestTemplate` to contact the downstream services then this is just a -matter of how to create the template with the right context. - -If your service uses `UserInfoTokenServices` to authenticate incoming -tokens (i.e. it is using the `security.oauth2.user-info-uri` -configuration), then you can simply create an `OAuth2RestTemplate` -using an autowired `OAuth2ClientContext` (it will be populated by the -authentication process before it hits the backend code). Equivalently -(with Spring Boot 1.4), you can inject a -`UserInfoRestTemplateFactory` and grab its `OAuth2RestTemplate` in -your configuration. For example: - -.MyConfiguration.java -[source,java] ----- -@Bean -public OAuth2RestTemplate restTemplate(UserInfoRestTemplateFactory factory) { - return factory.getUserInfoRestTemplate(); -} ----- - -This rest template will then have the same `OAuth2ClientContext` -(request-scoped) that is used by the authentication filter, so you can -use it to send requests with the same access token. - -If your app is not using `UserInfoTokenServices` but is still a client -(i.e. it declares `@EnableOAuth2Client` or `@EnableOAuth2Sso`), then -with Spring Security Cloud any `OAuth2RestOperations` that the user -creates from an `@Autowired` `OAuth2Context` will also forward -tokens. This feature is implemented by default as an MVC handler -interceptor, so it only works in Spring MVC. If you are not using MVC -you can use a custom filter or AOP interceptor wrapping an -`AccessTokenContextRelay` to provide the same feature. - -Here's a basic -example showing the use of an autowired rest template created -elsewhere ("foo.com" is a Resource Server accepting the same tokens as -the surrounding app): - -.MyController.java -[source,java] ----- -@Autowired -private OAuth2RestOperations restTemplate; - -@RequestMapping("/relay") -public String relay() { - ResponseEntity response = - restTemplate.getForEntity("https://foo.com/bar", String.class); - return "Success! (" + response.getBody() + ")"; -} ----- - -If you don't want to forward tokens (and that is a valid -choice, since you might want to act as yourself, rather than the -client that sent you the token), then you only need to create your own -`OAuth2Context` instead of autowiring the default one. - -Feign clients will also pick up an interceptor that uses the -`OAuth2ClientContext` if it is available, so they should also do a -token relay anywhere where a `RestTemplate` would. - diff --git a/docs/pom.xml b/docs/pom.xml deleted file mode 100644 index f2474c5e..00000000 --- a/docs/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - 4.0.0 - org.springframework.cloud - spring-cloud-commons-docs - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - - jar - Spring Cloud Commons Docs - Spring Cloud Commons Docs - - spring-cloud-commons - ${basedir}/.. - spring.cloud.* - deploy - - none - - - 1.0.0 - ${maven.multiModuleProjectDirectory}/spring-cloud-commons/ - .* - ${maven.multiModuleProjectDirectory}/target/ - - - - ${project.groupId} - spring-cloud-starter - - - ${project.groupId} - spring-cloud-starter-loadbalancer - - - - src/main/asciidoc - - - - docs - - - - pl.project13.maven - git-commit-id-plugin - - - org.codehaus.mojo - exec-maven-plugin - - - generate-docs - prepare-package - - java - - - io.micrometer.docs.DocsGeneratorCommand - true - - ${micrometer-docs-generator.inputPath} - ${micrometer-docs-generator.inclusionPattern} - ${micrometer-docs-generator.outputPath} - - - - - - - io.micrometer - micrometer-docs-generator - ${micrometer-docs-generator.version} - jar - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - org.apache.maven.plugins - maven-resources-plugin - - - org.asciidoctor - asciidoctor-maven-plugin - - - org.apache.maven.plugins - maven-antrun-plugin - - - maven-deploy-plugin - - - - - - diff --git a/docs/src/main/asciidoc/ghpages.sh b/docs/src/main/asciidoc/ghpages.sh deleted file mode 100755 index 552a8989..00000000 --- a/docs/src/main/asciidoc/ghpages.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/bin/bash -x - -set -e - -# Set default props like MAVEN_PATH, ROOT_FOLDER etc. -function set_default_props() { - # The script should be run from the root folder - ROOT_FOLDER=`pwd` - echo "Current folder is ${ROOT_FOLDER}" - - if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then - echo "You're not in the root folder of the project!" - exit 1 - fi - - # Prop that will let commit the changes - COMMIT_CHANGES="no" - MAVEN_PATH=${MAVEN_PATH:-} - echo "Path to Maven is [${MAVEN_PATH}]" - REPO_NAME=${PWD##*/} - echo "Repo name is [${REPO_NAME}]" - SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git} - echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}" -} - -# Check if gh-pages exists and docs have been built -function check_if_anything_to_sync() { - git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'` - - if ! (git remote set-branches --add origin gh-pages && git fetch -q); then - echo "No gh-pages, so not syncing" - exit 0 - fi - - if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then - echo "No gh-pages sources in docs/target/generated-docs, so not syncing" - exit 0 - fi -} - -function retrieve_current_branch() { - # Code getting the name of the current branch. For master we want to publish as we did until now - # https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch - # If there is a branch already passed will reuse it - otherwise will try to find it - CURRENT_BRANCH=${BRANCH} - if [[ -z "${CURRENT_BRANCH}" ]] ; then - CURRENT_BRANCH=$(git symbolic-ref -q HEAD) - CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/} - CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD} - fi - echo "Current branch is [${CURRENT_BRANCH}]" - git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" -} - -# Switches to the provided value of the release version. We always prefix it with `v` -function switch_to_tag() { - git checkout v${VERSION} -} - -# Build the docs if switch is on -function build_docs_if_applicable() { - if [[ "${BUILD}" == "yes" ]] ; then - ./mvnw clean install -P docs -pl docs -DskipTests - fi -} - -# Get the name of the `docs.main` property -# Get allowed branches - assumes that a `docs` module is available under `docs` profile -function retrieve_doc_properties() { - MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \ - -Dexec.executable="echo" \ - -Dexec.args='${docs.main}' \ - --non-recursive \ - org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) - echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]" - - - ALLOW_PROPERTY=${ALLOW_PROPERTY:-"docs.allowed.branches"} - ALLOWED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \ - -Dexec.executable="echo" \ - -Dexec.args="\${${ALLOW_PROPERTY}}" \ - org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \ - -P docs \ - -pl docs) - echo "Extracted '${ALLOW_PROPERTY}' from Maven build [${ALLOWED_BRANCHES_VALUE}]" -} - -# Stash any outstanding changes -function stash_changes() { - git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1") - if [ "$dirty" != "0" ]; then git stash; fi -} - -# Switch to gh-pages branch to sync it with current branch -function add_docs_from_target() { - local DESTINATION_REPO_FOLDER - if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then - DESTINATION_REPO_FOLDER=${ROOT_FOLDER} - elif [[ "${CLONE}" == "yes" ]]; then - mkdir -p ${ROOT_FOLDER}/target - local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static - if [[ ! -e "${clonedStatic}/.git" ]]; then - echo "Cloning Spring Cloud Static to target" - git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages - else - echo "Spring Cloud Static already cloned - will pull changes" - cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages - fi - DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME} - mkdir -p ${DESTINATION_REPO_FOLDER} - else - if [[ ! -e "${DESTINATION}/.git" ]]; then - echo "[${DESTINATION}] is not a git repository" - exit 1 - fi - DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME} - mkdir -p ${DESTINATION_REPO_FOLDER} - echo "Destination was provided [${DESTINATION}]" - fi - cd ${DESTINATION_REPO_FOLDER} - git checkout gh-pages - git pull origin gh-pages - - # Add git branches - ################################################################### - if [[ -z "${VERSION}" ]] ; then - copy_docs_for_current_version - else - copy_docs_for_provided_version - fi - commit_changes_if_applicable -} - - -# Copies the docs by using the retrieved properties from Maven build -function copy_docs_for_current_version() { - if [[ "${CURRENT_BRANCH}" == "main" ]] ; then - echo -e "Current branch is main - will copy the current docs only to the root folder" - for f in docs/target/generated-docs/*; do - file=${f#docs/target/generated-docs/*} - if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then - # Not ignored... - cp -rf $f ${ROOT_FOLDER}/ - git add -A ${ROOT_FOLDER}/$file - fi - done - COMMIT_CHANGES="yes" - else - echo -e "Current branch is [${CURRENT_BRANCH}]" - # https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin - if [[ ",${ALLOWED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then - mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH} - echo -e "Branch [${CURRENT_BRANCH}] is allowed! Will copy the current docs to the [${CURRENT_BRANCH}] folder" - for f in docs/target/generated-docs/*; do - file=${f#docs/target/generated-docs/*} - if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then - # Not ignored... - # We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html - if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then - # We don't want to copy the spring-cloud-sleuth.html - # we want it to be converted to index.html - cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html - git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html - else - cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH} - git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file - fi - fi - done - COMMIT_CHANGES="yes" - else - echo -e "Branch [${CURRENT_BRANCH}] is not on the allow list! Check out the Maven [${ALLOW_PROPERTY}] property in - [docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch." - fi - fi -} - -# Copies the docs by using the explicitly provided version -function copy_docs_for_provided_version() { - local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION} - mkdir -p ${FOLDER} - echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder" - for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do - file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*} - copy_docs_for_branch ${file} ${FOLDER} - done - COMMIT_CHANGES="yes" - CURRENT_BRANCH="v${VERSION}" -} - -# Copies the docs from target to the provided destination -# Params: -# $1 - file from target -# $2 - destination to which copy the files -function copy_docs_for_branch() { - local file=$1 - local destination=$2 - if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then - # Not ignored... - # We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html - if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then - # We don't want to copy the spring-cloud-sleuth.html - # we want it to be converted to index.html - cp -rf $f ${destination}/index.html - git add -A ${destination}/index.html - else - cp -rf $f ${destination} - git add -A ${destination}/$file - fi - fi -} - -function commit_changes_if_applicable() { - if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then - COMMIT_SUCCESSFUL="no" - git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes" - - # Uncomment the following push if you want to auto push to - # the gh-pages branch whenever you commit to master locally. - # This is a little extreme. Use with care! - ################################################################### - if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then - git push origin gh-pages - fi - fi -} - -# Switch back to the previous branch and exit block -function checkout_previous_branch() { - # If -version was provided we need to come back to root project - cd ${ROOT_FOLDER} - git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" - if [ "$dirty" != "0" ]; then git stash pop; fi - exit 0 -} - -# Assert if properties have been properly passed -function assert_properties() { -echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]" -if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi -if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi -if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi -} - -# Prints the usage -function print_usage() { -cat </` -- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will - switch to gh-pages of that repo and copy the generated docs to `docs//` - -USAGE: - -You can use the following options: - --v|--version - the script will apply the whole procedure for a particular library version --d|--destination - the root of destination folder where the docs should be copied. You have to use the full path. - E.g. point to spring-cloud-static folder. Can't be used with (-c) --b|--build - will run the standard build process after checking out the branch --c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination. - Obviously can't be used with (-d) - -EOF -} - - -# ========================================== -# ____ ____ _____ _____ _____ _______ -# / ____|/ ____| __ \|_ _| __ \__ __| -# | (___ | | | |__) | | | | |__) | | | -# \___ \| | | _ / | | | ___/ | | -# ____) | |____| | \ \ _| |_| | | | -# |_____/ \_____|_| \_\_____|_| |_| -# -# ========================================== - -while [[ $# > 0 ]] -do -key="$1" -case ${key} in - -v|--version) - VERSION="$2" - shift # past argument - ;; - -d|--destination) - DESTINATION="$2" - shift # past argument - ;; - -b|--build) - BUILD="yes" - ;; - -c|--clone) - CLONE="yes" - ;; - -h|--help) - print_usage - exit 0 - ;; - *) - echo "Invalid option: [$1]" - print_usage - exit 1 - ;; -esac -shift # past argument or value -done - -assert_properties -set_default_props -check_if_anything_to_sync -if [[ -z "${VERSION}" ]] ; then - retrieve_current_branch -else - switch_to_tag -fi -build_docs_if_applicable -retrieve_doc_properties -stash_changes -add_docs_from_target -checkout_previous_branch diff --git a/eclipse/eclipse-code-formatter.xml b/eclipse/eclipse-code-formatter.xml deleted file mode 100644 index f44070cf..00000000 --- a/eclipse/eclipse-code-formatter.xml +++ /dev/null @@ -1,804 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eclipse/org.eclipse.jdt.core.prefs b/eclipse/org.eclipse.jdt.core.prefs deleted file mode 100644 index fd349833..00000000 --- a/eclipse/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,412 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.methodParameters=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=default -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.processAnnotations=disabled -org.eclipse.jdt.core.compiler.source=1.8 -org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_module_statements=16 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 -org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=4 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines -org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=true -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true -org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter diff --git a/eclipse/org.eclipse.jdt.ui.prefs b/eclipse/org.eclipse.jdt.ui.prefs deleted file mode 100644 index 28f88e08..00000000 --- a/eclipse/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,125 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=false -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=false -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=false -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=true -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=false -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=false -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Spring Cloud Cleanup Conventions -cleanup_settings_version=2 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_Spring Cloud Java Conventions -formatter_settings_version=13 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=true -org.eclipse.jdt.ui.ignorelowercasenames=true -org.eclipse.jdt.ui.importorder=java;javax;;org.springframework;\#; -org.eclipse.jdt.ui.javadoc=true -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=9999 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=true -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/pom.xml b/pom.xml index 8098b755..7367983f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,202 +1,70 @@ - - + + + 4.0.0 + org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - pom - Spring Cloud Commons Parent - Spring Cloud Commons Parent - https://projects.spring.io/spring-cloud/ - - org.springframework.cloud - spring-cloud-build - 4.1.0-SNAPSHOT - - + spring-cloud-commons-docs-build + 0.0.1-SNAPSHOT + + Spring Cloud Commons Docs Build + Builds Spring Cloud Commons Docs. + https://spring.io/projects/spring-cloud-commons - https://github.com/spring-cloud/spring-cloud-commons - scm:git:git://github.com/spring-cloud/spring-cloud-commons.git + scm:git:https://github.com/spring-cloud/spring-cloud-commons.git - scm:git:ssh://git@github.com/spring-cloud/spring-cloud-commons.git + scm:git:git@github.com:spring-cloud/spring-cloud-commons.git - HEAD + https://github.com/spring-cloud/spring-cloud-commons + + https://github.com/spring-cloud/spring-cloud-commons/issues + + - commons - 1.0.0 - - 2.5.2 + 0.0.3 + + - org.codehaus.mojo - flatten-maven-plugin - - - org.apache.maven.plugins - maven-eclipse-plugin + io.spring.maven.antora + antora-maven-plugin + ${io.spring.maven.antora-version} + true - false - - - .settings/org.eclipse.jdt.ui.prefs - - ${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.ui.prefs - - - - .settings/org.eclipse.jdt.core.prefs - - ${maven.multiModuleProjectDirectory}/eclipse/org.eclipse.jdt.core.prefs - - - - - - - io.spring.javaformat - spring-javaformat-maven-plugin - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - org.basepom.maven - duplicate-finder-maven-plugin - - - - org.apache.httpcomponents - httpclient - true - - - org.apache.httpcomponents.client5 - httpclient5 - - + + + + + + + 9d489079e5ec46dbb238909fee5c9c29 + WB1FQYI187 + springcloudcommons + - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - + + + spring-snapshot + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestone + https://repo.spring.io/milestone + + - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - - - - org.springframework.cloud - spring-cloud-commons-dependencies - ${project.version} - pom - import - - - org.springframework.cloud - spring-cloud-test-support - ${project.version} - - - - - - spring-cloud-commons-dependencies - spring-cloud-test-support - spring-cloud-context - spring-cloud-context-integration-tests - spring-cloud-context-webflux-integration-tests - spring-cloud-commons - spring-cloud-loadbalancer - spring-cloud-starter - spring-cloud-starter-bootstrap - spring-cloud-starter-loadbalancer - docs - diff --git a/spring-cloud-commons-dependencies/pom.xml b/spring-cloud-commons-dependencies/pom.xml deleted file mode 100644 index c4f526a0..00000000 --- a/spring-cloud-commons-dependencies/pom.xml +++ /dev/null @@ -1,129 +0,0 @@ - - - 4.0.0 - - spring-cloud-dependencies-parent - org.springframework.cloud - 4.1.0-SNAPSHOT - - - spring-cloud-commons-dependencies - 4.1.0-SNAPSHOT - pom - spring-cloud-commons-dependencies - Spring Cloud Commons Dependencies - - 1.1.1 - - - - - org.springframework.security - spring-security-rsa - ${spring-security-rsa.version} - - - org.springframework - spring-core - - - org.springframework.security - spring-security-crypto - - - - - org.springframework.cloud - spring-cloud-commons - ${project.version} - - - org.springframework.cloud - spring-cloud-context - ${project.version} - - - org.springframework.cloud - spring-cloud-loadbalancer - ${project.version} - - - org.springframework.cloud - spring-cloud-starter - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-bootstrap - ${project.version} - - - org.springframework.cloud - spring-cloud-starter-loadbalancer - ${project.version} - - - org.springframework.cloud - spring-cloud-test-support - ${project.version} - - - - - - spring - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - - - diff --git a/spring-cloud-commons/README.md b/spring-cloud-commons/README.md deleted file mode 100644 index e690ca0a..00000000 --- a/spring-cloud-commons/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Spring Cloud Commons - -Common classes used in different Spring Cloud implementations (eg. Spring Cloud Netflix vs. Spring Cloud Consul). \ No newline at end of file diff --git a/spring-cloud-commons/eclipse/eclipse-code-formatter.xml b/spring-cloud-commons/eclipse/eclipse-code-formatter.xml deleted file mode 100644 index 5cbf769b..00000000 --- a/spring-cloud-commons/eclipse/eclipse-code-formatter.xml +++ /dev/null @@ -1,754 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-cloud-commons/eclipse/org.eclipse.jdt.core.prefs b/spring-cloud-commons/eclipse/org.eclipse.jdt.core.prefs deleted file mode 100644 index 63d59166..00000000 --- a/spring-cloud-commons/eclipse/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,389 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=8 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/spring-cloud-commons/eclipse/org.eclipse.jdt.ui.prefs b/spring-cloud-commons/eclipse/org.eclipse.jdt.ui.prefs deleted file mode 100644 index badcb453..00000000 --- a/spring-cloud-commons/eclipse/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,125 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=false -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=false -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=false -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=true -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=false -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=true -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Spring Cloud Cleanup Conventions -cleanup_settings_version=2 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_Spring Cloud Java Conventions -formatter_settings_version=12 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=false -org.eclipse.jdt.ui.ignorelowercasenames=true -org.eclipse.jdt.ui.importorder=java;javax;org;com;\#; -org.eclipse.jdt.ui.javadoc=true -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=9999 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=true -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml deleted file mode 100644 index 6fcfa118..00000000 --- a/spring-cloud-commons/pom.xml +++ /dev/null @@ -1,191 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - spring-cloud-commons - jar - Spring Cloud Commons - Spring Cloud Commons - - - - org.apache.maven.plugins - maven-jar-plugin - - - test-compile - - test-jar - - - - - - **/*.properties - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.apache.maven.plugins - maven-jar-plugin - [3.0.0,) - - test-jar - - - - - - - - - - - - - - - - 1.0.0 - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-webflux - true - - - org.springframework.security - spring-security-crypto - - - org.springframework.security - spring-security-rsa - true - - - org.springframework.integration - spring-integration-jmx - true - - - org.springframework.boot - spring-boot-starter-hateoas - true - - - - org.springframework.boot - spring-boot-starter-aop - true - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.retry - spring-retry - true - - - org.springframework - spring-core - - - javax.annotation - javax.annotation-api - - - - - com.jayway.jsonpath - json-path - true - - - org.apache.httpcomponents.client5 - httpclient5 - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.junit.platform - junit-platform-launcher - test - - - io.projectreactor - reactor-test - test - - - io.micrometer - micrometer-observation-test - test - - - diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java deleted file mode 100644 index ad30201c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/CommonsClientAutoConfiguration.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -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.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.FeaturesEndpoint; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicator; -import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties; -import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthContributor; -import org.springframework.cloud.client.discovery.health.DiscoveryHealthIndicator; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Cloud Commons Client. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Tim Ysewyn - * @author Omer Naci Soydemir - */ -@Configuration(proxyBeanMethods = false) -public class CommonsClientAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(HealthIndicator.class) - @EnableConfigurationProperties(DiscoveryClientHealthIndicatorProperties.class) - @ConditionalOnBean(DiscoveryClient.class) - @ConditionalOnDiscoveryEnabled - @ConditionalOnBlockingDiscoveryEnabled - protected static class DiscoveryLoadBalancerConfiguration { - - @Bean - @ConditionalOnDiscoveryHealthIndicatorEnabled - public DiscoveryClientHealthIndicator discoveryClientHealthIndicator( - ObjectProvider discoveryClient, DiscoveryClientHealthIndicatorProperties properties) { - return new DiscoveryClientHealthIndicator(discoveryClient, properties); - } - - @Bean - @ConditionalOnProperty(value = "spring.cloud.discovery.client.composite-indicator.enabled", - matchIfMissing = true) - @ConditionalOnBean({ DiscoveryHealthIndicator.class }) - public DiscoveryCompositeHealthContributor discoveryCompositeHealthContributor( - List indicators) { - return new DiscoveryCompositeHealthContributor(indicators); - } - - @Bean - public HasFeatures springCloudCommonsFeatures() { - return HasFeatures.abstractFeatures(DiscoveryClient.class, LoadBalancerClient.class); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(Endpoint.class) - @ConditionalOnProperty(value = "spring.cloud.features.enabled", matchIfMissing = true) - protected static class ActuatorConfiguration { - - @Autowired(required = false) - private List hasFeatures = new ArrayList<>(); - - @Bean - @ConditionalOnAvailableEndpoint - public FeaturesEndpoint featuresEndpoint() { - return new FeaturesEndpoint(this.hasFeatures); - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnBlockingDiscoveryEnabled.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnBlockingDiscoveryEnabled.java deleted file mode 100644 index e6a495a0..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnBlockingDiscoveryEnabled.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2019-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -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.boot.autoconfigure.condition.ConditionalOnProperty; - -/** - * Provides a more succinct conditional - * spring.cloud.discovery.blocking.enabled. - * - * @author Tim Ysewyn - * @since 2.2.0 - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@ConditionalOnProperty(value = "spring.cloud.discovery.blocking.enabled", matchIfMissing = true) -public @interface ConditionalOnBlockingDiscoveryEnabled { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryEnabled.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryEnabled.java deleted file mode 100644 index 3d2beb71..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryEnabled.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2019-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -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.boot.autoconfigure.condition.ConditionalOnProperty; - -/** - * Provides a more succinct conditional spring.cloud.discovery.enabled. - * - * @since 2.0 - * @author Olga Maciaszek-Sharma - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@ConditionalOnProperty(value = "spring.cloud.discovery.enabled", matchIfMissing = true) -public @interface ConditionalOnDiscoveryEnabled { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryHealthIndicatorEnabled.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryHealthIndicatorEnabled.java deleted file mode 100644 index 918f1d6a..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnDiscoveryHealthIndicatorEnabled.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2019-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -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.boot.autoconfigure.condition.ConditionalOnProperty; - -/** - * Provides a more succinct conditional - * spring.cloud.discovery.client.health-indicator.enabled. - * - * @since 2.2.0 - * @author Tim Ysewyn - */ -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@ConditionalOnProperty(value = "spring.cloud.discovery.client.health-indicator.enabled", matchIfMissing = true) -public @interface ConditionalOnDiscoveryHealthIndicatorEnabled { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnReactiveDiscoveryEnabled.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnReactiveDiscoveryEnabled.java deleted file mode 100644 index 540658da..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ConditionalOnReactiveDiscoveryEnabled.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2019-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -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.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; - -/** - * Provides a more succinct conditional - * spring.cloud.discovery.reactive.enabled. Also takes into account whether - * or not `WebClient` is on the classpath. - * - * @author Tim Ysewyn - * @since 2.2.0 - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient") -@ConditionalOnProperty(value = "spring.cloud.discovery.reactive.enabled", matchIfMissing = true) -public @interface ConditionalOnReactiveDiscoveryEnabled { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/DefaultServiceInstance.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/DefaultServiceInstance.java deleted file mode 100644 index 9caefc53..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/DefaultServiceInstance.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import java.net.URI; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Default implementation of {@link ServiceInstance}. - * - * @author Spencer Gibb - * @author Tim Ysewyn - * @author Charu Covindane - * @author Neil Powell - */ -public class DefaultServiceInstance implements ServiceInstance { - - private String instanceId; - - private String serviceId; - - private String host; - - private int port; - - private boolean secure; - - private Map metadata = new LinkedHashMap<>(); - - private URI uri; - - /** - * @param instanceId the id of the instance. - * @param serviceId the id of the service. - * @param host the host where the service instance can be found. - * @param port the port on which the service is running. - * @param secure indicates whether or not the connection needs to be secure. - * @param metadata a map containing metadata. - */ - public DefaultServiceInstance(String instanceId, String serviceId, String host, int port, boolean secure, - Map metadata) { - this.instanceId = instanceId; - this.serviceId = serviceId; - this.host = host; - this.port = port; - this.secure = secure; - this.metadata = metadata; - } - - /** - * @param instanceId the id of the instance. - * @param serviceId the id of the service. - * @param host the host where the service instance can be found. - * @param port the port on which the service is running. - * @param secure indicates whether or not the connection needs to be secure. - */ - public DefaultServiceInstance(String instanceId, String serviceId, String host, int port, boolean secure) { - this(instanceId, serviceId, host, port, secure, new LinkedHashMap<>()); - } - - public DefaultServiceInstance() { - } - - /** - * Creates a URI from the given ServiceInstance's host:port. - * @param instance the ServiceInstance. - * @return URI of the form (secure)?https:http + "host:port". Scheme port default used - * if port not set. - */ - public static URI getUri(ServiceInstance instance) { - String scheme = (instance.isSecure()) ? "https" : "http"; - int port = instance.getPort(); - if (port <= 0) { - port = (instance.isSecure()) ? 443 : 80; - } - String uri = String.format("%s://%s:%s", scheme, instance.getHost(), port); - return URI.create(uri); - } - - @Override - public URI getUri() { - return getUri(this); - } - - @Override - public Map getMetadata() { - return metadata; - } - - @Override - public String getInstanceId() { - return instanceId; - } - - @Override - public String getServiceId() { - return serviceId; - } - - @Override - public String getHost() { - return host; - } - - @Override - public int getPort() { - return port; - } - - @Override - public boolean isSecure() { - return secure; - } - - public void setInstanceId(String instanceId) { - this.instanceId = instanceId; - } - - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - public void setHost(String host) { - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setSecure(boolean secure) { - this.secure = secure; - } - - public void setUri(URI uri) { - this.uri = uri; - this.host = this.uri.getHost(); - this.port = this.uri.getPort(); - String scheme = this.uri.getScheme(); - if ("https".equals(scheme)) { - this.secure = true; - } - } - - @Override - public String toString() { - return "DefaultServiceInstance{" + "instanceId='" + instanceId + '\'' + ", serviceId='" + serviceId + '\'' - + ", host='" + host + '\'' + ", port=" + port + ", secure=" + secure + ", metadata=" + metadata + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DefaultServiceInstance that = (DefaultServiceInstance) o; - return port == that.port && secure == that.secure && Objects.equals(instanceId, that.instanceId) - && Objects.equals(serviceId, that.serviceId) && Objects.equals(host, that.host) - && Objects.equals(metadata, that.metadata); - } - - @Override - public int hashCode() { - return Objects.hash(instanceId, serviceId, host, port, secure, metadata); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessor.java deleted file mode 100644 index e44d4364..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessor.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import java.util.LinkedHashMap; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.InetUtils.HostInfo; -import org.springframework.cloud.commons.util.InetUtilsProperties; -import org.springframework.core.Ordered; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; - -/** - * @author Spencer Gibb - */ -public class HostInfoEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { - - // Before BootstrapConfigFileApplicationListener - private int order = Ordered.HIGHEST_PRECEDENCE + 9; - - @Override - public int getOrder() { - return this.order; - } - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment); - LinkedHashMap map = new LinkedHashMap<>(); - map.put("spring.cloud.client.hostname", hostInfo.getHostname()); - map.put("spring.cloud.client.ip-address", hostInfo.getIpAddress()); - MapPropertySource propertySource = new MapPropertySource("springCloudClientHostInfo", map); - environment.getPropertySources().addLast(propertySource); - } - - private HostInfo getFirstNonLoopbackHostInfo(ConfigurableEnvironment environment) { - InetUtilsProperties target = new InetUtilsProperties(); - ConfigurationPropertySources.attach(environment); - Binder.get(environment).bind(InetUtilsProperties.PREFIX, Bindable.ofInstance(target)); - try (InetUtils utils = new InetUtils(target)) { - return utils.findFirstNonLoopbackHostInfo(); - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfiguration.java deleted file mode 100644 index baf71c58..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfiguration.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import java.util.Collection; - -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -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.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties; -import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryCompositeHealthContributor; -import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryHealthIndicator; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for reactive Spring Cloud Commons - * Client. - * - * @author Tim Ysewyn - * @since 2.2.0 - */ -@Configuration(proxyBeanMethods = false) -public class ReactiveCommonsClientAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(DiscoveryClientHealthIndicatorProperties.class) - @ConditionalOnClass(ReactiveHealthIndicator.class) - @ConditionalOnBean(ReactiveDiscoveryClient.class) - @ConditionalOnDiscoveryEnabled - @ConditionalOnReactiveDiscoveryEnabled - protected static class ReactiveDiscoveryLoadBalancerConfiguration { - - @Bean - @ConditionalOnProperty(value = "spring.cloud.discovery.client.composite-indicator.enabled", - matchIfMissing = true) - @ConditionalOnBean({ ReactiveDiscoveryHealthIndicator.class }) - public ReactiveDiscoveryCompositeHealthContributor reactiveDiscoveryClients( - Collection indicators) { - return new ReactiveDiscoveryCompositeHealthContributor(indicators); - } - - @Bean - public HasFeatures reactiveCommonsFeatures() { - return HasFeatures.abstractFeatures(ReactiveDiscoveryClient.class, ReactiveLoadBalancer.class); - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ServiceInstance.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ServiceInstance.java deleted file mode 100644 index 7e457e3c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/ServiceInstance.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import java.net.URI; -import java.util.Map; - -/** - * Represents an instance of a service in a discovery system. - * - * @author Spencer Gibb - * @author Tim Ysewyn - */ -public interface ServiceInstance { - - /** - * @return The unique instance ID as registered. - */ - default String getInstanceId() { - return null; - } - - /** - * @return The service ID as registered. - */ - String getServiceId(); - - /** - * @return The hostname of the registered service instance. - */ - String getHost(); - - /** - * @return The port of the registered service instance. - */ - int getPort(); - - /** - * @return Whether the port of the registered service instance uses HTTPS. - */ - boolean isSecure(); - - /** - * @return The service URI address. - */ - URI getUri(); - - /** - * @return The key / value pair metadata associated with the service instance. - */ - Map getMetadata(); - - /** - * @return The scheme of the service instance. - */ - default String getScheme() { - return null; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/FeaturesEndpoint.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/FeaturesEndpoint.java deleted file mode 100644 index a164a4f2..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/FeaturesEndpoint.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.actuator; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -/** - * @author Spencer Gibb - */ -@Endpoint(id = "features") -public class FeaturesEndpoint implements ApplicationContextAware { - - private final List hasFeaturesList; - - private ApplicationContext context; - - public FeaturesEndpoint(List hasFeaturesList) { - this.hasFeaturesList = hasFeaturesList; - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - - @ReadOperation - public Features features() { - Features features = new Features(); - - for (HasFeatures hasFeatures : this.hasFeaturesList) { - List> abstractFeatures = hasFeatures.getAbstractFeatures(); - if (abstractFeatures != null) { - for (Class clazz : abstractFeatures) { - addAbstractFeature(features, clazz); - } - } - - List namedFeatures = hasFeatures.getNamedFeatures(); - if (namedFeatures != null) { - for (NamedFeature namedFeature : namedFeatures) { - addFeature(features, namedFeature); - } - } - } - - return features; - } - - private void addAbstractFeature(Features features, Class type) { - String featureName = type.getSimpleName(); - try { - Object bean = this.context.getBean(type); - Class beanClass = bean.getClass(); - addFeature(features, new NamedFeature(featureName, beanClass)); - } - catch (NoSuchBeanDefinitionException e) { - features.getDisabled().add(featureName); - } - } - - private void addFeature(Features features, NamedFeature feature) { - Class type = feature.getType(); - features.getEnabled().add(new Feature(feature.getName(), type.getCanonicalName(), - type.getPackage().getImplementationVersion(), type.getPackage().getImplementationVendor())); - } - - static class Features { - - final List enabled = new ArrayList<>(); - - final List disabled = new ArrayList<>(); - - public List getEnabled() { - return this.enabled; - } - - public List getDisabled() { - return this.disabled; - } - - } - - static class Feature { - - final String type; - - final String name; - - final String version; - - final String vendor; - - Feature(String name, String type, String version, String vendor) { - this.type = type; - this.name = name; - this.version = version; - this.vendor = vendor; - } - - public String getType() { - return this.type; - } - - public String getName() { - return this.name; - } - - public String getVersion() { - return this.version; - } - - public String getVendor() { - return this.vendor; - } - - @Override - public String toString() { - return "Feature{" + "type='" + this.type + '\'' + ", name='" + this.name + '\'' + ", version='" - + this.version + '\'' + ", vendor='" + this.vendor + '\'' + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Feature feature = (Feature) o; - - if (!Objects.equals(this.type, feature.type)) { - return false; - } - if (!Objects.equals(this.name, feature.name)) { - return false; - } - if (!Objects.equals(this.version, feature.version)) { - return false; - } - return Objects.equals(this.vendor, feature.vendor); - } - - @Override - public int hashCode() { - int result = this.type != null ? this.type.hashCode() : 0; - result = 31 * result + (this.name != null ? this.name.hashCode() : 0); - result = 31 * result + (this.version != null ? this.version.hashCode() : 0); - result = 31 * result + (this.vendor != null ? this.vendor.hashCode() : 0); - return result; - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/HasFeatures.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/HasFeatures.java deleted file mode 100644 index 8534e91f..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/HasFeatures.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.actuator; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -/** - * @author Spencer Gibb - */ -public class HasFeatures { - - private final List> abstractFeatures = new ArrayList<>(); - - private final List namedFeatures = new ArrayList<>(); - - public HasFeatures(List> abstractFeatures, List namedFeatures) { - this.abstractFeatures.addAll(abstractFeatures); - this.namedFeatures.addAll(namedFeatures); - } - - public static HasFeatures abstractFeatures(Class... abstractFeatures) { - return new HasFeatures(Arrays.asList(abstractFeatures), Collections.emptyList()); - } - - public static HasFeatures namedFeatures(NamedFeature... namedFeatures) { - return new HasFeatures(Collections.emptyList(), Arrays.asList(namedFeatures)); - } - - public static HasFeatures namedFeature(String name, Class type) { - return namedFeatures(new NamedFeature(name, type)); - } - - public static HasFeatures namedFeatures(String name1, Class type1, String name2, Class type2) { - return namedFeatures(new NamedFeature(name1, type1), new NamedFeature(name2, type2)); - } - - public List> getAbstractFeatures() { - return this.abstractFeatures; - } - - public List getNamedFeatures() { - return this.namedFeatures; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/NamedFeature.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/NamedFeature.java deleted file mode 100644 index 951d855e..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/actuator/NamedFeature.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.actuator; - -/** - * @author Spencer Gibb - */ -public class NamedFeature { - - private final String name; - - private final Class type; - - public NamedFeature(String name, Class type) { - this.name = name; - this.type = type; - } - - public String getName() { - return this.name; - } - - public Class getType() { - return this.type; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/AbstractCircuitBreakerFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/AbstractCircuitBreakerFactory.java deleted file mode 100644 index 2e1eb0bf..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/AbstractCircuitBreakerFactory.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Base class for factories which produce circuit breakers. - * - * @author Ryan Baxter - */ -public abstract class AbstractCircuitBreakerFactory> { - - private final ConcurrentHashMap configurations = new ConcurrentHashMap<>(); - - /** - * Adds configurations for circuit breakers. - * @param ids The id of the circuit breaker - * @param consumer A configuration builder consumer, allows consumers to customize the - * builder before the configuration is built - */ - public void configure(Consumer consumer, String... ids) { - for (String id : ids) { - CONFB builder = configBuilder(id); - consumer.accept(builder); - CONF conf = builder.build(); - getConfigurations().put(id, conf); - } - } - - /** - * Gets the configurations for the circuit breakers. - * @return The configurations - */ - protected ConcurrentHashMap getConfigurations() { - return configurations; - } - - /** - * Creates a configuration builder for the given id. - * @param id The id of the circuit breaker - * @return The configuration builder - */ - protected abstract CONFB configBuilder(String id); - - /** - * Sets the default configuration for circuit breakers. - * @param defaultConfiguration A function that returns the default configuration - */ - public abstract void configureDefault(Function defaultConfiguration); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreaker.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreaker.java deleted file mode 100644 index 080841d6..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreaker.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -import java.util.function.Function; -import java.util.function.Supplier; - -/** - * Spring Cloud circuit breaker. - * - * @author Ryan Baxter - */ -public interface CircuitBreaker { - - default T run(Supplier toRun) { - return run(toRun, throwable -> { - throw new NoFallbackAvailableException("No fallback available.", throwable); - }); - } - - T run(Supplier toRun, Function fallback); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreakerFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreakerFactory.java deleted file mode 100644 index 393aac2b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/CircuitBreakerFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -/** - * Creates circuit breakers based on the underlying implementation. - * - * @author Ryan Baxter - * @author Andrii Bohutskyi - */ -public abstract class CircuitBreakerFactory> - extends AbstractCircuitBreakerFactory { - - public abstract CircuitBreaker create(String id); - - public CircuitBreaker create(String id, String groupName) { - return create(id); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ConfigBuilder.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ConfigBuilder.java deleted file mode 100644 index bc41778b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ConfigBuilder.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -/** - * A builder for circuit breaker configurations. - * - * @author Ryan Baxter - */ -public interface ConfigBuilder { - - CONF build(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/Customizer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/Customizer.java deleted file mode 100644 index e46c218d..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/Customizer.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.function.Function; - -/** - * Customizes the parameterized class. - * - * @author Ryan Baxter - * @author Toshiaki Maki - */ -public interface Customizer { - - void customize(TOCUSTOMIZE tocustomize); - - /** - * Create a wrapped customizer that guarantees that the {@link #customize(Object)} - * method of the delegated customizer is called at most once per target. - * @param customizer a customizer to be delegated - * @param keyMapper a mapping function to produce the identifier of the target - * @param the type of the target to customize - * @param the type of the identifier of the target - * @return a wrapped customizer - */ - static Customizer once(Customizer customizer, Function keyMapper) { - final ConcurrentMap customized = new ConcurrentHashMap<>(); - return t -> { - final K key = keyMapper.apply(t); - customized.computeIfAbsent(key, k -> { - customizer.customize(t); - return true; - }); - }; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/NoFallbackAvailableException.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/NoFallbackAvailableException.java deleted file mode 100644 index 53761263..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/NoFallbackAvailableException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -/** - * A runtime exception that tells no fallback is available for the circuit breaker. - * - * @author Toshiaki Maki - */ -public class NoFallbackAvailableException extends RuntimeException { - - public NoFallbackAvailableException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreaker.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreaker.java deleted file mode 100644 index bef51d9a..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreaker.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -import java.util.function.Function; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Spring Cloud reactive circuit breaker API. - * - * @author Ryan Baxter - */ -public interface ReactiveCircuitBreaker { - - default Mono run(Mono toRun) { - return run(toRun, throwable -> { - throw new NoFallbackAvailableException("No fallback available.", throwable); - }); - } - - Mono run(Mono toRun, Function> fallback); - - default Flux run(Flux toRun) { - return run(toRun, throwable -> { - throw new NoFallbackAvailableException("No fallback available.", throwable); - }); - } - - Flux run(Flux toRun, Function> fallback); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreakerFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreakerFactory.java deleted file mode 100644 index bfb58967..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/ReactiveCircuitBreakerFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -/** - * Creates reactive circuit breakers. - * - * @author Ryan Baxter - * @author Andrii Bohutskyi - */ -public abstract class ReactiveCircuitBreakerFactory> - extends AbstractCircuitBreakerFactory { - - public abstract ReactiveCircuitBreaker create(String id); - - public ReactiveCircuitBreaker create(String id, String groupName) { - return create(id); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationContext.java deleted file mode 100644 index 52bc0718..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationContext.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import io.micrometer.observation.Observation; - -/** - * Circuit Breaker {@link Observation.Context}. - * - * @author Marcin Grzejszczak - * @since 4.0.0 - */ -public class CircuitBreakerObservationContext extends Observation.Context { - - private final Type type; - - /** - * Creates a new instance of {@link CircuitBreakerObservationDocumentation}. - * @param type type of wrapped object - */ - public CircuitBreakerObservationContext(Type type) { - this.type = type; - } - - /** - * Gets the wrapped object type. - * @return type of wrapped object - */ - public Type getType() { - return type; - } - - /** - * Describes the type of wrapped object. - */ - public enum Type { - - /** - * Fallback function. - */ - FUNCTION, - - /** - * Operation to run. - */ - SUPPLIER - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationConvention.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationConvention.java deleted file mode 100644 index 6dd7c0c9..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationConvention.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationConvention; - -/** - * {@link ObservationConvention} for {@link CircuitBreakerObservationContext}. - * - * @author Marcin Grzejszczak - * @since 4.0.0 - */ -public interface CircuitBreakerObservationConvention extends ObservationConvention { - - @Override - default boolean supportsContext(Observation.Context context) { - return context instanceof CircuitBreakerObservationContext; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationDocumentation.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationDocumentation.java deleted file mode 100644 index 773e63e5..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/CircuitBreakerObservationDocumentation.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import io.micrometer.common.docs.KeyName; -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationConvention; -import io.micrometer.observation.docs.ObservationDocumentation; - -enum CircuitBreakerObservationDocumentation implements ObservationDocumentation { - - /** - * Observation created when we wrap a Supplier passed to the CircuitBreaker. - */ - CIRCUIT_BREAKER_SUPPLIER_OBSERVATION { - @Override - public Class> getDefaultConvention() { - return DefaultCircuitBreakerObservationConvention.class; - } - - @Override - public KeyName[] getLowCardinalityKeyNames() { - return LowCardinalityTags.values(); - } - - @Override - public String getPrefix() { - return "spring.cloud.circuitbreaker"; - } - - }, - - /** - * Observation created when we wrap a Function passed to the CircuitBreaker as - * fallback. - */ - CIRCUIT_BREAKER_FUNCTION_OBSERVATION { - @Override - public Class> getDefaultConvention() { - return DefaultCircuitBreakerObservationConvention.class; - } - - @Override - public KeyName[] getLowCardinalityKeyNames() { - return LowCardinalityTags.values(); - } - - @Override - public String getPrefix() { - return "spring.cloud.circuitbreaker"; - } - - }; - - public enum LowCardinalityTags implements KeyName { - - /** - * Defines the type of wrapped lambda. - */ - OBJECT_TYPE { - @Override - public String asString() { - return "spring.cloud.circuitbreaker.type"; - } - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/DefaultCircuitBreakerObservationConvention.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/DefaultCircuitBreakerObservationConvention.java deleted file mode 100644 index 99cae778..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/DefaultCircuitBreakerObservationConvention.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import java.util.Locale; - -import io.micrometer.common.KeyValues; - -/** - * Default implementation of {@link CircuitBreakerObservationContext}. - * - * @author Marcin Grzejszczak - * @since 4.0.0 - */ -public class DefaultCircuitBreakerObservationConvention implements CircuitBreakerObservationConvention { - - /** - * Don't know why this needs to be public. - */ - public static final DefaultCircuitBreakerObservationConvention INSTANCE = new DefaultCircuitBreakerObservationConvention(); - - @Override - public KeyValues getLowCardinalityKeyValues(CircuitBreakerObservationContext context) { - return KeyValues.of(CircuitBreakerObservationDocumentation.LowCardinalityTags.OBJECT_TYPE - .withValue(context.getType().name().toLowerCase(Locale.ROOT))); - } - - @Override - public String getName() { - return "spring.cloud.circuitbreaker"; - } - - @Override - public String getContextualName(CircuitBreakerObservationContext context) { - if (context.getType() == CircuitBreakerObservationContext.Type.SUPPLIER) { - return "circuit-breaker"; - } - return "circuit-breaker fallback"; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreaker.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreaker.java deleted file mode 100644 index b30ffe5b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreaker.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import java.util.function.Function; -import java.util.function.Supplier; - -import io.micrometer.observation.ObservationRegistry; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; - -/** - * Observed Circuit Breaker. - * - * @author Marcin Grzejszczak - * @since 4.0.0 - */ -public class ObservedCircuitBreaker implements CircuitBreaker { - - private final CircuitBreaker delegate; - - private final ObservationRegistry observationRegistry; - - private CircuitBreakerObservationConvention customConvention; - - public ObservedCircuitBreaker(CircuitBreaker delegate, ObservationRegistry observationRegistry) { - this.delegate = delegate; - this.observationRegistry = observationRegistry; - } - - @Override - public T run(Supplier toRun, Function fallback) { - return this.delegate.run( - new ObservedSupplier<>(this.customConvention, - new CircuitBreakerObservationContext(CircuitBreakerObservationContext.Type.SUPPLIER), - "circuit-breaker", this.observationRegistry, toRun), - new ObservedFunction<>(this.customConvention, - new CircuitBreakerObservationContext(CircuitBreakerObservationContext.Type.FUNCTION), - "circuit-breaker fallback", this.observationRegistry, fallback)); - } - - @Override - public T run(Supplier toRun) { - return this.delegate.run(new ObservedSupplier<>(this.customConvention, - new CircuitBreakerObservationContext(CircuitBreakerObservationContext.Type.SUPPLIER), "circuit-breaker", - this.observationRegistry, toRun)); - } - - public void setCustomConvention(CircuitBreakerObservationConvention customConvention) { - this.customConvention = customConvention; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedFunction.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedFunction.java deleted file mode 100644 index c6fe6a72..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedFunction.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import java.util.function.Function; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; - -/** - * Observed {@link Function}. - * - * @param type returned by the fallback - * @since 4.0.0 - */ -class ObservedFunction implements Function { - - private final Function delegate; - - private final Observation observation; - - ObservedFunction(CircuitBreakerObservationConvention customConvention, CircuitBreakerObservationContext context, - String conextualName, ObservationRegistry observationRegistry, Function toRun) { - this.delegate = toRun; - this.observation = CircuitBreakerObservationDocumentation.CIRCUIT_BREAKER_SUPPLIER_OBSERVATION - .observation(customConvention, DefaultCircuitBreakerObservationConvention.INSTANCE, () -> context, - observationRegistry) - .parentObservation(observationRegistry.getCurrentObservation()); - this.observation.contextualName(conextualName); - } - - @Override - public T apply(Throwable throwable) { - return this.observation.observe(() -> this.delegate.apply(throwable)); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedSupplier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedSupplier.java deleted file mode 100644 index 996b28a3..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedSupplier.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import java.util.function.Supplier; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; - -/** - * Observed {@link Supplier}. - * - * @param type returned by the supplier - * @since 4.0.0 - */ -class ObservedSupplier implements Supplier { - - private final Supplier delegate; - - private final Observation observation; - - ObservedSupplier(CircuitBreakerObservationConvention customConvention, CircuitBreakerObservationContext context, - String contextualName, ObservationRegistry observationRegistry, Supplier toRun) { - this.delegate = toRun; - this.observation = CircuitBreakerObservationDocumentation.CIRCUIT_BREAKER_SUPPLIER_OBSERVATION - .observation(customConvention, DefaultCircuitBreakerObservationConvention.INSTANCE, () -> context, - observationRegistry) - .parentObservation(observationRegistry.getCurrentObservation()); - this.observation.contextualName(contextualName); - } - - @Override - public T get() { - return this.observation.observe(this.delegate); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java deleted file mode 100644 index b770467d..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import java.util.List; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; - -/** - * Represents read operations commonly available to discovery services such as Netflix - * Eureka or consul.io. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Chris Bono - */ -public interface DiscoveryClient extends Ordered { - - /** - * Default order of the discovery client. - */ - int DEFAULT_ORDER = 0; - - /** - * A human-readable description of the implementation, used in HealthIndicator. - * @return The description. - */ - String description(); - - /** - * Gets all ServiceInstances associated with a particular serviceId. - * @param serviceId The serviceId to query. - * @return A List of ServiceInstance. - */ - List getInstances(String serviceId); - - /** - * @return All known service IDs. - */ - List getServices(); - - /** - * Can be used to verify the client is valid and able to make calls. - *

- * A successful invocation with no exception thrown implies the client is able to make - * calls. - *

- * The default implementation simply calls {@link #getServices()} - client - * implementations can override with a lighter weight operation if they choose to. - */ - default void probe() { - getServices(); - } - - /** - * Default implementation for getting order of discovery clients. - * @return order - */ - @Override - default int getOrder() { - return DEFAULT_ORDER; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java deleted file mode 100644 index 1198e174..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClient.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -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.context.annotation.Import; - -/** - * Annotation to enable a DiscoveryClient implementation. - * @author Spencer Gibb - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Import(EnableDiscoveryClientImportSelector.class) -public @interface EnableDiscoveryClient { - - /** - * If true, the ServiceRegistry will automatically register the local server. - * @return - {@code true} if you want to automatically register. - */ - boolean autoRegister() default true; - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java deleted file mode 100644 index a57ff0a8..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelector.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; - -import org.springframework.cloud.commons.util.SpringFactoryImportSelector; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.annotation.Order; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.type.AnnotationMetadata; - -/** - * @author Spencer Gibb - */ -@Order(Ordered.LOWEST_PRECEDENCE - 100) -public class EnableDiscoveryClientImportSelector extends SpringFactoryImportSelector { - - @Override - public String[] selectImports(AnnotationMetadata metadata) { - String[] imports = super.selectImports(metadata); - - AnnotationAttributes attributes = AnnotationAttributes - .fromMap(metadata.getAnnotationAttributes(getAnnotationClass().getName(), true)); - - boolean autoRegister = attributes.getBoolean("autoRegister"); - - if (autoRegister) { - List importsList = new ArrayList<>(Arrays.asList(imports)); - importsList.add("org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration"); - imports = importsList.toArray(new String[0]); - } - else { - Environment env = getEnvironment(); - if (env instanceof ConfigurableEnvironment configEnv) { - LinkedHashMap map = new LinkedHashMap<>(); - map.put("spring.cloud.service-registry.auto-registration.enabled", false); - MapPropertySource propertySource = new MapPropertySource("springCloudDiscoveryClient", map); - configEnv.getPropertySources().addLast(propertySource); - } - - } - - return imports; - } - - @Override - protected boolean isEnabled() { - return getEnvironment().getProperty("spring.cloud.discovery.enabled", Boolean.class, Boolean.TRUE); - } - - @Override - protected boolean hasDefaultFactory() { - return true; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ManagementServerPortUtils.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ManagementServerPortUtils.java deleted file mode 100644 index eb2a61b3..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ManagementServerPortUtils.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.web.context.WebApplicationContext; - -/** - * Utility class for management server ports. - * - * @author Spencer Gibb - */ -public final class ManagementServerPortUtils { - - // for testing - static final boolean hasActuator; - - static { - boolean hasEndpointClass = hasClass("org.springframework.boot.actuate.endpoint.annotation.Endpoint"); - boolean hasManagementServerPropertiesClass = hasClass( - "org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties"); - hasActuator = hasEndpointClass && hasManagementServerPropertiesClass; - } - - private ManagementServerPortUtils() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - private static boolean hasClass(String className) { - boolean hasClass; - try { - Class.forName(className); - hasClass = true; - } - catch (ClassNotFoundException e) { - hasClass = false; - } - return hasClass; - } - - public static ManagementServerPort get(BeanFactory beanFactory) { - return ManagementServerPort.get(beanFactory); - } - - public static boolean isDifferent(BeanFactory beanFactory) { - return get(beanFactory) == ManagementServerPort.DIFFERENT; - } - - public static boolean isDisabled(BeanFactory beanFactory) { - return get(beanFactory) == ManagementServerPort.DISABLE; - } - - public static boolean isSame(BeanFactory beanFactory) { - return get(beanFactory) == ManagementServerPort.SAME; - } - - public static Integer getPort(BeanFactory beanFactory) { - if (!hasActuator) { - return null; - } - try { - ManagementServerProperties properties = beanFactory.getBean(ManagementServerProperties.class); - return properties.getPort(); - } - catch (NoSuchBeanDefinitionException ex) { - return null; - } - } - - // TODO: copied from EndpointWebMvcAutoConfiguration.ManagementServerPort - - /** - * Enumeration for management server ports. - */ - public enum ManagementServerPort { - - /** - * Disabled management server port. - */ - DISABLE, - - /** - * Add it. TODO: Add it - */ - SAME, - - /** - * Add it. TODO: Add it - */ - DIFFERENT; - - public static ManagementServerPort get(BeanFactory beanFactory) { - if (!hasActuator) { - return SAME; - } - - ServerProperties serverProperties; - try { - serverProperties = beanFactory.getBean(ServerProperties.class); - } - catch (NoSuchBeanDefinitionException ex) { - serverProperties = new ServerProperties(); - } - - ManagementServerProperties managementServerProperties; - try { - managementServerProperties = beanFactory.getBean(ManagementServerProperties.class); - } - catch (NoSuchBeanDefinitionException ex) { - managementServerProperties = new ManagementServerProperties(); - } - - Integer port = managementServerProperties.getPort(); - if (port != null && port < 0) { - return DISABLE; - } - if (!(beanFactory instanceof WebApplicationContext)) { - // Current context is not a webapp - return DIFFERENT; - } - return ((port == null) || (serverProperties.getPort() == null && port.equals(8080)) - || (port != 0 && port.equals(serverProperties.getPort())) ? SAME : DIFFERENT); - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ReactiveDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ReactiveDiscoveryClient.java deleted file mode 100644 index 5ef5b333..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/ReactiveDiscoveryClient.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.Ordered; - -/** - * Represents read operations commonly available to discovery services such as Netflix - * Eureka or consul.io. - * - * @author Tim Ysewyn - * @author Olga Maciaszek-Sharma - */ -public interface ReactiveDiscoveryClient extends Ordered { - - Log LOG = LogFactory.getLog(ReactiveDiscoveryClient.class); - - /** - * Default order of the discovery client. - */ - int DEFAULT_ORDER = 0; - - /** - * A human-readable description of the implementation, used in HealthIndicator. - * @return The description. - */ - String description(); - - /** - * Gets all ServiceInstances associated with a particular serviceId. - * @param serviceId The serviceId to query. - * @return A List of ServiceInstance. - */ - Flux getInstances(String serviceId); - - /** - * @return All known service IDs. - */ - Flux getServices(); - - /** - * Can be used to verify the client is still valid and able to make calls. - *

- * A successful invocation with no exception thrown implies the client is able to make - * calls. - *

- * The default implementation simply calls {@link #getServices()} - client - * implementations can override with a lighter weight operation if they choose to. - * @deprecated in favour of {@link ReactiveDiscoveryClient#reactiveProbe()}. This - * method should not be used as is, as it contains a bug - the method called within - * returns a {@link Flux}, which is not accessible for subscription or blocking from - * within. We are leaving it with a deprecation in order not to bring downstream - * implementations. - */ - @Deprecated - default void probe() { - if (LOG.isWarnEnabled()) { - LOG.warn("ReactiveDiscoveryClient#probe has been called. If you're calling this method directly, " - + "use ReactiveDiscoveryClient#reactiveProbe instead."); - } - getServices(); - } - - /** - * Can be used to verify the client is still valid and able to make calls. - *

- * A successful invocation with no exception thrown implies the client is able to make - * calls. - *

- * The default implementation simply calls {@link #getServices()} and wraps it with a - * {@link Mono} - client implementations can override with a lighter weight operation - * if they choose to. - */ - default Mono reactiveProbe() { - return getServices().then(); - } - - /** - * Default implementation for getting order of discovery clients. - * @return order - */ - @Override - default int getOrder() { - return DEFAULT_ORDER; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java deleted file mode 100644 index e44be5c0..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; - -/** - * A {@link DiscoveryClient} that is composed of other discovery clients and delegates - * calls to each of them in order. - * - * @author Biju Kunjummen - * @author Olga Maciaszek-Sharma - * @author Sean Ruffatti - */ -public class CompositeDiscoveryClient implements DiscoveryClient { - - private final List discoveryClients; - - public CompositeDiscoveryClient(List discoveryClients) { - AnnotationAwareOrderComparator.sort(discoveryClients); - this.discoveryClients = discoveryClients; - } - - @Override - public String description() { - return "Composite Discovery Client"; - } - - @Override - public List getInstances(String serviceId) { - if (this.discoveryClients != null) { - for (DiscoveryClient discoveryClient : this.discoveryClients) { - List instances = discoveryClient.getInstances(serviceId); - if (instances != null && !instances.isEmpty()) { - return instances; - } - } - } - return Collections.emptyList(); - } - - @Override - public List getServices() { - LinkedHashSet services = new LinkedHashSet<>(); - if (this.discoveryClients != null) { - for (DiscoveryClient discoveryClient : this.discoveryClients) { - List serviceForClient = discoveryClient.getServices(); - if (serviceForClient != null) { - services.addAll(serviceForClient); - } - } - } - return new ArrayList<>(services); - } - - @Override - public void probe() { - if (this.discoveryClients != null) { - for (DiscoveryClient discoveryClient : this.discoveryClients) { - discoveryClient.probe(); - } - } - } - - public List getDiscoveryClients() { - return this.discoveryClients; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java deleted file mode 100644 index 4cc47d5d..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfiguration.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite; - -import java.util.List; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; - -/** - * Auto-configuration for composite discovery client. - * - * @author Biju Kunjummen - */ - -@Configuration(proxyBeanMethods = false) -@AutoConfigureBefore(SimpleDiscoveryClientAutoConfiguration.class) -public class CompositeDiscoveryClientAutoConfiguration { - - @Bean - @Primary - public CompositeDiscoveryClient compositeDiscoveryClient(List discoveryClients) { - return new CompositeDiscoveryClient(discoveryClients); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClient.java deleted file mode 100644 index 6f054916..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClient.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite.reactive; - -import java.util.ArrayList; -import java.util.List; - -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.commons.publisher.CloudFlux; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; - -/** - * A {@link ReactiveDiscoveryClient} that is composed of other discovery clients and - * delegates calls to each of them in order. - * - * @author Tim Ysewyn - */ -public class ReactiveCompositeDiscoveryClient implements ReactiveDiscoveryClient { - - private final List discoveryClients; - - public ReactiveCompositeDiscoveryClient(List discoveryClients) { - AnnotationAwareOrderComparator.sort(discoveryClients); - this.discoveryClients = discoveryClients; - } - - @Override - public String description() { - return "Composite Reactive Discovery Client"; - } - - @Override - public Flux getInstances(String serviceId) { - if (discoveryClients == null || discoveryClients.isEmpty()) { - return Flux.empty(); - } - List> serviceInstances = new ArrayList<>(); - for (ReactiveDiscoveryClient discoveryClient : discoveryClients) { - serviceInstances.add(discoveryClient.getInstances(serviceId)); - } - return CloudFlux.firstNonEmpty(serviceInstances); - } - - @Override - public Flux getServices() { - if (discoveryClients == null || discoveryClients.isEmpty()) { - return Flux.empty(); - } - return Flux.fromIterable(discoveryClients).flatMap(ReactiveDiscoveryClient::getServices); - } - - public List getDiscoveryClients() { - return discoveryClients; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfiguration.java deleted file mode 100644 index 33e48efd..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite.reactive; - -import java.util.List; - -import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; -import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; - -/** - * Auto-configuration for reactive composite discovery client. - * - * @author Tim Ysewyn - * @since 2.2.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnDiscoveryEnabled -@ConditionalOnReactiveDiscoveryEnabled -public class ReactiveCompositeDiscoveryClientAutoConfiguration { - - @Bean - @Primary - public ReactiveCompositeDiscoveryClient reactiveCompositeDiscoveryClient( - List discoveryClients) { - return new ReactiveCompositeDiscoveryClient(discoveryClients); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatEvent.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatEvent.java deleted file mode 100644 index 45130c22..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatEvent.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.event; - -import org.springframework.context.ApplicationEvent; - -/** - * An event that a DiscoveryClient implementation can broadcast if it supports heartbeats - * from the discovery server. Provides listeners with a basic indication of a state change - * in the service catalog. - * - * @author Spencer Gibb - * @author Dave Syer - */ -@SuppressWarnings("serial") -public class HeartbeatEvent extends ApplicationEvent { - - private final Object state; - - /** - * Creates a new event with a source (for example, a discovery client) and a value. - * Neither parameter should be relied on to have specific content or format. - * @param source The source of the event. - * @param state The value indicating state of the catalog. - */ - public HeartbeatEvent(Object source, Object state) { - super(source); - this.state = state; - } - - /** - * A value representing the state of the service catalog. The only requirement is that - * it changes when the catalog is updated; it can be as simple as a version counter or - * a hash. Implementations can provide information to help users visualize what is - * going on in the catalog, but users should not rely on the content (since the - * implementation of the underlying discovery might change). - * @return A value representing state of the service catalog. - */ - public Object getValue() { - return this.state; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitor.java deleted file mode 100644 index dfe9749a..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitor.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.event; - -import java.util.concurrent.atomic.AtomicReference; - -/** - * Helper class for listeners to the {@link HeartbeatEvent}, providing a convenient way to - * determine if there has been a change in state. - * - * @author Dave Syer - */ -public class HeartbeatMonitor { - - private AtomicReference latestHeartbeat = new AtomicReference<>(); - - /** - * @param value The latest heartbeat. - * @return True if the state changed. - */ - public boolean update(Object value) { - Object last = this.latestHeartbeat.get(); - if (value != null && !value.equals(last)) { - return this.latestHeartbeat.compareAndSet(last, value); - } - return false; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstancePreRegisteredEvent.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstancePreRegisteredEvent.java deleted file mode 100644 index d21fc993..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstancePreRegisteredEvent.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.event; - -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.context.ApplicationEvent; - -/** - * An event to fire before a service is registered. - * - * @author Ryan Baxter - */ -public class InstancePreRegisteredEvent extends ApplicationEvent { - - private Registration registration; - - /** - * Create a new pre registration event. - * @param source the object on which the event initially occurred (never {@code null}) - * @param registration the registration meta data - */ - public InstancePreRegisteredEvent(Object source, Registration registration) { - super(source); - this.registration = registration; - } - - /** - * Get the registration data. - * @return the registration data - */ - public Registration getRegistration() { - return this.registration; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstanceRegisteredEvent.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstanceRegisteredEvent.java deleted file mode 100644 index 1b0ee0fd..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/InstanceRegisteredEvent.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.event; - -import org.springframework.context.ApplicationEvent; - -/** - * Event to be published after the local service instance registers itself with a - * discovery service. - * - * @param - type of configuration - * @author Spencer Gibb - */ -@SuppressWarnings("serial") -public class InstanceRegisteredEvent extends ApplicationEvent { - - private T config; - - /** - * Creates a new {@link InstanceRegisteredEvent} instance. - * @param source The component that published the event (never {@code null}). - * @param config The configuration of the instance. - */ - public InstanceRegisteredEvent(Object source, T config) { - super(source); - this.config = config; - } - - public T getConfig() { - return this.config; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/ParentHeartbeatEvent.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/ParentHeartbeatEvent.java deleted file mode 100644 index 21ee97c1..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/event/ParentHeartbeatEvent.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.event; - -import org.springframework.context.ApplicationEvent; - -/** - * Heartbeat event that a parent ApplicationContext can send to a child context. Useful, - * for example, when a config server is located via a DiscoveryClient, in which case the - * {@link HeartbeatEvent} that triggers this event is fired in the parent (bootstrap) - * context. - * - * @author Spencer Gibb - */ -@SuppressWarnings("serial") -// WARNING: do not extend HearbeatEvent because of a parent context forwarding -// Heartbeat events to a child. Avoids a stack overflow. -public class ParentHeartbeatEvent extends ApplicationEvent { - - private final Object value; - - public ParentHeartbeatEvent(Object source, Object value) { - super(source); - this.value = value; - } - - public Object getValue() { - return this.value; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java deleted file mode 100644 index 93a37128..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicator.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health; - -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.core.Ordered; - -/** - * @author Spencer Gibb - * @author Chris Bono - */ -public class DiscoveryClientHealthIndicator - implements DiscoveryHealthIndicator, Ordered, ApplicationListener> { - - private final ObjectProvider discoveryClient; - - private final DiscoveryClientHealthIndicatorProperties properties; - - private final Log log = LogFactory.getLog(DiscoveryClientHealthIndicator.class); - - private AtomicBoolean discoveryInitialized = new AtomicBoolean(false); - - private int order = Ordered.HIGHEST_PRECEDENCE; - - public DiscoveryClientHealthIndicator(ObjectProvider discoveryClient, - DiscoveryClientHealthIndicatorProperties properties) { - this.discoveryClient = discoveryClient; - this.properties = properties; - } - - @Override - public void onApplicationEvent(InstanceRegisteredEvent event) { - if (this.discoveryInitialized.compareAndSet(false, true)) { - this.log.debug("Discovery Client has been initialized"); - } - } - - @Override - public Health health() { - Health.Builder builder = new Health.Builder(); - - if (this.discoveryInitialized.get()) { - try { - DiscoveryClient client = this.discoveryClient.getIfAvailable(); - String description = (this.properties.isIncludeDescription()) ? client.description() : ""; - - if (properties.isUseServicesQuery()) { - List services = client.getServices(); - builder.status(new Status("UP", description)).withDetail("services", services); - } - else { - client.probe(); - builder.status(new Status("UP", description)); - } - } - catch (Exception e) { - this.log.error("Error", e); - builder.down(e); - } - } - else { - builder.status(new Status(Status.UNKNOWN.getCode(), "Discovery Client not initialized")); - } - return builder.build(); - } - - @Override - public String getName() { - return "discoveryClient"; - } - - @Override - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java deleted file mode 100644 index 8f6b2f8d..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorProperties.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -/** - * @author Spencer Gibb - */ -@ConfigurationProperties("spring.cloud.discovery.client.health-indicator") -public class DiscoveryClientHealthIndicatorProperties { - - private boolean enabled = true; - - private boolean includeDescription = false; - - /** - * Whether or not the indicator should use {@link DiscoveryClient#getServices} to - * check its health. When set to {@code false} the indicator instead uses the lighter - * {@link DiscoveryClient#probe()}. This can be helpful in large deployments where the - * number of services returned makes the operation unnecessarily heavy. - */ - private boolean useServicesQuery = true; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isIncludeDescription() { - return this.includeDescription; - } - - public void setIncludeDescription(boolean includeDescription) { - this.includeDescription = includeDescription; - } - - public boolean isUseServicesQuery() { - return useServicesQuery; - } - - public void setUseServicesQuery(boolean useServicesQuery) { - this.useServicesQuery = useServicesQuery; - } - - @Override - public String toString() { - return "DiscoveryClientHealthIndicatorProperties{" + "enabled=" + this.enabled + ", includeDescription=" - + this.includeDescription + ", useServicesQuery=" + this.useServicesQuery + '}'; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributor.java deleted file mode 100644 index cde4574c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributor.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health; - -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.util.Assert; - -/** - * Adapter that converts a collection of {@link DiscoveryHealthIndicator} beans into a - * {@link CompositeHealthContributor}. - * - * @author Phillip Webb - * @since 2.2.0 - */ -public class DiscoveryCompositeHealthContributor implements CompositeHealthContributor { - - private Map indicators; - - public DiscoveryCompositeHealthContributor(Collection indicators) { - Assert.notNull(indicators, "'indicators' must not be null"); - this.indicators = indicators.stream() - .collect(Collectors.toMap(DiscoveryHealthIndicator::getName, Function.identity())); - } - - @Override - public HealthContributor getContributor(String name) { - return asHealthIndicator(this.indicators.get(name)); - } - - @Override - public Iterator> iterator() { - return this.indicators.values().stream().map(this::asNamedContributor).iterator(); - } - - private NamedContributor asNamedContributor(DiscoveryHealthIndicator indicator) { - return new NamedContributor<>() { - - @Override - public String getName() { - return indicator.getName(); - } - - @Override - public HealthIndicator getContributor() { - return asHealthIndicator(indicator); - } - - }; - } - - private HealthIndicator asHealthIndicator(DiscoveryHealthIndicator indicator) { - return (indicator != null) ? indicator::health : null; - } - - public Map getIndicators() { - return Collections.unmodifiableMap(indicators); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryHealthIndicator.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryHealthIndicator.java deleted file mode 100644 index 0deb4cf2..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/DiscoveryHealthIndicator.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health; - -import org.springframework.boot.actuate.health.Health; - -/** - * A health indicator interface specific to a DiscoveryClient implementation. - * - * @author Spencer Gibb - */ -public interface DiscoveryHealthIndicator { - - String getName(); - - /** - * @return An indication of health. - */ - Health health(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicator.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicator.java deleted file mode 100644 index 13111cd8..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicator.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health.reactive; - -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties; -import org.springframework.context.ApplicationListener; -import org.springframework.core.Ordered; - -import static java.util.Collections.emptyList; - -/** - * A health indicator which indicates whether the discovery client has been initialized. - * - * @author Tim Ysewyn - * @author Chris Bono - * @author Olga Maciaszek-Sharma - */ -public class ReactiveDiscoveryClientHealthIndicator - implements ReactiveDiscoveryHealthIndicator, Ordered, ApplicationListener> { - - private static final Log LOG = LogFactory.getLog(ReactiveDiscoveryClientHealthIndicator.class); - - private final ReactiveDiscoveryClient discoveryClient; - - private final DiscoveryClientHealthIndicatorProperties properties; - - private AtomicBoolean discoveryInitialized = new AtomicBoolean(false); - - private int order = Ordered.HIGHEST_PRECEDENCE; - - public ReactiveDiscoveryClientHealthIndicator(ReactiveDiscoveryClient discoveryClient, - DiscoveryClientHealthIndicatorProperties properties) { - this.discoveryClient = discoveryClient; - this.properties = properties; - } - - @Override - public void onApplicationEvent(InstanceRegisteredEvent event) { - if (discoveryInitialized.compareAndSet(false, true)) { - LOG.debug("Discovery Client has been initialized"); - } - } - - @Override - public Mono health() { - if (discoveryInitialized.get()) { - return doHealthCheck(); - } - else { - return Mono.just( - Health.status(new Status(Status.UNKNOWN.getCode(), "Discovery Client not initialized")).build()); - } - } - - private Mono doHealthCheck() { - // @formatter:off - return Mono.just(properties.isUseServicesQuery()) - .flatMap(useServices -> useServices ? doHealthCheckWithServices() : doHealthCheckWithProbe()) - .onErrorResume(exception -> { - if (LOG.isErrorEnabled()) { - LOG.error("Error", exception); - } - return Mono.just(Health.down().withException(exception).build()); - }); - // @formatter:on - } - - private Mono doHealthCheckWithProbe() { - return discoveryClient.reactiveProbe().doOnError(exception -> { - if (LOG.isErrorEnabled()) { - LOG.error("Probe has failed.", exception); - } - }).then(buildHealthUp(discoveryClient)); - } - - private Mono buildHealthUp(ReactiveDiscoveryClient discoveryClient) { - String description = (properties.isIncludeDescription()) ? discoveryClient.description() : ""; - return Mono.just(Health.status(new Status("UP", description)).build()); - } - - private Mono doHealthCheckWithServices() { - // @formatter:off - return Mono.justOrEmpty(discoveryClient) - .flatMapMany(ReactiveDiscoveryClient::getServices) - .collectList() - .defaultIfEmpty(emptyList()) - .map(services -> { - String description = (properties.isIncludeDescription()) ? - discoveryClient.description() : ""; - return Health.status(new Status("UP", description)) - .withDetail("services", services).build(); - }); - // @formatter:on - } - - @Override - public String getName() { - return discoveryClient.description(); - } - - @Override - public int getOrder() { - return order; - } - - public void setOrder(int order) { - this.order = order; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributor.java deleted file mode 100644 index dcaeac4a..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributor.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health.reactive; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.springframework.boot.actuate.health.CompositeReactiveHealthContributor; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; -import org.springframework.util.Assert; - -/** - * A composite health contributor specific to a reactive discovery client implementation. - * - * @author Tim Ysewyn - */ -public class ReactiveDiscoveryCompositeHealthContributor implements CompositeReactiveHealthContributor { - - private Map indicators; - - public ReactiveDiscoveryCompositeHealthContributor(Collection indicators) { - Assert.notNull(indicators, "'indicators' must not be null"); - this.indicators = indicators.stream() - .collect(Collectors.toMap(ReactiveDiscoveryHealthIndicator::getName, Function.identity())); - } - - @Override - public ReactiveHealthContributor getContributor(String name) { - return asHealthIndicator(indicators.get(name)); - } - - @Override - public Iterator> iterator() { - return indicators.values().stream().map(this::asNamedContributor).iterator(); - } - - private NamedContributor asNamedContributor(ReactiveDiscoveryHealthIndicator indicator) { - return new NamedContributor<>() { - - @Override - public String getName() { - return indicator.getName(); - } - - @Override - public ReactiveHealthContributor getContributor() { - return asHealthIndicator(indicator); - } - - }; - } - - private ReactiveHealthIndicator asHealthIndicator(ReactiveDiscoveryHealthIndicator indicator) { - return (indicator != null) ? indicator::health : null; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryHealthIndicator.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryHealthIndicator.java deleted file mode 100644 index a54e0e7f..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryHealthIndicator.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health.reactive; - -import reactor.core.publisher.Mono; - -import org.springframework.boot.actuate.health.Health; - -/** - * A health indicator interface specific to a reactive discovery client implementation. - * - * @author Tim Ysewyn - */ -public interface ReactiveDiscoveryHealthIndicator { - - /** - * Provide the name of health indicator. - * @return a {@link String} that provides the name of health indicator, usually the - * name of the implementation. - */ - String getName(); - - /** - * Provide the indicator of health. - * @return a {@link Mono} that provides the {@link Health} - */ - Mono health(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java deleted file mode 100644 index cd9c1968..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -/** - * A {@link org.springframework.cloud.client.discovery.DiscoveryClient} that will use the - * properties file as a source of service instances. - * - * @author Biju Kunjummen - * @author Olga Maciaszek-Sharma - * @author Charu Covindane - */ -public class SimpleDiscoveryClient implements DiscoveryClient { - - private SimpleDiscoveryProperties simpleDiscoveryProperties; - - public SimpleDiscoveryClient(SimpleDiscoveryProperties simpleDiscoveryProperties) { - this.simpleDiscoveryProperties = simpleDiscoveryProperties; - } - - @Override - public String description() { - return "Simple Discovery Client"; - } - - @Override - public List getInstances(String serviceId) { - List serviceInstances = new ArrayList<>(); - List serviceInstanceForService = this.simpleDiscoveryProperties.getInstances() - .get(serviceId); - if (serviceInstanceForService != null) { - serviceInstances.addAll(serviceInstanceForService); - } - return serviceInstances; - } - - @Override - public List getServices() { - return new ArrayList<>(this.simpleDiscoveryProperties.getInstances().keySet()); - } - - @Override - public int getOrder() { - return this.simpleDiscoveryProperties.getOrder(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java deleted file mode 100644 index 035ccab3..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -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.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.cloud.client.CommonsClientAutoConfiguration; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; - -/** - * Spring Boot auto-configuration for simple properties-based discovery client. - * - * @author Biju Kunjummen - * @author Charu Covindane - */ -@Configuration(proxyBeanMethods = false) -@AutoConfigureBefore({ CommonsClientAutoConfiguration.class }) -public class SimpleDiscoveryClientAutoConfiguration implements ApplicationListener { - - private ServerProperties server; - - private InetUtils inet; - - private int port = 0; - - private SimpleDiscoveryProperties simple = new SimpleDiscoveryProperties(); - - @Autowired(required = false) - public void setServer(ServerProperties server) { - this.server = server; - } - - @Autowired - public void setInet(InetUtils inet) { - this.inet = inet; - } - - @Bean - @ConditionalOnMissingBean - public SimpleDiscoveryProperties simpleDiscoveryProperties( - @Value("${spring.application.name:application}") String serviceId) { - simple.getLocal().setServiceId(serviceId); - simple.getLocal().setHost(inet.findFirstNonLoopbackHostInfo().getHostname()); - simple.getLocal().setPort(findPort()); - return simple; - } - - @Bean - @Order - public DiscoveryClient simpleDiscoveryClient(SimpleDiscoveryProperties properties) { - return new SimpleDiscoveryClient(properties); - } - - private int findPort() { - if (port > 0) { - return port; - } - if (server != null && server.getPort() != null && server.getPort() > 0) { - return server.getPort(); - } - return 8080; - } - - @Override - public void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) { - port = webServerInitializedEvent.getWebServer().getPort(); - if (port > 0) { - simple.getLocal().setHost(inet.findFirstNonLoopbackHostInfo().getHostname()); - simple.getLocal().setPort(port); - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java deleted file mode 100644 index f5fd10cf..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.NestedConfigurationProperty; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -/** - * Properties to hold the details of a - * {@link org.springframework.cloud.client.discovery.DiscoveryClient} service instances - * for a given service. It also holds the user-configurable order that will be used to - * establish the precedence of this client in the list of clients used by - * {@link org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient}. - * - * @author Biju Kunjummen - * @author Olga Maciaszek-Sharma - * @author Tim Ysewyn - * @author Charu Covindane - */ - -@ConfigurationProperties(prefix = "spring.cloud.discovery.client.simple") -public class SimpleDiscoveryProperties implements InitializingBean { - - private Map> instances = new HashMap<>(); - - /** - * The properties of the local instance (if it exists). Users should set these - * properties explicitly if they are exporting data (e.g. metrics) that need to be - * identified by the service instance. - */ - @NestedConfigurationProperty - private DefaultServiceInstance local = new DefaultServiceInstance(null, null, null, 0, false); - - private int order = DiscoveryClient.DEFAULT_ORDER; - - public Map> getInstances() { - return this.instances; - } - - public void setInstances(Map> instances) { - this.instances = instances; - } - - public DefaultServiceInstance getLocal() { - return this.local; - } - - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public void afterPropertiesSet() { - for (String key : this.instances.keySet()) { - for (DefaultServiceInstance instance : this.instances.get(key)) { - instance.setServiceId(key); - } - } - } - - public void setInstance(String serviceId, String host, int port) { - local = new DefaultServiceInstance(null, serviceId, host, port, false); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClient.java deleted file mode 100644 index d961137e..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClient.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple.reactive; - -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; - -/** - * A {@link ReactiveDiscoveryClient} that will use the properties file as a source of - * service instances. - * - * @author Tim Ysewyn - */ -public class SimpleReactiveDiscoveryClient implements ReactiveDiscoveryClient { - - private SimpleReactiveDiscoveryProperties simpleDiscoveryProperties; - - public SimpleReactiveDiscoveryClient(SimpleReactiveDiscoveryProperties simpleDiscoveryProperties) { - this.simpleDiscoveryProperties = simpleDiscoveryProperties; - } - - @Override - public String description() { - return "Simple Reactive Discovery Client"; - } - - @Override - public Flux getInstances(String serviceId) { - return this.simpleDiscoveryProperties.getInstances(serviceId); - } - - @Override - public Flux getServices() { - return Flux.fromIterable(this.simpleDiscoveryProperties.getInstances().keySet()); - } - - @Override - public int getOrder() { - return this.simpleDiscoveryProperties.getOrder(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfiguration.java deleted file mode 100644 index 42289b70..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfiguration.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple.reactive; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; -import org.springframework.cloud.client.ConditionalOnDiscoveryHealthIndicatorEnabled; -import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled; -import org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration; -import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration; -import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties; -import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryClientHealthIndicator; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; - -/** - * Spring Boot auto-configuration for simple properties-based reactive discovery client. - * - * @author Tim Ysewyn - * @author Charu Covindane - * @since 2.2.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnDiscoveryEnabled -@ConditionalOnReactiveDiscoveryEnabled -@EnableConfigurationProperties(DiscoveryClientHealthIndicatorProperties.class) -@AutoConfigureBefore(ReactiveCommonsClientAutoConfiguration.class) -@AutoConfigureAfter(ReactiveCompositeDiscoveryClientAutoConfiguration.class) -public class SimpleReactiveDiscoveryClientAutoConfiguration implements ApplicationListener { - - @Autowired(required = false) - private ServerProperties server; - - @Value("${spring.application.name:application}") - private String serviceId; - - @Autowired - private InetUtils inet; - - private int port = 0; - - private SimpleReactiveDiscoveryProperties simple = new SimpleReactiveDiscoveryProperties(); - - @Bean - public SimpleReactiveDiscoveryProperties simpleReactiveDiscoveryProperties() { - simple.getLocal().setServiceId(serviceId); - simple.getLocal().setHost(inet.findFirstNonLoopbackHostInfo().getHostname()); - simple.getLocal().setPort(findPort()); - return simple; - } - - @Bean - @Order - public SimpleReactiveDiscoveryClient simpleReactiveDiscoveryClient(SimpleReactiveDiscoveryProperties properties) { - return new SimpleReactiveDiscoveryClient(properties); - } - - private int findPort() { - if (port > 0) { - return port; - } - if (server != null && server.getPort() != null && server.getPort() > 0) { - return server.getPort(); - } - return 8080; - } - - @Override - public void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) { - port = webServerInitializedEvent.getWebServer().getPort(); - if (port > 0) { - simple.getLocal().setHost(inet.findFirstNonLoopbackHostInfo().getHostname()); - simple.getLocal().setPort(port); - } - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(ReactiveHealthIndicator.class) - protected static class HealthConfiguration { - - @Bean - @ConditionalOnDiscoveryHealthIndicatorEnabled - public ReactiveDiscoveryClientHealthIndicator simpleReactiveDiscoveryClientHealthIndicator( - DiscoveryClientHealthIndicatorProperties properties, - SimpleReactiveDiscoveryClient simpleReactiveDiscoveryClient) { - return new ReactiveDiscoveryClientHealthIndicator(simpleReactiveDiscoveryClient, properties); - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryProperties.java deleted file mode 100644 index d9b0fc2c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryProperties.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple.reactive; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import reactor.core.publisher.Flux; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; - -import static java.util.Collections.emptyList; - -/** - * Properties to hold the details of a {@link ReactiveDiscoveryClient} service instance - * for a given service. It also holds the user-configurable order that will be used to - * establish the precedence of this client in the list of clients used by - * {@link org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient}. - * - * @author Tim Ysewyn - * @author Charu Covindane - * @since 2.2.0 - */ -@ConfigurationProperties(prefix = "spring.cloud.discovery.client.simple") -public class SimpleReactiveDiscoveryProperties implements InitializingBean { - - private Map> instances = new HashMap<>(); - - /** - * The properties of the local instance (if it exists). Users should set these - * properties explicitly if they are exporting data (e.g. metrics) that need to be - * identified by the service instance. - */ - private DefaultServiceInstance local = new DefaultServiceInstance(); - - private int order = DiscoveryClient.DEFAULT_ORDER; - - public Flux getInstances(String service) { - return Flux.fromIterable(instances.getOrDefault(service, emptyList())); - } - - Map> getInstances() { - return instances; - } - - public void setInstances(Map> instances) { - this.instances = instances; - } - - public DefaultServiceInstance getLocal() { - return this.local; - } - - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public void afterPropertiesSet() { - for (String key : this.instances.keySet()) { - for (DefaultServiceInstance instance : this.instances.get(key)) { - instance.setServiceId(key); - } - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfiguration.java deleted file mode 100644 index e69ebda7..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfiguration.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import java.util.Collections; -import java.util.List; - -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.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration.CloudHypermediaProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.hateoas.Link; - -/** - * Registers a default {@link RemoteResourceRefresher} if at least one - * {@link RemoteResource} is declared in the system. Applies verification timings defined - * in the application properties. - * - * @author Oliver Gierke - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(Link.class) -@ConditionalOnBean(type = "org.springframework.cloud.client.hypermedia.RemoteResource") -@EnableConfigurationProperties(CloudHypermediaProperties.class) -public class CloudHypermediaAutoConfiguration { - - @Autowired(required = false) - List discoveredResources = Collections.emptyList(); - - @Autowired - CloudHypermediaProperties properties; - - @Bean - @ConditionalOnMissingBean - public RemoteResourceRefresher discoveredResourceRefresher() { - return new RemoteResourceRefresher(this.discoveredResources, this.properties.getRefresh().getFixedDelay(), - this.properties.getRefresh().getInitialDelay()); - } - - /** - * Configuration for Cloud hypermedia. - */ - @ConfigurationProperties(prefix = "spring.cloud.hypermedia") - public static class CloudHypermediaProperties { - - private Refresh refresh = new Refresh(); - - public Refresh getRefresh() { - return this.refresh; - } - - public void setRefresh(Refresh refresh) { - this.refresh = refresh; - } - - /** - * Configuration for Cloud hypermedia refresh. - */ - public static class Refresh { - - private int fixedDelay = 5000; - - private int initialDelay = 10000; - - public int getFixedDelay() { - return this.fixedDelay; - } - - public void setFixedDelay(int fixedDelay) { - this.fixedDelay = fixedDelay; - } - - public int getInitialDelay() { - return this.initialDelay; - } - - public void setInitialDelay(int initialDelay) { - this.initialDelay = initialDelay; - } - - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DiscoveredResource.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DiscoveredResource.java deleted file mode 100644 index 6c0fc6b9..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DiscoveredResource.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import java.net.URI; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.hateoas.Link; -import org.springframework.hateoas.MediaTypes; -import org.springframework.hateoas.client.Traverson; -import org.springframework.util.Assert; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestOperations; -import org.springframework.web.client.RestTemplate; - -/** - * A REST resource that is defined by a service reference and a traversal operation within - * that service. - * - * @author Oliver Gierke - */ -public class DiscoveredResource implements RemoteResource { - - private final ServiceInstanceProvider provider; - - private final TraversalDefinition traversal; - - private final Logger log = LoggerFactory.getLogger(DiscoveredResource.class); - - private RestOperations restOperations = new RestTemplate(); - - private Link link = null; - - public DiscoveredResource(ServiceInstanceProvider provider, TraversalDefinition traversal) { - this.provider = provider; - this.traversal = traversal; - } - - public ServiceInstanceProvider getProvider() { - return this.provider; - } - - public TraversalDefinition getTraversal() { - return this.traversal; - } - - public RestOperations getRestOperations() { - return this.restOperations; - } - - /** - * Configures the {@link RestOperations} to use to execute the traversal and verifying - * HEAD calls. - * @param restOperations Can be {@literal null}; resorts to a default - * {@link RestTemplate} in that case. - */ - public void setRestOperations(RestOperations restOperations) { - this.restOperations = restOperations == null ? new RestTemplate() : restOperations; - } - - @Override - public Link getLink() { - return this.link; - } - - public void setLink(Link link) { - this.link = link; - } - - /** - * Verifies the link to the current. - */ - public void verifyOrDiscover() { - this.link = this.link == null ? discoverLink() : verify(this.link); - } - - /** - * Verifies the given {@link Link} by issuing an HTTP HEAD request to the resource. - * @param link Must not be {@literal null}. - * @return - link to the resource - */ - private Link verify(Link link) { - - Assert.notNull(link, "Link must not be null!"); - - try { - - String uri = link.expand().getHref(); - - this.log.debug("Verifying link pointing to {}…", uri); - this.restOperations.headForHeaders(uri); - this.log.debug("Successfully verified link!"); - - return link; - - } - catch (RestClientException o_O) { - - this.log.debug("Verification failed, marking as outdated!"); - return null; - } - } - - private Link discoverLink() { - - try { - - ServiceInstance service = this.provider.getServiceInstance(); - - if (service == null) { - return null; - } - - URI uri = service.getUri(); - String serviceId = service.getServiceId(); - - this.log.debug("Discovered {} system at {}. Discovering resource…", serviceId, uri); - - Traverson traverson = new Traverson(uri, MediaTypes.HAL_JSON); - Link link = this.traversal.buildTraversal(traverson).asTemplatedLink(); - - this.log.debug("Found link pointing to {}.", link.getHref()); - - return link; - - } - catch (RuntimeException o_O) { - - this.link = null; - this.log.debug("Target system unavailable. Got: ", o_O.getMessage()); - - return null; - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProvider.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProvider.java deleted file mode 100644 index ee07259c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import java.util.List; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -/** - * {@link ServiceInstanceProvider} to work with a {@link DiscoveryClient} to look up a - * service by name. Picks the first one returned by the configured - * {@link DiscoveryClient}. - * - * @author Oliver Gierke - */ -public class DynamicServiceInstanceProvider implements ServiceInstanceProvider { - - private final DiscoveryClient client; - - private final String serviceName; - - public DynamicServiceInstanceProvider(DiscoveryClient client, String serviceName) { - this.client = client; - this.serviceName = serviceName; - } - - /* - * (non-Javadoc) - * - * @see example.customers.integration.ServiceInstanceProvider#getServiceInstance() - */ - @Override - public ServiceInstance getServiceInstance() { - - try { - - List instances = this.client.getInstances(this.serviceName); - return instances.isEmpty() ? null : instances.get(0); - - } - catch (RuntimeException o_O) { - return null; - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResource.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResource.java deleted file mode 100644 index 00fe349c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResource.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import org.springframework.hateoas.Link; - -/** - * A REST resource that can be discovered and can be either gone or available. - * - * @author Oliver Gierke - */ -public interface RemoteResource { - - /** - * Returns the {@link Link} to the resource if it is available, or {@literal null} if - * it is gone (i.e. it either is generally unavailable or can't be discovered). - * @return a link to the resource. - */ - Link getLink(); - - /** - * Discovers the resource if it hasn't been discovered yet or has become unavailable. - * If a link has been discovered previously, it is verified and either confirmed or - * removed to indicate that it's not available anymore. - */ - void verifyOrDiscover(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResourceRefresher.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResourceRefresher.java deleted file mode 100644 index f696ade8..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/RemoteResourceRefresher.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import java.time.Duration; -import java.util.List; - -import org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar; -import org.springframework.scheduling.config.IntervalTask; -import org.springframework.scheduling.config.ScheduledTaskRegistrar; - -/** - * A {@link ScheduledTaskRegistrar} that verifies all {@link DiscoveredResource} instances - * in the system, based on the given timing configuration. - * - * @author Oliver Gierke - */ -public class RemoteResourceRefresher extends ContextLifecycleScheduledTaskRegistrar { - - private final List discoveredResources; - - private final int fixedDelay; - - private final int initialDelay; - - public RemoteResourceRefresher(List discoveredResources, int fixedDelay, int initialDelay) { - this.discoveredResources = discoveredResources; - this.fixedDelay = fixedDelay; - this.initialDelay = initialDelay; - } - - /* - * (non-Javadoc) - * - * @see org.springframework.scheduling.config.ContextLifecycleScheduledTaskRegistrar# - * afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - - for (final RemoteResource resource : this.discoveredResources) { - addFixedDelayTask(new IntervalTask(resource::verifyOrDiscover, Duration.ofMillis(fixedDelay), - Duration.ofMillis(initialDelay))); - } - - super.afterPropertiesSet(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/ServiceInstanceProvider.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/ServiceInstanceProvider.java deleted file mode 100644 index 93a5cbbc..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/ServiceInstanceProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * A component that will provide a {@link ServiceInstance}, or can express the absence of - * one by returning {@literal null}. - * - * @author Oliver Gierke - */ -public interface ServiceInstanceProvider { - - /** - * Returns the service instance or {@literal null} if the service is currently - * unavailable. - * @return The service instance, or {@literal null} if the service is currently - * unavailable. - */ - ServiceInstance getServiceInstance(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/StaticServiceInstanceProvider.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/StaticServiceInstanceProvider.java deleted file mode 100644 index 60c2dfc7..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/StaticServiceInstanceProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * A {@link ServiceInstanceProvider} that will always return the configured - * {@link ServiceInstance}. - * - * @author Oliver Gierke - */ -public class StaticServiceInstanceProvider implements ServiceInstanceProvider { - - private final ServiceInstance instance; - - public StaticServiceInstanceProvider(ServiceInstance instance) { - this.instance = instance; - } - - /* - * (non-Javadoc) - * - * @see example.customers.integration.ServiceInstanceProvider#getServiceInstance() - */ - @Override - public ServiceInstance getServiceInstance() { - return this.instance; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/TraversalDefinition.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/TraversalDefinition.java deleted file mode 100644 index 5f1863bc..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/hypermedia/TraversalDefinition.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import org.springframework.hateoas.client.Traverson; - -/** - * Callback to define the traversal to a resource. - * - * @author Oliver Gierke - */ -public interface TraversalDefinition { - - /** - * @param traverson The Traverson instance to run the traversal on. - * @return the builder for traversing - */ - Traverson.TraversalBuilder buildTraversal(Traverson traverson); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/BlockingLoadBalancerRequest.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/BlockingLoadBalancerRequest.java deleted file mode 100644 index d51e247f..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/BlockingLoadBalancerRequest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.List; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; - -/** - * Default {@link LoadBalancerRequest} implementation. - * - * @author Olga Maciaszek-Sharma - * @since 3.1.2 - */ -class BlockingLoadBalancerRequest implements HttpRequestLoadBalancerRequest { - - private final LoadBalancerClient loadBalancer; - - private final List transformers; - - private final ClientHttpRequestData clientHttpRequestData; - - BlockingLoadBalancerRequest(LoadBalancerClient loadBalancer, List transformers, - ClientHttpRequestData clientHttpRequestData) { - this.loadBalancer = loadBalancer; - this.transformers = transformers; - this.clientHttpRequestData = clientHttpRequestData; - } - - @Override - public ClientHttpResponse apply(ServiceInstance instance) throws Exception { - HttpRequest serviceRequest = new ServiceRequestWrapper(clientHttpRequestData.request, instance, loadBalancer); - if (this.transformers != null) { - for (LoadBalancerRequestTransformer transformer : this.transformers) { - serviceRequest = transformer.transformRequest(serviceRequest, instance); - } - } - return clientHttpRequestData.execution.execute(serviceRequest, clientHttpRequestData.body); - } - - @Override - public HttpRequest getHttpRequest() { - return clientHttpRequestData.request; - } - - static class ClientHttpRequestData { - - private final HttpRequest request; - - private final byte[] body; - - private final ClientHttpRequestExecution execution; - - ClientHttpRequestData(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) { - this.request = request; - this.body = body; - this.execution = execution; - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeException.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeException.java deleted file mode 100644 index fd83c895..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeException.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.client.AbstractClientHttpResponse; -import org.springframework.http.client.ClientHttpResponse; - -/** - * {@link RetryableStatusCodeException} that captures a {@link ClientHttpResponse}. - * - * @author Ryan Baxter - */ -public class ClientHttpResponseStatusCodeException extends RetryableStatusCodeException { - - private final ClientHttpResponseWrapper response; - - /** - * Constructor. - * @param serviceId The service ID. - * @param response The response object. - * @param body The response body. - * @throws IOException Thrown if the {@link ClientHttpResponse} response code cannot - * be retrieved. - */ - public ClientHttpResponseStatusCodeException(String serviceId, ClientHttpResponse response, byte[] body) - throws IOException { - super(serviceId, response.getStatusCode().value(), response, null); - this.response = new ClientHttpResponseWrapper(response, body); - } - - @Override - public ClientHttpResponse getResponse() { - return this.response; - } - - static class ClientHttpResponseWrapper extends AbstractClientHttpResponse { - - private ClientHttpResponse response; - - private byte[] body; - - ClientHttpResponseWrapper(ClientHttpResponse response, byte[] body) { - this.response = response; - this.body = body; - } - - @Override - public int getRawStatusCode() throws IOException { - return this.response.getStatusCode().value(); - } - - @Override - public String getStatusText() throws IOException { - return this.response.getStatusText(); - } - - @Override - public void close() { - this.response.close(); - } - - @Override - public InputStream getBody() { - return new ByteArrayInputStream(this.body); - } - - @Override - public HttpHeaders getHeaders() { - return this.response.getHeaders(); - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/CompletionContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/CompletionContext.java deleted file mode 100644 index dfbdb7c3..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/CompletionContext.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.core.style.ToStringCreator; - -/** - * Allows propagation of data related to load-balanced call completion status. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class CompletionContext { - - private final Status status; - - private final Throwable throwable; - - private final Response loadBalancerResponse; - - private final RES clientResponse; - - private final Request loadBalancerRequest; - - public CompletionContext(Status status, Request loadBalancerRequest) { - this(status, null, loadBalancerRequest, null, null); - } - - public CompletionContext(Status status, Request loadBalancerRequest, Response response) { - this(status, null, loadBalancerRequest, response, null); - } - - public CompletionContext(Status status, Throwable throwable, Request loadBalancerRequest, - Response loadBalancerResponse) { - this(status, throwable, loadBalancerRequest, loadBalancerResponse, null); - } - - public CompletionContext(Status status, Request loadBalancerRequest, Response loadBalancerResponse, - RES clientResponse) { - this(status, null, loadBalancerRequest, loadBalancerResponse, clientResponse); - } - - public CompletionContext(Status status, Throwable throwable, Request loadBalancerRequest, - Response loadBalancerResponse, RES clientResponse) { - this.status = status; - this.throwable = throwable; - this.loadBalancerRequest = loadBalancerRequest; - this.loadBalancerResponse = loadBalancerResponse; - this.clientResponse = clientResponse; - } - - public Status status() { - return this.status; - } - - public Throwable getThrowable() { - return this.throwable; - } - - public Response getLoadBalancerResponse() { - return loadBalancerResponse; - } - - public RES getClientResponse() { - return clientResponse; - } - - public Request getLoadBalancerRequest() { - return loadBalancerRequest; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("status", this.status); - to.append("throwable", this.throwable); - to.append("loadBalancerResponse", loadBalancerResponse); - to.append("clientResponse", clientResponse); - return to.toString(); - } - - /** - * Request status state. - */ - public enum Status { - - /** Request was handled successfully. */ - SUCCESS, - /** Request reached the server but failed due to timeout or internal error. */ - FAILED, - /** Request did not go off box and should not be counted for statistics. */ - DISCARD, - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequest.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequest.java deleted file mode 100644 index 7079ad67..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.Objects; - -import org.springframework.core.style.ToStringCreator; - -/** - * A default implementation of {@link Request}. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -public class DefaultRequest implements Request { - - private T context; - - public DefaultRequest() { - new DefaultRequestContext(); - } - - public DefaultRequest(T context) { - this.context = context; - } - - @Override - public T getContext() { - return context; - } - - public void setContext(T context) { - this.context = context; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("context", context); - return to.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DefaultRequest that)) { - return false; - } - return Objects.equals(context, that.context); - } - - @Override - public int hashCode() { - return Objects.hash(context); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequestContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequestContext.java deleted file mode 100644 index f0bd9d21..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultRequestContext.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.Objects; - -import org.springframework.core.style.ToStringCreator; - -/** - * Contains information relevant to the request. - * - * @author Olga Maciaszek-Sharma - */ -public class DefaultRequestContext extends HintRequestContext { - - /** - * The request to be executed against the service instance selected by the - * LoadBalancer. - */ - private final Object clientRequest; - - public DefaultRequestContext() { - clientRequest = null; - } - - public DefaultRequestContext(Object clientRequest) { - this.clientRequest = clientRequest; - } - - public DefaultRequestContext(Object clientRequest, String hint) { - super(hint); - this.clientRequest = clientRequest; - } - - public Object getClientRequest() { - return clientRequest; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("clientRequest", clientRequest); - return to.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DefaultRequestContext that)) { - return false; - } - return Objects.equals(clientRequest, that.clientRequest); - } - - @Override - public int hashCode() { - return Objects.hash(clientRequest); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultResponse.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultResponse.java deleted file mode 100644 index 7e966338..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/DefaultResponse.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.Objects; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.style.ToStringCreator; - -/** - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -public class DefaultResponse implements Response { - - private final ServiceInstance serviceInstance; - - public DefaultResponse(ServiceInstance serviceInstance) { - this.serviceInstance = serviceInstance; - } - - @Override - public boolean hasServer() { - return this.serviceInstance != null; - } - - @Override - public ServiceInstance getServer() { - return this.serviceInstance; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("serviceInstance", serviceInstance); - return to.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof DefaultResponse that)) { - return false; - } - return Objects.equals(serviceInstance, that.serviceInstance); - } - - @Override - public int hashCode() { - return Objects.hash(serviceInstance); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/EmptyResponse.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/EmptyResponse.java deleted file mode 100644 index 1253526d..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/EmptyResponse.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * @author Spencer Gibb - */ -public class EmptyResponse implements Response { - - @Override - public boolean hasServer() { - return false; - } - - @Override - public ServiceInstance getServer() { - return null; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HintRequestContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HintRequestContext.java deleted file mode 100644 index e62a1c61..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HintRequestContext.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.Objects; - -import org.springframework.core.style.ToStringCreator; - -/** - * Allows propagating hints to the LoadBalancer. - * - * @author Olga Maciaszek-Sharma - */ -public class HintRequestContext implements TimedRequestContext { - - /** - * A {@link String} value of hint that can be used to choose the correct service - * instance. - */ - private String hint = "default"; - - private long requestStartTime; - - public HintRequestContext() { - } - - public HintRequestContext(String hint) { - this.hint = hint; - } - - public String getHint() { - return hint; - } - - public void setHint(String hint) { - this.hint = hint; - } - - @Override - public long getRequestStartTime() { - return requestStartTime; - } - - @Override - public void setRequestStartTime(long requestStartTime) { - this.requestStartTime = requestStartTime; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("hint", hint); - return to.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof HintRequestContext that)) { - return false; - } - return Objects.equals(hint, that.hint); - } - - @Override - public int hashCode() { - return Objects.hash(hint); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HttpRequestLoadBalancerRequest.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HttpRequestLoadBalancerRequest.java deleted file mode 100644 index 9c4ae023..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/HttpRequestLoadBalancerRequest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.http.HttpRequest; - -/** - * Represents a {@link LoadBalancerRequest} created on top of an {@link HttpRequest}. - * - * @author Olga Maciaszek-Sharma - * @since 3.1.2 - */ -public interface HttpRequestLoadBalancerRequest extends LoadBalancerRequest { - - HttpRequest getHttpRequest(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicy.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicy.java deleted file mode 100644 index b9cbce9d..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicy.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryPolicy; - -/** - * {@link RetryPolicy} used by the {@link LoadBalancerClient} when retrying failed - * requests. - * - * @author Ryan Baxter - * @author Olga Maciaszek-Sharma - */ -public class InterceptorRetryPolicy implements RetryPolicy { - - private final HttpRequest request; - - private final LoadBalancedRetryPolicy policy; - - private final ServiceInstanceChooser serviceInstanceChooser; - - private final String serviceName; - - /** - * Creates a new retry policy. - * @param request The request that will be retried. - * @param policy The retry policy from the load balancer. - * @param serviceInstanceChooser The load balancer client. - * @param serviceName The name of the service. - */ - public InterceptorRetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, - ServiceInstanceChooser serviceInstanceChooser, String serviceName) { - this.request = request; - this.policy = policy; - this.serviceInstanceChooser = serviceInstanceChooser; - this.serviceName = serviceName; - } - - @Override - public boolean canRetry(RetryContext context) { - if (!policy.retryableException(context.getLastThrowable())) { - return false; - } - LoadBalancedRetryContext lbContext = (LoadBalancedRetryContext) context; - if (lbContext.getRetryCount() == 0 && lbContext.getServiceInstance() == null) { - // We haven't even tried to make the request yet so return true so we do - lbContext.setServiceInstance(null); - return true; - } - return policy.canRetryNextServer(lbContext); - } - - @Override - public RetryContext open(RetryContext parent) { - return new LoadBalancedRetryContext(parent, request); - } - - @Override - public void close(RetryContext context) { - policy.close((LoadBalancedRetryContext) context); - } - - @Override - public void registerThrowable(RetryContext context, Throwable throwable) { - LoadBalancedRetryContext lbContext = (LoadBalancedRetryContext) context; - // this is important as it registers the last exception in the context and also - // increases the retry count - lbContext.registerThrowable(throwable); - // let the policy know about the exception as well - policy.registerThrowable(lbContext, throwable); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - InterceptorRetryPolicy that = (InterceptorRetryPolicy) o; - - if (!request.equals(that.request)) { - return false; - } - if (!policy.equals(that.policy)) { - return false; - } - if (!serviceInstanceChooser.equals(that.serviceInstanceChooser)) { - return false; - } - return serviceName.equals(that.serviceName); - - } - - @Override - public int hashCode() { - int result = request.hashCode(); - result = 31 * result + policy.hashCode(); - result = 31 * result + serviceInstanceChooser.hashCode(); - result = 31 * result + serviceName.hashCode(); - return result; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalanced.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalanced.java deleted file mode 100644 index a09062ce..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalanced.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -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.beans.factory.annotation.Qualifier; - -/** - * Annotation to mark a RestTemplate or WebClient bean to be configured to use a - * LoadBalancerClient. - * @author Spencer Gibb - */ -@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Inherited -@Qualifier -public @interface LoadBalanced { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRecoveryCallback.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRecoveryCallback.java deleted file mode 100644 index ccbf59cb..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRecoveryCallback.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.net.URI; - -import org.springframework.retry.RecoveryCallback; -import org.springframework.retry.RetryContext; -import org.springframework.retry.RetryException; - -/** - * An implementation of {@link RecoveryCallback} which relies on an implementation of - * {@link RetryableStatusCodeException} to contain the last response object from the - * request. - * - * @param - response type to return - * @param - response type from the HTTP client - * @author LiYuan Lee - */ -public abstract class LoadBalancedRecoveryCallback implements RecoveryCallback { - - /** - * Creates the response returned in the {@link RecoveryCallback}. - * @param response The response from the HTTP client. - * @param uri The URI the response is from. - * @return The response to be returned. - */ - protected abstract T createResponse(R response, URI uri); - - @Override - public T recover(RetryContext context) throws Exception { - Throwable lastThrowable = context.getLastThrowable(); - if (lastThrowable != null) { - if (lastThrowable instanceof RetryableStatusCodeException ex) { - return createResponse((R) ex.getResponse(), ex.getUri()); - } - else if (lastThrowable instanceof Exception) { - throw (Exception) lastThrowable; - } - } - throw new RetryException("Could not recover", lastThrowable); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContext.java deleted file mode 100644 index 9789e046..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContext.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryContext; -import org.springframework.retry.context.RetryContextSupport; - -/** - * {@link RetryContext} for load-balanced retries. - * - * @author Ryan Baxter - * @author Olga Maciaszek-Sharma - */ -public class LoadBalancedRetryContext extends RetryContextSupport { - - private HttpRequest request; - - private ServiceInstance serviceInstance; - - private ServiceInstance previousServiceInstance; - - /** - * Creates a new load-balanced context. - * @param parent The parent context. - * @param request The request that is being load-balanced. - */ - public LoadBalancedRetryContext(RetryContext parent, HttpRequest request) { - super(parent); - this.request = request; - } - - /** - * Gets the request that is being load-balanced. - * @return The request that is being load-balanced. - */ - public HttpRequest getRequest() { - return this.request; - } - - /** - * Sets the request that is being load-balanced. - * @param request The request to be load balanced. - */ - public void setRequest(HttpRequest request) { - this.request = request; - } - - /** - * Gets the service instance used during the retry. - * @return The service instance used during the retry. - */ - public ServiceInstance getServiceInstance() { - return this.serviceInstance; - } - - /** - * Sets the service instance to use during the retry. - * @param serviceInstance The service instance to use during the retry. - */ - public void setServiceInstance(ServiceInstance serviceInstance) { - setPreviousServiceInstance(this.serviceInstance); - this.serviceInstance = serviceInstance; - } - - public ServiceInstance getPreviousServiceInstance() { - return previousServiceInstance; - } - - public void setPreviousServiceInstance(ServiceInstance previousServiceInstance) { - this.previousServiceInstance = previousServiceInstance; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryFactory.java deleted file mode 100644 index 18385391..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.retry.RetryListener; -import org.springframework.retry.backoff.BackOffPolicy; -import org.springframework.retry.backoff.NoBackOffPolicy; - -/** - * Factory class used to customize the retry functionality throughout Spring Cloud. - * - * @author Ryan Baxter - */ -public interface LoadBalancedRetryFactory { - - /** - * Creates a {@link LoadBalancedRetryPolicy}. - * @param service The ID of the service to create the retry policy for. - * @param serviceInstanceChooser Used to get the next server from a load balancer. - * @return A retry policy for the service. - */ - default LoadBalancedRetryPolicy createRetryPolicy(String service, ServiceInstanceChooser serviceInstanceChooser) { - return null; - } - - /** - * Creates an array of {@link RetryListener}s for a given service. - * @param service The service to create the {@link RetryListener}s for. - * @return An array of {@link RetryListener}s. - */ - default RetryListener[] createRetryListeners(String service) { - return new RetryListener[0]; - } - - /** - * Creates a {@link BackOffPolicy} for a given service. - * @param service The service to create the {@link BackOffPolicy} for. - * @return The {@link BackOffPolicy}. - */ - default BackOffPolicy createBackOffPolicy(String service) { - return new NoBackOffPolicy(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java deleted file mode 100644 index 0d214d61..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -/** - * Retry logic to use for the {@link LoadBalancerClient}. - * - * @author Ryan Baxter - * @author Olga Maciaszek-Sharma - */ -public interface LoadBalancedRetryPolicy { - - /** - * Return true to retry the failed request on the same server. This method may be - * called more than once when executing a single operation. - * @param context The context for the retry operation. - * @return True to retry the failed request on the same server; false otherwise. - */ - boolean canRetrySameServer(LoadBalancedRetryContext context); - - /** - * Return true to retry the failed request on the next server from the load balancer. - * This method may be called more than once when executing a single operation. - * @param context The context for the retry operation. - * @return True to retry the failed request on the next server from the load balancer; - * false otherwise. - */ - boolean canRetryNextServer(LoadBalancedRetryContext context); - - /** - * Called when the retry operation has ended. - * @param context The context for the retry operation. - */ - void close(LoadBalancedRetryContext context); - - /** - * Called when the execution fails. - * @param context The context for the retry operation. - * @param throwable The throwable from the failed execution. - */ - void registerThrowable(LoadBalancedRetryContext context, Throwable throwable); - - /** - * If an exception is not thrown when making a request, this method will be called to - * see if the client would like to retry the request based on the status code - * returned. For example, in Cloud Foundry, the router will return a 404 - * when an app is not available. Since HTTP clients do not throw an exception when a - * 404 is returned, retryableStatusCode allows clients to - * force a retry. - * @param statusCode The HTTP status code. - * @return True if a retry should be attempted; false to just return the response. - */ - boolean retryableStatusCode(int statusCode); - - /** - * Return true to retry if the provided exception is thrown. - * @param exception the {@link Throwable} to evaluate - * @return true to retry on the provided exception - */ - boolean retryableException(Throwable exception); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java deleted file mode 100644 index 7fdc57da..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfiguration.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.SmartInitializingSingleton; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -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.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.client.RestTemplate; - -/** - * Auto-configuration for blocking client-side load balancing. - * - * @author Spencer Gibb - * @author Dave Syer - * @author Will Tran - * @author Gang Li - * @author Olga Maciaszek-Sharma - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(RestTemplate.class) -@ConditionalOnBean(LoadBalancerClient.class) -@EnableConfigurationProperties(LoadBalancerClientsProperties.class) -public class LoadBalancerAutoConfiguration { - - @LoadBalanced - @Autowired(required = false) - private List restTemplates = Collections.emptyList(); - - @Autowired(required = false) - private List transformers = Collections.emptyList(); - - @Bean - public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated( - final ObjectProvider> restTemplateCustomizers) { - return () -> restTemplateCustomizers.ifAvailable(customizers -> { - for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) { - for (RestTemplateCustomizer customizer : customizers) { - customizer.customize(restTemplate); - } - } - }); - } - - @Bean - @ConditionalOnMissingBean - public LoadBalancerRequestFactory loadBalancerRequestFactory(LoadBalancerClient loadBalancerClient) { - return new LoadBalancerRequestFactory(loadBalancerClient, this.transformers); - } - - @Configuration(proxyBeanMethods = false) - @Conditional(RetryMissingOrDisabledCondition.class) - static class LoadBalancerInterceptorConfig { - - @Bean - public LoadBalancerInterceptor loadBalancerInterceptor(LoadBalancerClient loadBalancerClient, - LoadBalancerRequestFactory requestFactory) { - return new LoadBalancerInterceptor(loadBalancerClient, requestFactory); - } - - @Bean - @ConditionalOnMissingBean - public RestTemplateCustomizer restTemplateCustomizer(final LoadBalancerInterceptor loadBalancerInterceptor) { - return restTemplate -> { - List list = new ArrayList<>(restTemplate.getInterceptors()); - list.add(loadBalancerInterceptor); - restTemplate.setInterceptors(list); - }; - } - - } - - private static class RetryMissingOrDisabledCondition extends AnyNestedCondition { - - RetryMissingOrDisabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate") - static class RetryTemplateMissing { - - } - - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "false") - static class RetryDisabled { - - } - - } - - /** - * Auto configuration for retry mechanism. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(RetryTemplate.class) - public static class RetryAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public LoadBalancedRetryFactory loadBalancedRetryFactory() { - return new LoadBalancedRetryFactory() { - }; - } - - } - - /** - * Auto configuration for retry intercepting mechanism. - */ - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(RetryTemplate.class) - @ConditionalOnBean(ReactiveLoadBalancer.Factory.class) - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", matchIfMissing = true) - public static class RetryInterceptorAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public RetryLoadBalancerInterceptor loadBalancerInterceptor(LoadBalancerClient loadBalancerClient, - LoadBalancerRequestFactory requestFactory, LoadBalancedRetryFactory loadBalancedRetryFactory, - ReactiveLoadBalancer.Factory loadBalancerFactory) { - return new RetryLoadBalancerInterceptor(loadBalancerClient, requestFactory, loadBalancedRetryFactory, - loadBalancerFactory); - } - - @Bean - @ConditionalOnMissingBean - public RestTemplateCustomizer restTemplateCustomizer( - final RetryLoadBalancerInterceptor loadBalancerInterceptor) { - return restTemplate -> { - List list = new ArrayList<>(restTemplate.getInterceptors()); - list.add(loadBalancerInterceptor); - restTemplate.setInterceptors(list); - }; - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClient.java deleted file mode 100644 index 33ac91c1..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClient.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.IOException; -import java.net.URI; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * Represents a client-side load balancer. - * - * @author Spencer Gibb - */ -public interface LoadBalancerClient extends ServiceInstanceChooser { - - /** - * Executes request using a ServiceInstance from the LoadBalancer for the specified - * service. - * @param serviceId The service ID to look up the LoadBalancer. - * @param request Allows implementations to execute pre and post actions, such as - * incrementing metrics. - * @param type of the response - * @throws IOException in case of IO issues. - * @return The result of the LoadBalancerRequest callback on the selected - * ServiceInstance. - */ - T execute(String serviceId, LoadBalancerRequest request) throws IOException; - - /** - * Executes request using a ServiceInstance from the LoadBalancer for the specified - * service. - * @param serviceId The service ID to look up the LoadBalancer. - * @param serviceInstance The service to execute the request to. - * @param request Allows implementations to execute pre and post actions, such as - * incrementing metrics. - * @param type of the response - * @throws IOException in case of IO issues. - * @return The result of the LoadBalancerRequest callback on the selected - * ServiceInstance. - */ - T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) throws IOException; - - /** - * Creates a proper URI with a real host and port for systems to utilize. Some systems - * use a URI with the logical service name as the host, such as - * http://myservice/path/to/service. This will replace the service name with the - * host:port from the ServiceInstance. - * @param instance service instance to reconstruct the URI - * @param original A URI with the host as a logical service name. - * @return A reconstructed URI. - */ - URI reconstructURI(ServiceInstance instance, URI original); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClientsProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClientsProperties.java deleted file mode 100644 index 24082985..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerClientsProperties.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * A {@link ConfigurationProperties} bean for Spring Cloud Loadbalancer. - * - * Individual clients are configured via the {@link LoadBalancerClientsProperties#clients} - * field. Defaults and other properties are located in the {@link LoadBalancerProperties} - * base class. - * - * @author Spencer Gibb - * @since 3.1.0 - */ -@ConfigurationProperties("spring.cloud.loadbalancer") -public class LoadBalancerClientsProperties extends LoadBalancerProperties { - - private Map clients = new HashMap<>(); - - public Map getClients() { - return this.clients; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerDefaultMappingsProviderAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerDefaultMappingsProviderAutoConfiguration.java deleted file mode 100644 index 501f1c4b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerDefaultMappingsProviderAutoConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.context.properties.source.ConfigurationPropertyName; -import org.springframework.cloud.commons.config.DefaultsBindHandlerAdvisor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - * @since 3.1.0 - */ -@Configuration(proxyBeanMethods = false) -@AutoConfigureBefore(name = "org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration") -public class LoadBalancerDefaultMappingsProviderAutoConfiguration { - - @Bean - public DefaultsBindHandlerAdvisor.MappingsProvider loadBalancerClientsDefaultsMappingsProvider() { - return () -> { - Map mappings = new HashMap<>(); - mappings.put(ConfigurationPropertyName.of("spring.cloud.loadbalancer.clients"), - ConfigurationPropertyName.of("spring.cloud.loadbalancer")); - return mappings; - }; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerEagerLoadProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerEagerLoadProperties.java deleted file mode 100644 index d99c0d8e..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerEagerLoadProperties.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Andrii Bohutskyi - */ -@ConfigurationProperties("spring.cloud.loadbalancer.eager-load") -public class LoadBalancerEagerLoadProperties { - - private List clients = new ArrayList<>(); - - public List getClients() { - return clients; - } - - public void setClients(List clients) { - this.clients = clients; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerInterceptor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerInterceptor.java deleted file mode 100644 index 06db38a9..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerInterceptor.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.IOException; -import java.net.URI; - -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.Assert; - -/** - * @author Spencer Gibb - * @author Dave Syer - * @author Ryan Baxter - * @author William Tran - */ -public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor { - - private LoadBalancerClient loadBalancer; - - private LoadBalancerRequestFactory requestFactory; - - public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) { - this.loadBalancer = loadBalancer; - this.requestFactory = requestFactory; - } - - public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) { - // for backwards compatibility - this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer)); - } - - @Override - public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, - final ClientHttpRequestExecution execution) throws IOException { - final URI originalUri = request.getURI(); - String serviceName = originalUri.getHost(); - Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri); - return this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution)); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycle.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycle.java deleted file mode 100644 index 4ba9240b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycle.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -/** - * Allows to define actions that should be carried out before and after load-balancing. - * - * @author Olga Maciaszek-Sharma - */ -public interface LoadBalancerLifecycle { - - /** - * Allows to assess whether the lifecycle bean's callbacks should be executed. Some - * examples of possible implementations could comprise of verifying whether the - * classes passed in parameters are exactly or extend the classes that this lifecycle - * bean should process. - * @param requestContextClass The class of the {@link Request} context - * @param responseClass The class of the {@link CompletionContext} - * clientResponse - * @param serverTypeClass The type of Server that the LoadBalancer retrieves - * @return true if the lifecycle should be used to process given classes - */ - default boolean supports(Class requestContextClass, Class responseClass, Class serverTypeClass) { - return true; - } - - /** - * A callback method executed before load-balancing. - * @param request the {@link Request} that will be used by the LoadBalancer to select - * a service instance - */ - void onStart(Request request); - - /** - * A callback method executed after a service instance has been selected, before - * executing the actual load-balanced request. - * @param request the {@link Request} that has been used by the LoadBalancer to select - * a service instance - * @param lbResponse the {@link Response} returned by the LoadBalancer - */ - void onStartRequest(Request request, Response lbResponse); - - /** - * A callback method executed after load-balancing. - * @param completionContext the {@link CompletionContext} containing data relevant to - * the load-balancing and the response returned from the selected service instance - */ - void onComplete(CompletionContext completionContext); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycleValidator.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycleValidator.java deleted file mode 100644 index b51c81f4..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerLifecycleValidator.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Utility class containing methods that allow to filter out supported - * {@link LoadBalancerLifecycle} beans. - * - * @author Olga Maciaszek-Sharma - * @since 3.0 - */ -public final class LoadBalancerLifecycleValidator { - - private LoadBalancerLifecycleValidator() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - @SuppressWarnings("rawtypes") - public static Set getSupportedLifecycleProcessors( - Map lifecycleProcessors, Class requestContextClass, - Class clientResponseClass, Class serverTypeClass) { - if (lifecycleProcessors == null) { - return new HashSet<>(); - } - return lifecycleProcessors.values().stream() - .filter(lifecycle -> lifecycle.supports(requestContextClass, clientResponseClass, serverTypeClass)) - .collect(Collectors.toSet()); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java deleted file mode 100644 index dd93f89a..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.IOException; -import java.time.Duration; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeoutException; - -import reactor.util.retry.RetryBackoffSpec; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpMethod; -import org.springframework.util.LinkedCaseInsensitiveMap; - -/** - * The base configuration bean for Spring Cloud LoadBalancer. - * - * See {@link LoadBalancerClientsProperties} for the {@link ConfigurationProperties} - * annotation. - * - * @author Olga Maciaszek-Sharma - * @author Gandhimathi Velusamy - * @since 2.2.1 - */ -public class LoadBalancerProperties { - - /** - * Properties for HealthCheckServiceInstanceListSupplier. - */ - private HealthCheck healthCheck = new HealthCheck(); - - /** - * Allows setting the value of hint that is passed on to the LoadBalancer - * request and can subsequently be used in {@link ReactiveLoadBalancer} - * implementations. - */ - private Map hint = new LinkedCaseInsensitiveMap<>(); - - /** - * Allows setting the name of the header used for passing the hint for hint-based - * service instance filtering. - */ - private String hintHeaderName = "X-SC-LB-Hint"; - - /** - * Properties for Spring-Retry and Reactor Retry support in Spring Cloud LoadBalancer. - */ - private Retry retry = new Retry(); - - /** - * Properties for LoadBalancer sticky-session. - */ - private StickySession stickySession = new StickySession(); - - /** - * If this flag is set to {@code true}, - * {@code ServiceInstanceListSupplier#get(Request request)} method will be implemented - * to call {@code delegate.get(request)} in classes assignable from - * {@code DelegatingServiceInstanceListSupplier} that don't already implement that - * method, with the exclusion of {@code CachingServiceInstanceListSupplier} and - * {@code HealthCheckServiceInstanceListSupplier}, which should be placed in the - * instance supplier hierarchy directly after the supplier performing instance - * retrieval over the network, before any request-based filtering is done, - * {@code true} by default. - */ - private boolean callGetWithRequestOnDelegates = true; - - public HealthCheck getHealthCheck() { - return healthCheck; - } - - public void setHealthCheck(HealthCheck healthCheck) { - this.healthCheck = healthCheck; - } - - public Map getHint() { - return hint; - } - - public void setHint(Map hint) { - this.hint = hint; - } - - public Retry getRetry() { - return retry; - } - - public void setRetry(Retry retry) { - this.retry = retry; - } - - public StickySession getStickySession() { - return stickySession; - } - - public void setStickySession(StickySession stickySession) { - this.stickySession = stickySession; - } - - public String getHintHeaderName() { - return hintHeaderName; - } - - public void setHintHeaderName(String hintHeaderName) { - this.hintHeaderName = hintHeaderName; - } - - /** - * Enabling X-Forwarded Host and Proto Headers. - */ - private XForwarded xForwarded = new XForwarded(); - - public void setxForwarded(XForwarded xForwarded) { - this.xForwarded = xForwarded; - } - - public XForwarded getXForwarded() { - return xForwarded; - } - - public boolean isCallGetWithRequestOnDelegates() { - return callGetWithRequestOnDelegates; - } - - public void setCallGetWithRequestOnDelegates(boolean callGetWithRequestOnDelegates) { - this.callGetWithRequestOnDelegates = callGetWithRequestOnDelegates; - } - - public static class StickySession { - - /** - * The name of the cookie holding the preferred instance id. - */ - private String instanceIdCookieName = "sc-lb-instance-id"; - - /** - * Indicates whether a cookie with the newly selected instance should be added by - * SC LoadBalancer. - */ - private boolean addServiceInstanceCookie = false; - - public String getInstanceIdCookieName() { - return instanceIdCookieName; - } - - public void setInstanceIdCookieName(String instanceIdCookieName) { - this.instanceIdCookieName = instanceIdCookieName; - } - - public boolean isAddServiceInstanceCookie() { - return addServiceInstanceCookie; - } - - public void setAddServiceInstanceCookie(boolean addServiceInstanceCookie) { - this.addServiceInstanceCookie = addServiceInstanceCookie; - } - - } - - public static class XForwarded { - - /** - * To Enable X-Forwarded Headers. - */ - private boolean enabled = false; - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - } - - public static class HealthCheck { - - /** - * Initial delay value for the HealthCheck scheduler. - */ - private Duration initialDelay = Duration.ZERO; - - /** - * Interval for rerunning the HealthCheck scheduler. - */ - private Duration interval = Duration.ofSeconds(25); - - /** - * Interval for refetching available service instances. - */ - private Duration refetchInstancesInterval = Duration.ofSeconds(25); - - /** - * Path at which the health-check request should be made. Can be set up per - * serviceId. A default value can be set up as well. If - * none is set up, /actuator/health will be used. - */ - private Map path = new LinkedCaseInsensitiveMap<>(); - - /** - * Port at which the health-check request should be made. If none is set, the port - * under which the requested service is available at the service instance. - */ - private Integer port; - - /** - * Indicates whether the instances should be refetched by the - * HealthCheckServiceInstanceListSupplier. This can be used if the - * instances can be updated and the underlying delegate does not provide an - * ongoing flux. - */ - private boolean refetchInstances = false; - - /** - * Indicates whether health checks should keep repeating. It might be useful to - * set it to false if periodically refetching the instances, as every - * refetch will also trigger a healthcheck. - */ - private boolean repeatHealthCheck = true; - - /** - * Indicates whether the {@code healthCheckFlux} should emit on each alive - * {@link ServiceInstance} that has been retrieved. If set to {@code false}, the - * entire alive instances sequence is first collected into a list and only then - * emitted. - */ - private boolean updateResultsList = true; - - public boolean getRefetchInstances() { - return refetchInstances; - } - - public void setRefetchInstances(boolean refetchInstances) { - this.refetchInstances = refetchInstances; - } - - public boolean getRepeatHealthCheck() { - return repeatHealthCheck; - } - - public void setRepeatHealthCheck(boolean repeatHealthCheck) { - this.repeatHealthCheck = repeatHealthCheck; - } - - public Duration getInitialDelay() { - return initialDelay; - } - - public void setInitialDelay(Duration initialDelay) { - this.initialDelay = initialDelay; - } - - public Duration getRefetchInstancesInterval() { - return refetchInstancesInterval; - } - - public void setRefetchInstancesInterval(Duration refetchInstancesInterval) { - this.refetchInstancesInterval = refetchInstancesInterval; - } - - public Map getPath() { - return path; - } - - public void setPath(Map path) { - this.path = path; - } - - public Duration getInterval() { - return interval; - } - - public void setInterval(Duration interval) { - this.interval = interval; - } - - public Integer getPort() { - return port; - } - - public void setPort(Integer port) { - this.port = port; - } - - public boolean isUpdateResultsList() { - return updateResultsList; - } - - public void setUpdateResultsList(boolean updateResultsList) { - this.updateResultsList = updateResultsList; - } - - } - - public static class Retry { - - private boolean enabled = true; - - /** - * Indicates retries should be attempted on operations other than - * {@link HttpMethod#GET}. - */ - private boolean retryOnAllOperations = false; - - /** - * Indicates retries should be attempted for all exceptions, not only those - * specified in {@code retryableExceptions}. - */ - private boolean retryOnAllExceptions = false; - - /** - * Number of retries to be executed on the same ServiceInstance. - */ - private int maxRetriesOnSameServiceInstance = 0; - - /** - * Number of retries to be executed on the next ServiceInstance. A - * ServiceInstance is chosen before each retry call. - */ - private int maxRetriesOnNextServiceInstance = 1; - - /** - * A {@link Set} of status codes that should trigger a retry. - */ - private Set retryableStatusCodes = new HashSet<>(); - - /** - * A {@link Set} of {@link Throwable} classes that should trigger a retry. - */ - private Set> retryableExceptions = new HashSet<>( - Arrays.asList(IOException.class, TimeoutException.class, RetryableStatusCodeException.class, - org.springframework.cloud.client.loadbalancer.reactive.RetryableStatusCodeException.class)); - - /** - * Properties for Reactor Retry backoffs in Spring Cloud LoadBalancer. - */ - private Backoff backoff = new Backoff(); - - /** - * Returns true if the load balancer should retry failed requests. - * @return True if the load balancer should retry failed requests; false - * otherwise. - */ - public boolean isEnabled() { - return this.enabled; - } - - /** - * Sets whether the load balancer should retry failed requests. - * @param enabled Whether the load balancer should retry failed requests. - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isRetryOnAllOperations() { - return retryOnAllOperations; - } - - public void setRetryOnAllOperations(boolean retryOnAllOperations) { - this.retryOnAllOperations = retryOnAllOperations; - } - - public int getMaxRetriesOnSameServiceInstance() { - return maxRetriesOnSameServiceInstance; - } - - public void setMaxRetriesOnSameServiceInstance(int maxRetriesOnSameServiceInstance) { - this.maxRetriesOnSameServiceInstance = maxRetriesOnSameServiceInstance; - } - - public int getMaxRetriesOnNextServiceInstance() { - return maxRetriesOnNextServiceInstance; - } - - public void setMaxRetriesOnNextServiceInstance(int maxRetriesOnNextServiceInstance) { - this.maxRetriesOnNextServiceInstance = maxRetriesOnNextServiceInstance; - } - - public Set getRetryableStatusCodes() { - return retryableStatusCodes; - } - - public void setRetryableStatusCodes(Set retryableStatusCodes) { - this.retryableStatusCodes = retryableStatusCodes; - } - - public Set> getRetryableExceptions() { - return retryableExceptions; - } - - public void setRetryableExceptions(Set> retryableExceptions) { - retryableExceptions - .add(org.springframework.cloud.client.loadbalancer.reactive.RetryableStatusCodeException.class); - this.retryableExceptions = retryableExceptions; - } - - public Backoff getBackoff() { - return backoff; - } - - public void setBackoff(Backoff backoff) { - this.backoff = backoff; - } - - public boolean isRetryOnAllExceptions() { - return retryOnAllExceptions; - } - - public void setRetryOnAllExceptions(boolean retryOnAllExceptions) { - this.retryOnAllExceptions = retryOnAllExceptions; - } - - public static class Backoff { - - /** - * Indicates whether Reactor Retry backoffs should be applied. - */ - private boolean enabled = false; - - /** - * Used to set {@link RetryBackoffSpec#minBackoff}. - */ - private Duration minBackoff = Duration.ofMillis(5); - - /** - * Used to set {@link RetryBackoffSpec#maxBackoff}. - */ - private Duration maxBackoff = Duration.ofMillis(Long.MAX_VALUE); - - /** - * Used to set {@link RetryBackoffSpec#jitter}. - */ - private double jitter = 0.5d; - - public Duration getMinBackoff() { - return minBackoff; - } - - public void setMinBackoff(Duration minBackoff) { - this.minBackoff = minBackoff; - } - - public Duration getMaxBackoff() { - return maxBackoff; - } - - public void setMaxBackoff(Duration maxBackoff) { - this.maxBackoff = maxBackoff; - } - - public double getJitter() { - return jitter; - } - - public void setJitter(double jitter) { - this.jitter = jitter; - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequest.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequest.java deleted file mode 100644 index 52a0fe3e..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * Simple interface used by LoadBalancerClient to apply metrics or pre and post actions - * around load balancer requests. - * - * @param type of the response - * @author Spencer Gibb - */ -public interface LoadBalancerRequest { - - T apply(ServiceInstance instance) throws Exception; - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestAdapter.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestAdapter.java deleted file mode 100644 index 038ffa75..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestAdapter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * An adapter class that allows creating {@link Request} objects from previously - * {@link LoadBalancerRequest} objects. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class LoadBalancerRequestAdapter extends DefaultRequest implements LoadBalancerRequest { - - private final LoadBalancerRequest delegate; - - public LoadBalancerRequestAdapter(LoadBalancerRequest delegate) { - this.delegate = delegate; - } - - public LoadBalancerRequestAdapter(LoadBalancerRequest delegate, RC context) { - super(context); - this.delegate = delegate; - } - - @Override - public T apply(ServiceInstance instance) throws Exception { - return delegate.apply(instance); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactory.java deleted file mode 100644 index b8a06fbb..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; - -/** - * Creates {@link LoadBalancerRequest}s for {@link LoadBalancerInterceptor} and - * {@link RetryLoadBalancerInterceptor}. Applies {@link LoadBalancerRequestTransformer}s - * to the intercepted {@link HttpRequest}. - * - * @author William Tran - * @author Olga Maciaszek-Sharma - * - */ -public class LoadBalancerRequestFactory { - - private final LoadBalancerClient loadBalancer; - - private final List transformers; - - public LoadBalancerRequestFactory(LoadBalancerClient loadBalancer, - List transformers) { - this.loadBalancer = loadBalancer; - this.transformers = transformers; - } - - public LoadBalancerRequestFactory(LoadBalancerClient loadBalancer) { - this.loadBalancer = loadBalancer; - transformers = new ArrayList<>(); - } - - public LoadBalancerRequest createRequest(final HttpRequest request, final byte[] body, - final ClientHttpRequestExecution execution) { - return new BlockingLoadBalancerRequest(loadBalancer, transformers, - new BlockingLoadBalancerRequest.ClientHttpRequestData(request, body, execution)); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestTransformer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestTransformer.java deleted file mode 100644 index 3efa567c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestTransformer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpRequest; - -/** - * Allows applications to transform the load-balanced {@link HttpRequest} given the chosen - * {@link ServiceInstance}. - * - * @author Will Tran - */ -@Order(LoadBalancerRequestTransformer.DEFAULT_ORDER) -public interface LoadBalancerRequestTransformer { - - /** - * Order for the load balancer request tranformer. - */ - int DEFAULT_ORDER = 0; - - HttpRequest transformRequest(HttpRequest request, ServiceInstance instance); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java deleted file mode 100644 index 63779ac2..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriTools.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.net.URI; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -public final class LoadBalancerUriTools { - - private LoadBalancerUriTools() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - private static final String PERCENTAGE_SIGN = "%"; - - private static final String DEFAULT_SCHEME = "http"; - - private static final String DEFAULT_SECURE_SCHEME = "https"; - - private static final Map INSECURE_SCHEME_MAPPINGS; - - static { - INSECURE_SCHEME_MAPPINGS = new HashMap<>(); - INSECURE_SCHEME_MAPPINGS.put(DEFAULT_SCHEME, DEFAULT_SECURE_SCHEME); - INSECURE_SCHEME_MAPPINGS.put("ws", "wss"); - } - - // see original - // https://github.com/spring-cloud/spring-cloud-gateway/blob/main/spring-cloud-gateway-core/ - // src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java - private static boolean containsEncodedParts(URI uri) { - boolean encoded = (uri.getRawQuery() != null && uri.getRawQuery().contains(PERCENTAGE_SIGN)) - || (uri.getRawPath() != null && uri.getRawPath().contains(PERCENTAGE_SIGN)) - || (uri.getRawFragment() != null && uri.getRawFragment().contains(PERCENTAGE_SIGN)); - // Verify if it is really fully encoded. Treat partial encoded as unencoded. - if (encoded) { - try { - UriComponentsBuilder.fromUri(uri).build(true); - return true; - } - catch (IllegalArgumentException ignore) { - } - return false; - } - return false; - } - - private static int computePort(int port, String scheme) { - if (port >= 0) { - return port; - } - if (Objects.equals(scheme, DEFAULT_SECURE_SCHEME)) { - return 443; - } - return 80; - } - - /** - * Modifies the URI in order to redirect the request to a service instance of choice. - * @param serviceInstance the {@link ServiceInstance} to redirect the request to. - * @param original the {@link URI} from the original request - * @return the modified {@link URI} - */ - public static URI reconstructURI(ServiceInstance serviceInstance, URI original) { - if (serviceInstance == null) { - throw new IllegalArgumentException("Service Instance cannot be null."); - } - return doReconstructURI(serviceInstance, original); - } - - private static URI doReconstructURI(ServiceInstance serviceInstance, URI original) { - String host = serviceInstance.getHost(); - String scheme = Optional.ofNullable(serviceInstance.getScheme()) - .orElse(computeScheme(original, serviceInstance)); - int port = computePort(serviceInstance.getPort(), scheme); - - if (Objects.equals(host, original.getHost()) && port == original.getPort() - && Objects.equals(scheme, original.getScheme())) { - return original; - } - - boolean encoded = containsEncodedParts(original); - return UriComponentsBuilder.fromUri(original).scheme(scheme).host(host).port(port).build(encoded).toUri(); - } - - private static String computeScheme(URI original, ServiceInstance serviceInstance) { - String originalOrDefault = Optional.ofNullable(original.getScheme()).orElse(DEFAULT_SCHEME); - if (serviceInstance.isSecure() && INSECURE_SCHEME_MAPPINGS.containsKey(originalOrDefault)) { - return INSECURE_SCHEME_MAPPINGS.get(originalOrDefault); - } - return originalOrDefault; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Request.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Request.java deleted file mode 100644 index f0657956..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Request.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -/** - * Marker interface for a request. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -public interface Request { - - // Avoid breaking backward compatibility - default C getContext() { - return null; - } - - // TODO: define contents - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestData.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestData.java deleted file mode 100644 index bd666d2b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestData.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.net.URI; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import org.springframework.core.style.ToStringCreator; -import org.springframework.http.HttpCookie; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.client.ClientRequest; - -/** - * Represents the data of the request that can be safely read (without passing request - * reactive stream values). - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class RequestData { - - private final HttpMethod httpMethod; - - private final URI url; - - private final HttpHeaders headers; - - private final MultiValueMap cookies; - - private final Map attributes; - - public RequestData(HttpMethod httpMethod, URI url, HttpHeaders headers, MultiValueMap cookies, - Map attributes) { - this.httpMethod = httpMethod; - this.url = url; - this.headers = headers; - this.cookies = cookies; - this.attributes = attributes; - } - - public RequestData(ClientRequest request) { - this(request.method(), request.url(), request.headers(), request.cookies(), request.attributes()); - } - - public RequestData(HttpRequest request) { - this(request.getMethod(), request.getURI(), request.getHeaders(), buildCookiesFromHeaders(request.getHeaders()), - new HashMap<>()); - } - - public RequestData(ServerHttpRequest request) { - this(request.getMethod(), request.getURI(), request.getHeaders(), buildCookies(request.getCookies()), - new HashMap<>()); - } - - public RequestData(ServerHttpRequest request, Map attributes) { - this(request.getMethod(), request.getURI(), request.getHeaders(), buildCookies(request.getCookies()), - attributes); - } - - private static MultiValueMap buildCookies(MultiValueMap cookies) { - HttpHeaders newCookies = new HttpHeaders(); - if (cookies != null) { - cookies.forEach((key, value) -> value - .forEach(cookie -> newCookies.put(cookie.getName(), Collections.singletonList(cookie.getValue())))); - } - return newCookies; - } - - private static MultiValueMap buildCookiesFromHeaders(HttpHeaders headers) { - HttpHeaders newCookies = new HttpHeaders(); - if (headers == null) { - return newCookies; - } - List cookiesFromHeaders = headers.get(HttpHeaders.COOKIE); - if (cookiesFromHeaders != null) { - cookiesFromHeaders.forEach(cookie -> { - String[] splitCookie = cookie.split("="); - if (splitCookie.length < 2) { - return; - } - newCookies.put(splitCookie[0], Collections.singletonList(splitCookie[1])); - }); - } - return newCookies; - } - - public HttpMethod getHttpMethod() { - return httpMethod; - } - - public URI getUrl() { - return url; - } - - public HttpHeaders getHeaders() { - return headers; - } - - public MultiValueMap getCookies() { - return cookies; - } - - public Map getAttributes() { - return attributes; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("httpMethod", httpMethod); - to.append("url", url); - to.append("headers", headers); - to.append("cookies", cookies); - return to.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof RequestData that)) { - return false; - } - return httpMethod == that.httpMethod && Objects.equals(url, that.url) && Objects.equals(headers, that.headers) - && Objects.equals(cookies, that.cookies) && Objects.equals(attributes, that.attributes); - } - - @Override - public int hashCode() { - return Objects.hash(httpMethod, url, headers, cookies, attributes); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestDataContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestDataContext.java deleted file mode 100644 index 6bb23dee..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RequestDataContext.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.http.HttpMethod; - -/** - * A {@link RequestData}-based {@link DefaultRequestContext}. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class RequestDataContext extends DefaultRequestContext { - - public RequestDataContext() { - super(); - } - - public RequestDataContext(RequestData requestData) { - this(requestData, "default"); - } - - public RequestDataContext(RequestData requestData, String hint) { - super(requestData, hint); - } - - public RequestData getClientRequest() { - return (RequestData) super.getClientRequest(); - } - - public HttpMethod method() { - return ((RequestData) super.getClientRequest()).getHttpMethod(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Response.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Response.java deleted file mode 100644 index a598f133..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/Response.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -/** - * Response created for each request. - * - * @param type of the server - * @author Spencer Gibb - */ -public interface Response { - - boolean hasServer(); - - T getServer(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ResponseData.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ResponseData.java deleted file mode 100644 index 34aa98e1..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ResponseData.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.Objects; - -import org.springframework.core.style.ToStringCreator; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatusCode; -import org.springframework.http.ResponseCookie; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.client.ClientResponse; - -/** - * Represents the data of the request that can be safely read (without passing request - * reactive stream values). - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class ResponseData { - - private final HttpStatusCode httpStatus; - - private final HttpHeaders headers; - - private final MultiValueMap cookies; - - private final RequestData requestData; - - public ResponseData(HttpStatusCode httpStatus, HttpHeaders headers, MultiValueMap cookies, - RequestData requestData) { - this.httpStatus = httpStatus; - this.headers = headers; - this.cookies = cookies; - this.requestData = requestData; - } - - public ResponseData(ClientResponse response, RequestData requestData) { - this(response.statusCode(), response.headers().asHttpHeaders(), response.cookies(), requestData); - } - - public ResponseData(ServerHttpResponse response, RequestData requestData) { - this(response.getStatusCode(), response.getHeaders(), response.getCookies(), requestData); - } - - public ResponseData(ClientHttpResponse clientHttpResponse, RequestData requestData) throws IOException { - this(clientHttpResponse.getStatusCode(), clientHttpResponse.getHeaders(), - buildCookiesFromHeaders(clientHttpResponse.getHeaders()), requestData); - } - - public HttpStatusCode getHttpStatus() { - return httpStatus; - } - - public HttpHeaders getHeaders() { - return headers; - } - - public MultiValueMap getCookies() { - return cookies; - } - - public RequestData getRequestData() { - return requestData; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("httpStatus", httpStatus); - return to.toString(); - } - - static MultiValueMap buildCookiesFromHeaders(HttpHeaders headers) { - LinkedMultiValueMap newCookies = new LinkedMultiValueMap<>(); - if (headers == null) { - return newCookies; - } - List cookiesFromHeaders = headers.get(HttpHeaders.COOKIE); - if (cookiesFromHeaders != null) { - cookiesFromHeaders.forEach(cookie -> { - String[] splitCookie = cookie.split("="); - if (splitCookie.length < 2) { - return; - } - newCookies.put(splitCookie[0], - Collections.singletonList(ResponseCookie.from(splitCookie[0], splitCookie[1]).build())); - }); - } - return newCookies; - } - - @Override - public int hashCode() { - return Objects.hash(httpStatus, headers, cookies, requestData); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof ResponseData that)) { - return false; - } - return httpStatus == that.httpStatus && Objects.equals(headers, that.headers) - && Objects.equals(cookies, that.cookies) && Objects.equals(requestData, that.requestData); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RestTemplateCustomizer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RestTemplateCustomizer.java deleted file mode 100644 index 7ffe0fec..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RestTemplateCustomizer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.web.client.RestTemplate; - -/** - * @author Spencer Gibb - */ -public interface RestTemplateCustomizer { - - void customize(RestTemplate restTemplate); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptor.java deleted file mode 100644 index 91a076a6..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptor.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.IOException; -import java.net.URI; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -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.util.Assert; -import org.springframework.util.StreamUtils; - -/** - * @author Ryan Baxter - * @author Will Tran - * @author Gang Li - * @author Olga Maciaszek-Sharma - */ -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class RetryLoadBalancerInterceptor implements ClientHttpRequestInterceptor { - - private static final Log LOG = LogFactory.getLog(RetryLoadBalancerInterceptor.class); - - private final LoadBalancerClient loadBalancer; - - private final LoadBalancerRequestFactory requestFactory; - - private final LoadBalancedRetryFactory lbRetryFactory; - - private final ReactiveLoadBalancer.Factory loadBalancerFactory; - - public RetryLoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory, - LoadBalancedRetryFactory lbRetryFactory, - ReactiveLoadBalancer.Factory loadBalancerFactory) { - this.loadBalancer = loadBalancer; - this.requestFactory = requestFactory; - this.lbRetryFactory = lbRetryFactory; - this.loadBalancerFactory = loadBalancerFactory; - } - - @Override - public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, - final ClientHttpRequestExecution execution) throws IOException { - final URI originalUri = request.getURI(); - final String serviceName = originalUri.getHost(); - Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri); - final LoadBalancedRetryPolicy retryPolicy = lbRetryFactory.createRetryPolicy(serviceName, loadBalancer); - RetryTemplate template = createRetryTemplate(serviceName, request, retryPolicy); - return template.execute(context -> { - ServiceInstance serviceInstance = null; - if (context instanceof LoadBalancedRetryContext lbContext) { - serviceInstance = lbContext.getServiceInstance(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Retrieved service instance from LoadBalancedRetryContext: %s", - serviceInstance)); - } - } - Set supportedLifecycleProcessors = LoadBalancerLifecycleValidator - .getSupportedLifecycleProcessors( - loadBalancerFactory.getInstances(serviceName, LoadBalancerLifecycle.class), - RetryableRequestContext.class, ResponseData.class, ServiceInstance.class); - String hint = getHint(serviceName); - if (serviceInstance == null) { - if (LOG.isDebugEnabled()) { - LOG.debug("Service instance retrieved from LoadBalancedRetryContext: was null. " - + "Reattempting service instance selection"); - } - ServiceInstance previousServiceInstance = null; - if (context instanceof LoadBalancedRetryContext lbContext) { - previousServiceInstance = lbContext.getPreviousServiceInstance(); - } - DefaultRequest lbRequest = new DefaultRequest<>( - new RetryableRequestContext(previousServiceInstance, new RequestData(request), hint)); - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest)); - serviceInstance = loadBalancer.choose(serviceName, lbRequest); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Selected service instance: %s", serviceInstance)); - } - if (context instanceof LoadBalancedRetryContext lbContext) { - lbContext.setServiceInstance(serviceInstance); - } - Response lbResponse = new DefaultResponse(serviceInstance); - if (serviceInstance == null) { - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle - .onComplete(new CompletionContext( - CompletionContext.Status.DISCARD, - new DefaultRequest<>( - new RetryableRequestContext(null, new RequestData(request), hint)), - lbResponse))); - } - } - LoadBalancerRequestAdapter lbRequest = new LoadBalancerRequestAdapter<>( - requestFactory.createRequest(request, body, execution), - new RetryableRequestContext(null, new RequestData(request), hint)); - ServiceInstance finalServiceInstance = serviceInstance; - ClientHttpResponse response = loadBalancer.execute(serviceName, finalServiceInstance, lbRequest); - int statusCode = response.getStatusCode().value(); - if (retryPolicy != null && retryPolicy.retryableStatusCode(statusCode)) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Retrying on status code: %d", statusCode)); - } - byte[] bodyCopy = StreamUtils.copyToByteArray(response.getBody()); - response.close(); - throw new ClientHttpResponseStatusCodeException(serviceName, response, bodyCopy); - } - return response; - }, new LoadBalancedRecoveryCallback() { - // This is a special case, where both parameters to - // LoadBalancedRecoveryCallback are - // the same. In most cases they would be different. - @Override - protected ClientHttpResponse createResponse(ClientHttpResponse response, URI uri) { - return response; - } - }); - } - - private RetryTemplate createRetryTemplate(String serviceName, HttpRequest request, - LoadBalancedRetryPolicy retryPolicy) { - RetryTemplate template = new RetryTemplate(); - BackOffPolicy backOffPolicy = lbRetryFactory.createBackOffPolicy(serviceName); - template.setBackOffPolicy(backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy); - template.setThrowLastExceptionOnExhausted(true); - RetryListener[] retryListeners = lbRetryFactory.createRetryListeners(serviceName); - if (retryListeners != null && retryListeners.length != 0) { - template.setListeners(retryListeners); - } - template.setRetryPolicy( - !loadBalancerFactory.getProperties(serviceName).getRetry().isEnabled() || retryPolicy == null - ? new NeverRetryPolicy() - : new InterceptorRetryPolicy(request, retryPolicy, loadBalancer, serviceName)); - return template; - } - - private String getHint(String serviceId) { - Map hint = loadBalancerFactory.getProperties(serviceId).getHint(); - String defaultHint = hint.getOrDefault("default", "default"); - String hintPropertyValue = hint.get(serviceId); - return hintPropertyValue != null ? hintPropertyValue : defaultHint; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableRequestContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableRequestContext.java deleted file mode 100644 index a796b1d2..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableRequestContext.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.Objects; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.style.ToStringCreator; - -/** - * A request context object that allows storing information on previously used service - * instances. - * - * @author Olga Maciaszek-Sharma - */ -public class RetryableRequestContext extends RequestDataContext { - - private ServiceInstance previousServiceInstance; - - public RetryableRequestContext(ServiceInstance previousServiceInstance) { - this.previousServiceInstance = previousServiceInstance; - } - - public RetryableRequestContext(ServiceInstance previousServiceInstance, RequestData clientRequestData) { - super(clientRequestData); - this.previousServiceInstance = previousServiceInstance; - } - - public RetryableRequestContext(ServiceInstance previousServiceInstance, RequestData clientRequestData, - String hint) { - super(clientRequestData, hint); - this.previousServiceInstance = previousServiceInstance; - } - - public ServiceInstance getPreviousServiceInstance() { - return previousServiceInstance; - } - - public void setPreviousServiceInstance(ServiceInstance previousServiceInstance) { - this.previousServiceInstance = previousServiceInstance; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("previousServiceInstance", previousServiceInstance); - return to.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof RetryableRequestContext context)) { - return false; - } - if (!super.equals(o)) { - return false; - } - return Objects.equals(previousServiceInstance, context.previousServiceInstance); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), previousServiceInstance); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableStatusCodeException.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableStatusCodeException.java deleted file mode 100644 index 78997822..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/RetryableStatusCodeException.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.IOException; -import java.net.URI; - -/** - * Exception to be thrown when the status code is deemed to be retryable. - * - * @author Ryan Baxter - */ -public class RetryableStatusCodeException extends IOException { - - private static final String MESSAGE = "Service %s returned a status code of %d"; - - private final Object response; - - private final URI uri; - - public RetryableStatusCodeException(String serviceId, int statusCode, Object response, URI uri) { - super(String.format(MESSAGE, serviceId, statusCode)); - this.response = response; - this.uri = uri; - } - - public Object getResponse() { - return this.response; - } - - public URI getUri() { - return this.uri; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceInstanceChooser.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceInstanceChooser.java deleted file mode 100644 index 6f90d33a..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceInstanceChooser.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * Implemented by classes which use a load balancer to choose a server to send a request - * to. - * - * @author Ryan Baxter - * @author Olga Maciaszek-Sharma - */ -public interface ServiceInstanceChooser { - - /** - * Chooses a ServiceInstance from the LoadBalancer for the specified service. - * @param serviceId The service ID to look up the LoadBalancer. - * @return A ServiceInstance that matches the serviceId. - */ - ServiceInstance choose(String serviceId); - - /** - * Chooses a ServiceInstance from the LoadBalancer for the specified service and - * LoadBalancer request. - * @param serviceId The service ID to look up the LoadBalancer. - * @param request The request to pass on to the LoadBalancer - * @param The type of the request context. - * @return A ServiceInstance that matches the serviceId. - */ - ServiceInstance choose(String serviceId, Request request); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceRequestWrapper.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceRequestWrapper.java deleted file mode 100644 index e3bdff0e..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/ServiceRequestWrapper.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.net.URI; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.support.HttpRequestWrapper; - -/** - * @author Ryan Baxter - */ -public class ServiceRequestWrapper extends HttpRequestWrapper { - - private final ServiceInstance instance; - - private final LoadBalancerClient loadBalancer; - - public ServiceRequestWrapper(HttpRequest request, ServiceInstance instance, LoadBalancerClient loadBalancer) { - super(request); - this.instance = instance; - this.loadBalancer = loadBalancer; - } - - @Override - public URI getURI() { - URI uri = this.loadBalancer.reconstructURI(this.instance, getRequest().getURI()); - return uri; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/TimedRequestContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/TimedRequestContext.java deleted file mode 100644 index 13f8eb90..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/TimedRequestContext.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -/** - * Allows setting and retrieving request start time. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public interface TimedRequestContext { - - long getRequestStartTime(); - - void setRequestStartTime(long requestStartTime); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/DeferringLoadBalancerExchangeFilterFunction.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/DeferringLoadBalancerExchangeFilterFunction.java deleted file mode 100644 index 4e419770..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/DeferringLoadBalancerExchangeFilterFunction.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import org.springframework.web.reactive.function.client.ExchangeFunction; - -/** - * An {@link ExchangeFilterFunction} implementation that uses {@link ObjectProvider} to - * resolve appropriate load-balancing {@link ExchangeFilterFunction} delegate when the - * {@link ExchangeFilterFunction#filter(ClientRequest, ExchangeFunction)} method is first - * called. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -public class DeferringLoadBalancerExchangeFilterFunction - implements ExchangeFilterFunction { - - private final ObjectProvider exchangeFilterFunctionProvider; - - private T delegate; - - public DeferringLoadBalancerExchangeFilterFunction(ObjectProvider exchangeFilterFunctionProvider) { - this.exchangeFilterFunctionProvider = exchangeFilterFunctionProvider; - } - - @Override - public Mono filter(ClientRequest request, ExchangeFunction next) { - tryResolveDelegate(); - return delegate.filter(request, next); - } - - // Visible for tests - void tryResolveDelegate() { - if (delegate == null) { - delegate = exchangeFilterFunctionProvider.getIfAvailable(); - if (delegate == null) { - throw new IllegalStateException("ReactorLoadBalancerExchangeFilterFunction not available."); - } - } - } - - // Visible for tests - T getDelegate() { - return delegate; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java deleted file mode 100644 index 319e3d06..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ExchangeFilterFunctionUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.net.URI; -import java.util.List; -import java.util.Map; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ExchangeFilterFunction; - -/** - * A utility class for load-balanced {@link ExchangeFilterFunction} instances. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public final class ExchangeFilterFunctionUtils { - - private ExchangeFilterFunctionUtils() { - throw new IllegalStateException("Can't instantiate a utility class."); - } - - static String getHint(String serviceId, Map hints) { - String defaultHint = hints.getOrDefault("default", "default"); - String hintPropertyValue = hints.get(serviceId); - return hintPropertyValue != null ? hintPropertyValue : defaultHint; - } - - static ClientRequest buildClientRequest(ClientRequest request, ServiceInstance serviceInstance, - String instanceIdCookieName, boolean addServiceInstanceCookie, - List transformers) { - URI originalUrl = request.url(); - ClientRequest clientRequest = ClientRequest - .create(request.method(), LoadBalancerUriTools.reconstructURI(serviceInstance, originalUrl)) - .headers(headers -> headers.addAll(request.headers())).cookies(cookies -> { - cookies.addAll(request.cookies()); - if (!(instanceIdCookieName == null || instanceIdCookieName.length() == 0) - && addServiceInstanceCookie) { - cookies.add(instanceIdCookieName, serviceInstance.getInstanceId()); - } - }).attributes(attributes -> attributes.putAll(request.attributes())).body(request.body()).build(); - if (transformers != null) { - for (LoadBalancerClientRequestTransformer transformer : transformers) { - clientRequest = transformer.transformRequest(clientRequest, serviceInstance); - } - } - return clientRequest; - } - - static String serviceInstanceUnavailableMessage(String serviceId) { - return "LoadBalancer does not contain an instance for the service " + serviceId; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancedExchangeFilterFunction.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancedExchangeFilterFunction.java deleted file mode 100644 index a6ba1d03..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancedExchangeFilterFunction.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.web.reactive.function.client.ExchangeFilterFunction; - -/** - * A marker interface for load-balanced {@link ExchangeFilterFunction} instances. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public interface LoadBalancedExchangeFilterFunction extends ExchangeFilterFunction { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java deleted file mode 100644 index 8e61f33c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerBeanPostProcessorAutoConfiguration.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * An auto-configuration that provides a {@link BeanPostProcessor} that allows the use of - * a {@link LoadBalanced} {@link WebClient.Builder} with - * {@link ReactorLoadBalancerExchangeFilterFunction} and {@link ReactiveLoadBalancer} used - * under the hood. NOTE: This has been extracted to a separate configuration in order to - * not impact instantiation and post-processing of other Reactor-LoadBalancer-related - * beans. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(WebClient.class) -@Conditional(LoadBalancerBeanPostProcessorAutoConfiguration.OnAnyLoadBalancerImplementationPresentCondition.class) -public class LoadBalancerBeanPostProcessorAutoConfiguration { - - @Bean - public LoadBalancerWebClientBuilderBeanPostProcessor loadBalancerWebClientBuilderBeanPostProcessor( - DeferringLoadBalancerExchangeFilterFunction deferringExchangeFilterFunction, ApplicationContext context) { - return new LoadBalancerWebClientBuilderBeanPostProcessor(deferringExchangeFilterFunction, context); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnBean(ReactiveLoadBalancer.Factory.class) - protected static class ReactorDeferringLoadBalancerFilterConfig { - - @Bean - @Primary - DeferringLoadBalancerExchangeFilterFunction reactorDeferringLoadBalancerExchangeFilterFunction( - ObjectProvider exchangeFilterFunctionProvider) { - return new DeferringLoadBalancerExchangeFilterFunction<>(exchangeFilterFunctionProvider); - } - - } - - static final class OnAnyLoadBalancerImplementationPresentCondition extends AnyNestedCondition { - - private OnAnyLoadBalancerImplementationPresentCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnBean(ReactiveLoadBalancer.Factory.class) - static class ReactiveLoadBalancerFactoryPresent { - - } - - @ConditionalOnBean(LoadBalancerClient.class) - static class LoadBalancerClientPresent { - - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformer.java deleted file mode 100644 index d28a3b04..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.core.annotation.Order; -import org.springframework.web.reactive.function.client.ClientRequest; - -/** - * Allows applications to transform the load-balanced {@link ClientRequest} given the - * chosen {@link ServiceInstance}. - * - * @author Toshiaki Maki - */ -@Order(LoadBalancerClientRequestTransformer.DEFAULT_ORDER) -public interface LoadBalancerClientRequestTransformer { - - /** - * Order for the {@link LoadBalancerClientRequestTransformer}. - */ - int DEFAULT_ORDER = 0; - - ClientRequest transformRequest(ClientRequest request, ServiceInstance instance); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryContext.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryContext.java deleted file mode 100644 index 3bdff95c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryContext.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.http.HttpMethod; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; - -/** - * Stores the data for a load-balanced call that is being retried. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class LoadBalancerRetryContext { - - private final ClientRequest request; - - private ClientResponse clientResponse; - - private Integer retriesSameServiceInstance = 0; - - private Integer retriesNextServiceInstance = 0; - - protected LoadBalancerRetryContext(ClientRequest request) { - this.request = request; - } - - /** - * Returns the {@link ClientRequest} that is being load-balanced. - * @return the request that is being load-balanced. - */ - protected ClientRequest getRequest() { - return request; - } - - /** - * Returns the {@link ClientResponse} returned for load-balanced request. - * @return the response for the load-balanced request. - */ - protected ClientResponse getClientResponse() { - return clientResponse; - } - - /** - * Sets the {@link ClientResponse} returned for load-balanced request. - * @param clientResponse the response for the load-balanced request. - */ - protected void setClientResponse(ClientResponse clientResponse) { - this.clientResponse = clientResponse; - } - - /** - * Returns the number of times a load-balanced request should be retried on the same - * {@link ServiceInstance}. - * @return the number of retries - */ - protected Integer getRetriesSameServiceInstance() { - return retriesSameServiceInstance; - } - - /** - * Increments the counter for the retries executed against the same - * {@link ServiceInstance}. - */ - protected void incrementRetriesSameServiceInstance() { - retriesSameServiceInstance++; - } - - /** - * Resets the counter for the retries executed against the same - * {@link ServiceInstance}. - */ - protected void resetRetriesSameServiceInstance() { - retriesSameServiceInstance = 0; - } - - /** - * Returns the number of times a load-balanced request should be retried on the next - * {@link ServiceInstance}. - * @return the number of retries - */ - protected Integer getRetriesNextServiceInstance() { - return retriesNextServiceInstance; - } - - /** - * Increments the counter for the retries executed against the same - * {@link ServiceInstance}. - */ - protected void incrementRetriesNextServiceInstance() { - retriesNextServiceInstance++; - } - - /** - * Returns the status code from the {@link ClientResponse} returned for load-balanced - * request. - * @return the status code from the response for the load-balanced request. - */ - protected Integer getResponseStatusCode() { - return clientResponse.statusCode().value(); - } - - /** - * Returns the {@link HttpMethod} of the {@link ClientRequest} that is being - * load-balanced. - * @return the HTTP method of the request that is being load-balanced. - */ - protected HttpMethod getRequestMethod() { - return request.method(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryPolicy.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryPolicy.java deleted file mode 100644 index 37b129fc..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerRetryPolicy.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.cglib.core.internal.Function; -import org.springframework.http.HttpMethod; - -/** - * Pluggable policy used to establish whether a given load-balanced call should be - * retried. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public interface LoadBalancerRetryPolicy { - - /** - * Return true to retry on the same service instance. - * @param context the context for the retry operation - * @return true to retry on the same service instance - */ - boolean canRetrySameServiceInstance(LoadBalancerRetryContext context); - - /** - * Return true to retry on the next service instance. - * @param context the context for the retry operation - * @return true to retry on the same service instance - */ - boolean canRetryNextServiceInstance(LoadBalancerRetryContext context); - - /** - * Return true to retry on the provided HTTP status code. - * @param statusCode the HTTP status code - * @return true to retry on the provided HTTP status code - */ - boolean retryableStatusCode(int statusCode); - - /** - * Return true to retry if the provided exception is thrown. - * @param exception the {@link Throwable} to evaluate - * @return true to retry on the provided exception - */ - boolean retryableException(Throwable exception); - - /** - * Return true to retry on the provided HTTP method. - * @param method the HTTP request method - * @return true to retry on the provided HTTP method - */ - boolean canRetryOnMethod(HttpMethod method); - - interface Factory extends Function { - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientBuilderBeanPostProcessor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientBuilderBeanPostProcessor.java deleted file mode 100644 index bb8db3ff..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerWebClientBuilderBeanPostProcessor.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.context.ApplicationContext; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * A {@link BeanPostProcessor} that applies - * {@link DeferringLoadBalancerExchangeFilterFunction} filter to all - * {@link WebClient.Builder} instances annotated with {@link LoadBalanced}. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -public class LoadBalancerWebClientBuilderBeanPostProcessor implements BeanPostProcessor { - - private final DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction; - - private final ApplicationContext context; - - public LoadBalancerWebClientBuilderBeanPostProcessor( - DeferringLoadBalancerExchangeFilterFunction exchangeFilterFunction, ApplicationContext context) { - this.exchangeFilterFunction = exchangeFilterFunction; - this.context = context; - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof WebClient.Builder) { - if (context.findAnnotationOnBean(beanName, LoadBalanced.class) == null) { - return bean; - } - ((WebClient.Builder) bean).filter(exchangeFilterFunction); - } - return bean; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactiveLoadBalancer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactiveLoadBalancer.java deleted file mode 100644 index 9d4613f8..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactiveLoadBalancer.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.util.Map; - -import org.reactivestreams.Publisher; - -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; - -/** - * Reactive load balancer. - * - * @param type of the response - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -public interface ReactiveLoadBalancer { - - /** - * Default implementation of a request. - */ - Request REQUEST = new DefaultRequest<>(); - - /** - * Choose the next server based on the load balancing algorithm. - * @param request - incoming request - * @return publisher for the response - */ - @SuppressWarnings("rawtypes") - Publisher> choose(Request request); - - default Publisher> choose() { // conflicting name - return choose(REQUEST); - } - - interface Factory { - - default LoadBalancerProperties getProperties(String serviceId) { - return null; - } - - ReactiveLoadBalancer getInstance(String serviceId); - - /** - * Allows accessing beans registered within client-specific LoadBalancer contexts. - * @param name Name of the beans to be returned - * @param type The class of the beans to be returned - * @param The type of the beans to be returned - * @return a {@link Map} of beans - * @see @LoadBalancerClient - */ - Map getInstances(String name, Class type); - - /** - * Allows accessing a bean registered within client-specific LoadBalancer - * contexts. - * @param name Name of the bean to be returned - * @param clazz The class of the bean to be returned - * @param generics The classes of generic types of the bean to be returned - * @param The type of the bean to be returned - * @return a {@link Map} of beans - * @see @LoadBalancerClient - */ - X getInstance(String name, Class clazz, Class... generics); - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java deleted file mode 100644 index a132b73b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfiguration.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.ObjectProvider; -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.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * An auto-configuration that allows the use of a {@link LoadBalanced} - * {@link WebClient.Builder} with {@link ReactorLoadBalancerExchangeFilterFunction} and - * {@link ReactiveLoadBalancer} used under the hood. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(WebClient.class) -@ConditionalOnBean(ReactiveLoadBalancer.Factory.class) -@EnableConfigurationProperties(LoadBalancerClientsProperties.class) -public class ReactorLoadBalancerClientAutoConfiguration { - - @ConditionalOnMissingBean - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "false", - matchIfMissing = true) - @Bean - public ReactorLoadBalancerExchangeFilterFunction loadBalancerExchangeFilterFunction( - ReactiveLoadBalancer.Factory loadBalancerFactory, - ObjectProvider> transformers) { - return new ReactorLoadBalancerExchangeFilterFunction(loadBalancerFactory, - transformers.getIfAvailable(Collections::emptyList)); - } - - @ConditionalOnMissingBean - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true") - @Bean - public RetryableLoadBalancerExchangeFilterFunction retryableLoadBalancerExchangeFilterFunction( - ReactiveLoadBalancer.Factory loadBalancerFactory, - LoadBalancerRetryPolicy.Factory retryPolicyFactory, - ObjectProvider> transformers) { - return new RetryableLoadBalancerExchangeFilterFunction(retryPolicyFactory, loadBalancerFactory, - transformers.getIfAvailable(Collections::emptyList)); - } - - @ConditionalOnMissingBean - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true") - @Bean - public LoadBalancerRetryPolicy.Factory loadBalancerRetryPolicy( - ReactiveLoadBalancer.Factory loadBalancerFactory) { - return new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy.Factory(loadBalancerFactory); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java deleted file mode 100644 index f4ec37b7..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunction.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.net.URI; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycleValidator; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import org.springframework.web.reactive.function.client.ExchangeFunction; - -import static org.springframework.cloud.client.loadbalancer.reactive.ExchangeFilterFunctionUtils.buildClientRequest; -import static org.springframework.cloud.client.loadbalancer.reactive.ExchangeFilterFunctionUtils.getHint; -import static org.springframework.cloud.client.loadbalancer.reactive.ExchangeFilterFunctionUtils.serviceInstanceUnavailableMessage; - -/** - * An {@link ExchangeFilterFunction} that uses {@link ReactiveLoadBalancer} to execute - * requests against a correct {@link ServiceInstance}. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -public class ReactorLoadBalancerExchangeFilterFunction implements LoadBalancedExchangeFilterFunction { - - private static final Log LOG = LogFactory.getLog(ReactorLoadBalancerExchangeFilterFunction.class); - - private final ReactiveLoadBalancer.Factory loadBalancerFactory; - - private final List transformers; - - public ReactorLoadBalancerExchangeFilterFunction(ReactiveLoadBalancer.Factory loadBalancerFactory, - List transformers) { - this.loadBalancerFactory = loadBalancerFactory; - this.transformers = transformers; - } - - @Override - public Mono filter(ClientRequest clientRequest, ExchangeFunction next) { - URI originalUrl = clientRequest.url(); - String serviceId = originalUrl.getHost(); - if (serviceId == null) { - String message = String.format("Request URI does not contain a valid hostname: %s", originalUrl); - if (LOG.isWarnEnabled()) { - LOG.warn(message); - } - return Mono.just(ClientResponse.create(HttpStatus.BAD_REQUEST).body(message).build()); - } - Set supportedLifecycleProcessors = LoadBalancerLifecycleValidator - .getSupportedLifecycleProcessors( - loadBalancerFactory.getInstances(serviceId, LoadBalancerLifecycle.class), - RequestDataContext.class, ResponseData.class, ServiceInstance.class); - String hint = getHint(serviceId, loadBalancerFactory.getProperties(serviceId).getHint()); - RequestData requestData = new RequestData(clientRequest); - DefaultRequest lbRequest = new DefaultRequest<>(new RequestDataContext(requestData, hint)); - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest)); - return choose(serviceId, lbRequest).flatMap(lbResponse -> { - ServiceInstance instance = lbResponse.getServer(); - if (instance == null) { - String message = serviceInstanceUnavailableMessage(serviceId); - if (LOG.isWarnEnabled()) { - LOG.warn(message); - } - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle - .onComplete(new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, lbResponse))); - return Mono.just(ClientResponse.create(HttpStatus.SERVICE_UNAVAILABLE) - .body(serviceInstanceUnavailableMessage(serviceId)).build()); - } - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("LoadBalancer has retrieved the instance for service %s: %s", serviceId, - instance.getUri())); - } - LoadBalancerProperties.StickySession stickySessionProperties = loadBalancerFactory.getProperties(serviceId) - .getStickySession(); - ClientRequest newRequest = buildClientRequest(clientRequest, instance, - stickySessionProperties.getInstanceIdCookieName(), - stickySessionProperties.isAddServiceInstanceCookie(), transformers); - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse)); - return next.exchange(newRequest) - .doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle - .onComplete(new CompletionContext( - CompletionContext.Status.FAILED, throwable, lbRequest, lbResponse)))) - .doOnSuccess(clientResponse -> supportedLifecycleProcessors.forEach( - lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, - lbRequest, lbResponse, new ResponseData(clientResponse, requestData))))); - }); - } - - protected Mono> choose(String serviceId, Request request) { - ReactiveLoadBalancer loadBalancer = loadBalancerFactory.getInstance(serviceId); - if (loadBalancer == null) { - return Mono.just(new EmptyResponse()); - } - return Mono.from(loadBalancer.choose(request)); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableExchangeFilterFunctionLoadBalancerRetryPolicy.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableExchangeFilterFunctionLoadBalancerRetryPolicy.java deleted file mode 100644 index b0d204b2..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableExchangeFilterFunctionLoadBalancerRetryPolicy.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.http.HttpMethod; - -/** - * The default implementation of {@link LoadBalancerRetryPolicy}. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class RetryableExchangeFilterFunctionLoadBalancerRetryPolicy implements LoadBalancerRetryPolicy { - - private final LoadBalancerProperties properties; - - public RetryableExchangeFilterFunctionLoadBalancerRetryPolicy(LoadBalancerProperties properties) { - this.properties = properties; - } - - @Override - public boolean canRetrySameServiceInstance(LoadBalancerRetryContext context) { - return context.getRetriesSameServiceInstance() < properties.getRetry().getMaxRetriesOnSameServiceInstance(); - } - - @Override - public boolean canRetryNextServiceInstance(LoadBalancerRetryContext context) { - return context.getRetriesNextServiceInstance() < properties.getRetry().getMaxRetriesOnNextServiceInstance(); - } - - @Override - public boolean retryableStatusCode(int statusCode) { - return properties.getRetry().getRetryableStatusCodes().contains(statusCode); - } - - @Override - public boolean retryableException(Throwable throwable) { - if (properties.getRetry().isRetryOnAllExceptions()) { - return true; - } - return properties.getRetry().getRetryableExceptions().stream() - .anyMatch(exception -> exception.isInstance(throwable) - || throwable != null && exception.isInstance(throwable.getCause())); - } - - @Override - public boolean canRetryOnMethod(HttpMethod method) { - return HttpMethod.GET.equals(method) || properties.getRetry().isRetryOnAllOperations(); - } - - static class Factory implements LoadBalancerRetryPolicy.Factory { - - final ReactiveLoadBalancer.Factory loadBalancerFactory; - - Factory(ReactiveLoadBalancer.Factory loadBalancerFactory) { - this.loadBalancerFactory = loadBalancerFactory; - } - - @Override - public LoadBalancerRetryPolicy apply(String serviceId) { - return new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy( - loadBalancerFactory.getProperties(serviceId)); - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java deleted file mode 100644 index 808ca359..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunction.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.net.URI; -import java.util.List; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.Exceptions; -import reactor.core.publisher.Mono; -import reactor.util.retry.Retry; -import reactor.util.retry.RetrySpec; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycleValidator; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.cloud.client.loadbalancer.RetryableRequestContext; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import org.springframework.web.reactive.function.client.ExchangeFunction; - -import static org.springframework.cloud.client.loadbalancer.reactive.ExchangeFilterFunctionUtils.buildClientRequest; -import static org.springframework.cloud.client.loadbalancer.reactive.ExchangeFilterFunctionUtils.getHint; -import static org.springframework.cloud.client.loadbalancer.reactive.ExchangeFilterFunctionUtils.serviceInstanceUnavailableMessage; - -/** - * An {@link ExchangeFilterFunction} that uses {@link ReactiveLoadBalancer} to execute - * requests against a correct {@link ServiceInstance} and Reactor Retries to retry the - * call both against the same and the next service instance, based on the provided - * {@link LoadBalancerRetryPolicy}. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class RetryableLoadBalancerExchangeFilterFunction implements LoadBalancedExchangeFilterFunction { - - private static final Log LOG = LogFactory.getLog(RetryableLoadBalancerExchangeFilterFunction.class); - - private final LoadBalancerRetryPolicy.Factory retryPolicyFactory; - - private final ReactiveLoadBalancer.Factory loadBalancerFactory; - - private final List transformers; - - public RetryableLoadBalancerExchangeFilterFunction(LoadBalancerRetryPolicy.Factory retryPolicyFactory, - ReactiveLoadBalancer.Factory loadBalancerFactory, - List transformers) { - this.retryPolicyFactory = retryPolicyFactory; - this.loadBalancerFactory = loadBalancerFactory; - this.transformers = transformers; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public Mono filter(ClientRequest clientRequest, ExchangeFunction next) { - URI originalUrl = clientRequest.url(); - String serviceId = originalUrl.getHost(); - if (serviceId == null) { - String message = String.format("Request URI does not contain a valid hostname: %s", originalUrl); - if (LOG.isWarnEnabled()) { - LOG.warn(message); - } - return Mono.just(ClientResponse.create(HttpStatus.BAD_REQUEST).body(message).build()); - } - LoadBalancerRetryContext loadBalancerRetryContext = new LoadBalancerRetryContext(clientRequest); - LoadBalancerProperties properties = loadBalancerFactory.getProperties(serviceId); - - LoadBalancerRetryPolicy retryPolicy = retryPolicyFactory.apply(serviceId); - Retry exchangeRetry = buildRetrySpec(properties.getRetry().getMaxRetriesOnSameServiceInstance(), true, - properties.getRetry(), retryPolicy); - Retry filterRetry = buildRetrySpec(properties.getRetry().getMaxRetriesOnNextServiceInstance(), false, - properties.getRetry(), retryPolicy); - - Set supportedLifecycleProcessors = LoadBalancerLifecycleValidator - .getSupportedLifecycleProcessors( - loadBalancerFactory.getInstances(serviceId, LoadBalancerLifecycle.class), - RetryableRequestContext.class, ResponseData.class, ServiceInstance.class); - String hint = getHint(serviceId, properties.getHint()); - RequestData requestData = new RequestData(clientRequest); - DefaultRequest lbRequest = new DefaultRequest<>( - new RetryableRequestContext(null, requestData, hint)); - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest)); - return Mono.defer(() -> choose(serviceId, lbRequest).flatMap(lbResponse -> { - ServiceInstance instance = lbResponse.getServer(); - lbRequest.setContext(new RetryableRequestContext(instance, requestData, hint)); - if (instance == null) { - String message = serviceInstanceUnavailableMessage(serviceId); - if (LOG.isWarnEnabled()) { - LOG.warn(message); - } - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle - .onComplete(new CompletionContext( - CompletionContext.Status.DISCARD, lbRequest, lbResponse))); - return Mono.just(ClientResponse.create(HttpStatus.SERVICE_UNAVAILABLE) - .body(serviceInstanceUnavailableMessage(serviceId)).build()); - } - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("LoadBalancer has retrieved the instance for service %s: %s", serviceId, - instance.getUri())); - } - LoadBalancerProperties.StickySession stickySessionProperties = properties.getStickySession(); - ClientRequest newRequest = buildClientRequest(clientRequest, instance, - stickySessionProperties.getInstanceIdCookieName(), - stickySessionProperties.isAddServiceInstanceCookie(), transformers); - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse)); - return next.exchange(newRequest) - .doOnError(throwable -> supportedLifecycleProcessors.forEach(lifecycle -> lifecycle - .onComplete(new CompletionContext( - CompletionContext.Status.FAILED, throwable, lbRequest, lbResponse)))) - .doOnSuccess(clientResponse -> supportedLifecycleProcessors.forEach( - lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, - lbRequest, lbResponse, new ResponseData(clientResponse, requestData))))) - .map(clientResponse -> { - loadBalancerRetryContext.setClientResponse(clientResponse); - if (shouldRetrySameServiceInstance(retryPolicy, loadBalancerRetryContext)) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Retrying on status code: %d", - clientResponse.statusCode().value())); - } - throw new RetryableStatusCodeException(); - } - return clientResponse; - - }); - }).map(clientResponse -> { - loadBalancerRetryContext.setClientResponse(clientResponse); - if (shouldRetryNextServiceInstance(retryPolicy, loadBalancerRetryContext)) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Retrying on status code: %d", clientResponse.statusCode().value())); - } - throw new RetryableStatusCodeException(); - } - return clientResponse; - - }).retryWhen(exchangeRetry)).retryWhen(filterRetry); - } - - private Retry buildRetrySpec(int max, boolean transientErrors, LoadBalancerProperties.Retry retry, - LoadBalancerRetryPolicy retryPolicy) { - if (!retry.isEnabled()) { - return Retry.max(0).filter(throwable -> isRetryException(throwable, retryPolicy)) - .transientErrors(transientErrors); - } - LoadBalancerProperties.Retry.Backoff backoffProperties = retry.getBackoff(); - if (backoffProperties.isEnabled()) { - return RetrySpec.backoff(max, backoffProperties.getMinBackoff()) - .filter(throwable -> isRetryException(throwable, retryPolicy)) - .maxBackoff(backoffProperties.getMaxBackoff()).jitter(backoffProperties.getJitter()) - .transientErrors(transientErrors); - } - return RetrySpec.max(max).filter(throwable -> isRetryException(throwable, retryPolicy)) - .transientErrors(transientErrors); - } - - private boolean shouldRetrySameServiceInstance(LoadBalancerRetryPolicy retryPolicy, - LoadBalancerRetryContext loadBalancerRetryContext) { - boolean shouldRetry = retryPolicy.retryableStatusCode(loadBalancerRetryContext.getResponseStatusCode()) - && retryPolicy.canRetryOnMethod(loadBalancerRetryContext.getRequestMethod()) - && retryPolicy.canRetrySameServiceInstance(loadBalancerRetryContext); - if (shouldRetry) { - loadBalancerRetryContext.incrementRetriesSameServiceInstance(); - } - return shouldRetry; - } - - private boolean shouldRetryNextServiceInstance(LoadBalancerRetryPolicy retryPolicy, - LoadBalancerRetryContext loadBalancerRetryContext) { - boolean shouldRetry = retryPolicy.retryableStatusCode(loadBalancerRetryContext.getResponseStatusCode()) - && retryPolicy.canRetryOnMethod(loadBalancerRetryContext.getRequestMethod()) - && retryPolicy.canRetryNextServiceInstance(loadBalancerRetryContext); - if (shouldRetry) { - loadBalancerRetryContext.incrementRetriesNextServiceInstance(); - loadBalancerRetryContext.resetRetriesSameServiceInstance(); - } - return shouldRetry; - } - - private boolean isRetryException(Throwable throwable, LoadBalancerRetryPolicy retryPolicy) { - return retryPolicy.retryableException(throwable) - || (throwable != null && retryPolicy.retryableException(throwable.getCause())) - || Exceptions.isRetryExhausted(throwable); - } - - protected Mono> choose(String serviceId, Request request) { - ReactiveLoadBalancer loadBalancer = loadBalancerFactory.getInstance(serviceId); - if (loadBalancer == null) { - return Mono.just(new EmptyResponse()); - } - return Mono.from(loadBalancer.choose(request)); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableStatusCodeException.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableStatusCodeException.java deleted file mode 100644 index 2fec503c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableStatusCodeException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -/** - * An {@link IllegalStateException} used to trigger retries based on the returned HTTP - * status code. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class RetryableStatusCodeException extends IllegalStateException { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/WebClientCustomizer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/WebClientCustomizer.java deleted file mode 100644 index 56f96426..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/reactive/WebClientCustomizer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import org.springframework.web.reactive.function.client.WebClient; - -/** - * Callback interface that can be used to customize a - * {@link org.springframework.web.reactive.function.client.WebClient.Builder - * WebClient.Builder}. - * - * See original - * {@link org.springframework.boot.web.reactive.function.client.WebClientCustomizer} - * - * @author Brian Clozel - * @since 2.1.0 - */ -@FunctionalInterface -public interface WebClientCustomizer { - - /** - * Callback to customize a - * {@link org.springframework.web.reactive.function.client.WebClient.Builder - * WebClient.Builder} instance. - * @param webClientBuilder the client builder to customize - */ - void customize(WebClient.Builder webClientBuilder); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistration.java deleted file mode 100644 index aadb0ed7..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistration.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -import jakarta.annotation.PreDestroy; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.BeansException; -import org.springframework.boot.web.context.ConfigurableWebServerApplicationContext; -import org.springframework.boot.web.context.WebServerInitializedEvent; -import org.springframework.cloud.client.discovery.ManagementServerPortUtils; -import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ApplicationListener; -import org.springframework.core.env.Environment; - -/** - * Lifecycle methods that may be useful and common to {@link ServiceRegistry} - * implementations. - * - * TODO: Document the lifecycle. - * - * @param Registration type passed to the {@link ServiceRegistry}. - * @author Spencer Gibb - * @author Zen Huifer - */ -public abstract class AbstractAutoServiceRegistration - implements AutoServiceRegistration, ApplicationContextAware, ApplicationListener { - - private static final Log logger = LogFactory.getLog(AbstractAutoServiceRegistration.class); - - private final ServiceRegistry serviceRegistry; - - private final boolean autoStartup = true; - - private final AtomicBoolean running = new AtomicBoolean(false); - - private final int order = 0; - - private final AtomicInteger port = new AtomicInteger(0); - - private ApplicationContext context; - - private Environment environment; - - private AutoServiceRegistrationProperties properties; - - private List> registrationManagementLifecycles = new ArrayList<>(); - - private List> registrationLifecycles = new ArrayList<>(); - - protected AbstractAutoServiceRegistration(ServiceRegistry serviceRegistry, - AutoServiceRegistrationProperties properties) { - this.serviceRegistry = serviceRegistry; - this.properties = properties; - } - - protected AbstractAutoServiceRegistration(ServiceRegistry serviceRegistry, - AutoServiceRegistrationProperties properties, - List> registrationManagementLifecycles, - List> registrationLifecycles) { - this.serviceRegistry = serviceRegistry; - this.properties = properties; - this.registrationManagementLifecycles = registrationManagementLifecycles; - this.registrationLifecycles = registrationLifecycles; - } - - protected AbstractAutoServiceRegistration(ServiceRegistry serviceRegistry, - AutoServiceRegistrationProperties properties, List> registrationLifecycles) { - this.serviceRegistry = serviceRegistry; - this.properties = properties; - this.registrationLifecycles = registrationLifecycles; - } - - public void addRegistrationManagementLifecycle(RegistrationManagementLifecycle registrationManagementLifecycle) { - this.registrationManagementLifecycles.add(registrationManagementLifecycle); - } - - public void addRegistrationLifecycle(RegistrationLifecycle registrationLifecycle) { - this.registrationLifecycles.add(registrationLifecycle); - } - - protected ApplicationContext getContext() { - return this.context; - } - - @Override - @SuppressWarnings("deprecation") - public void onApplicationEvent(WebServerInitializedEvent event) { - ApplicationContext context = event.getApplicationContext(); - if (context instanceof ConfigurableWebServerApplicationContext) { - if ("management".equals(((ConfigurableWebServerApplicationContext) context).getServerNamespace())) { - return; - } - } - this.port.compareAndSet(0, event.getWebServer().getPort()); - this.start(); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.context = applicationContext; - this.environment = this.context.getEnvironment(); - } - - @Deprecated - protected Environment getEnvironment() { - return this.environment; - } - - @Deprecated - protected AtomicInteger getPort() { - return this.port; - } - - public boolean isAutoStartup() { - return this.autoStartup; - } - - public void start() { - if (!isEnabled()) { - if (logger.isDebugEnabled()) { - logger.debug("Discovery Lifecycle disabled. Not starting"); - } - return; - } - - // only initialize if nonSecurePort is greater than 0 and it isn't already running - // because of containerPortInitializer below - if (!this.running.get()) { - this.context.publishEvent(new InstancePreRegisteredEvent(this, getRegistration())); - registrationLifecycles.forEach( - registrationLifecycle -> registrationLifecycle.postProcessBeforeStartRegister(getRegistration())); - register(); - this.registrationLifecycles.forEach( - registrationLifecycle -> registrationLifecycle.postProcessAfterStartRegister(getRegistration())); - if (shouldRegisterManagement()) { - this.registrationManagementLifecycles - .forEach(registrationManagementLifecycle -> registrationManagementLifecycle - .postProcessBeforeStartRegisterManagement(getManagementRegistration())); - this.registerManagement(); - registrationManagementLifecycles - .forEach(registrationManagementLifecycle -> registrationManagementLifecycle - .postProcessAfterStartRegisterManagement(getManagementRegistration())); - - } - this.context.publishEvent(new InstanceRegisteredEvent<>(this, getConfiguration())); - this.running.compareAndSet(false, true); - } - - } - - /** - * @return Whether the management service should be registered with the - * {@link ServiceRegistry}. - */ - protected boolean shouldRegisterManagement() { - if (this.properties == null || this.properties.isRegisterManagement()) { - return getManagementPort() != null && ManagementServerPortUtils.isDifferent(this.context); - } - return false; - } - - /** - * @return The object used to configure the registration. - */ - @Deprecated - protected abstract Object getConfiguration(); - - /** - * @return True, if this is enabled. - */ - protected abstract boolean isEnabled(); - - /** - * @return The serviceId of the Management Service. - */ - @Deprecated - protected String getManagementServiceId() { - // TODO: configurable management suffix - return this.context.getId() + ":management"; - } - - /** - * @return The service name of the Management Service. - */ - @Deprecated - protected String getManagementServiceName() { - // TODO: configurable management suffix - return getAppName() + ":management"; - } - - /** - * @return The management server port. - */ - @Deprecated - protected Integer getManagementPort() { - return ManagementServerPortUtils.getPort(this.context); - } - - /** - * @return The app name (currently the spring.application.name property). - */ - @Deprecated - protected String getAppName() { - return this.environment.getProperty("spring.application.name", "application"); - } - - @PreDestroy - public void destroy() { - stop(); - } - - public boolean isRunning() { - return this.running.get(); - } - - protected AtomicBoolean getRunning() { - return this.running; - } - - public int getOrder() { - return this.order; - } - - public int getPhase() { - return 0; - } - - protected ServiceRegistry getServiceRegistry() { - return this.serviceRegistry; - } - - protected abstract R getRegistration(); - - protected abstract R getManagementRegistration(); - - /** - * Register the local service with the {@link ServiceRegistry}. - */ - protected void register() { - this.serviceRegistry.register(getRegistration()); - } - - /** - * Register the local management service with the {@link ServiceRegistry}. - */ - protected void registerManagement() { - R registration = getManagementRegistration(); - if (registration != null) { - this.serviceRegistry.register(registration); - } - } - - /** - * De-register the local service with the {@link ServiceRegistry}. - */ - protected void deregister() { - this.serviceRegistry.deregister(getRegistration()); - } - - /** - * De-register the local management service with the {@link ServiceRegistry}. - */ - protected void deregisterManagement() { - R registration = getManagementRegistration(); - if (registration != null) { - this.serviceRegistry.deregister(registration); - } - } - - public void stop() { - if (this.getRunning().compareAndSet(true, false) && isEnabled()) { - - this.registrationLifecycles.forEach( - registrationLifecycle -> registrationLifecycle.postProcessBeforeStopRegister(getRegistration())); - deregister(); - this.registrationLifecycles.forEach( - registrationLifecycle -> registrationLifecycle.postProcessAfterStopRegister(getRegistration())); - if (shouldRegisterManagement()) { - this.registrationManagementLifecycles - .forEach(registrationManagementLifecycle -> registrationManagementLifecycle - .postProcessBeforeStopRegisterManagement(getManagementRegistration())); - deregisterManagement(); - this.registrationManagementLifecycles - .forEach(registrationManagementLifecycle -> registrationManagementLifecycle - .postProcessAfterStopRegisterManagement(getManagementRegistration())); - } - this.serviceRegistry.close(); - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistration.java deleted file mode 100644 index f36629a2..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistration.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -/** - * @author Spencer Gibb - */ -public interface AutoServiceRegistration { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfiguration.java deleted file mode 100644 index 3d44be73..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import(AutoServiceRegistrationConfiguration.class) -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) -public class AutoServiceRegistrationAutoConfiguration implements InitializingBean { - - @Autowired(required = false) - private AutoServiceRegistration autoServiceRegistration; - - @Autowired - private AutoServiceRegistrationProperties properties; - - @Override - public void afterPropertiesSet() { - if (this.autoServiceRegistration == null && this.properties.isFailFast()) { - throw new IllegalStateException( - "Auto Service Registration has " + "been requested, but there is no AutoServiceRegistration bean"); - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationConfiguration.java deleted file mode 100644 index 9f9914b4..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(AutoServiceRegistrationProperties.class) -@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true) -public class AutoServiceRegistrationConfiguration { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationProperties.java deleted file mode 100644 index 8eb27713..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationProperties.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Spencer Gibb - */ -@ConfigurationProperties("spring.cloud.service-registry.auto-registration") -public class AutoServiceRegistrationProperties { - - /** Whether service auto-registration is enabled. Defaults to true. */ - private boolean enabled = true; - - /** Whether to register the management as a service. Defaults to true. */ - private boolean registerManagement = true; - - /** - * Whether startup fails if there is no AutoServiceRegistration. Defaults to false. - */ - private boolean failFast = false; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isRegisterManagement() { - return this.registerManagement; - } - - public void setRegisterManagement(boolean registerManagement) { - this.registerManagement = registerManagement; - } - - @Deprecated - public boolean shouldRegisterManagement() { - return this.registerManagement; - } - - public boolean isFailFast() { - return this.failFast; - } - - public void setFailFast(boolean failFast) { - this.failFast = failFast; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java deleted file mode 100644 index 1e35fc83..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * A marker interface used by a {@link ServiceRegistry}. - * - * @author Spencer Gibb - * @since 1.2.0 - */ -public interface Registration extends ServiceInstance { - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationLifecycle.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationLifecycle.java deleted file mode 100644 index 9a25d527..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationLifecycle.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import org.springframework.core.Ordered; - -/** - * Service registration life cycle. This life cycle is only related to - * {@link Registration}. - * - * @author Zen Huifer - */ -public interface RegistrationLifecycle extends Ordered { - - /** - * default order. - */ - int DEFAULT_ORDER = 0; - - /** - * A method executed before registering the local service with the - * {@link ServiceRegistry}. - * @param registration registration - */ - void postProcessBeforeStartRegister(R registration); - - /** - * A method executed after registering the local service with the - * {@link ServiceRegistry}. - * @param registration registration - */ - void postProcessAfterStartRegister(R registration); - - /** - * A method executed before de-registering the local service with the - * {@link ServiceRegistry}. - * @param registration registration - */ - void postProcessBeforeStopRegister(R registration); - - /** - * A method executed after de-registering the local service with the - * {@link ServiceRegistry}. - * @param registration registration - */ - void postProcessAfterStopRegister(R registration); - - default int getOrder() { - return DEFAULT_ORDER; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationManagementLifecycle.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationManagementLifecycle.java deleted file mode 100644 index aa378d70..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/RegistrationManagementLifecycle.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -/** - * Service registration life cycle. This life cycle is only related to - * {@link org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration#getManagementRegistration()}. - * - * @author Zen Huifer - */ -public interface RegistrationManagementLifecycle extends RegistrationLifecycle { - - /** - * A method executed before registering the local management service with the - * {@link ServiceRegistry}. - * @param registrationManagement registrationManagement - */ - void postProcessBeforeStartRegisterManagement(R registrationManagement); - - /** - * A method executed after registering the local management service with the - * {@link ServiceRegistry}. - * @param registrationManagement registrationManagement - */ - void postProcessAfterStartRegisterManagement(R registrationManagement); - - /** - * A method executed before de-registering the management local service with the - * {@link ServiceRegistry}. - * @param registrationManagement registrationManagement - */ - void postProcessBeforeStopRegisterManagement(R registrationManagement); - - /** - * A method executed after de-registering the management local service with the - * {@link ServiceRegistry}. - * @param registrationManagement registrationManagement - */ - void postProcessAfterStopRegisterManagement(R registrationManagement); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java deleted file mode 100644 index 1d467b8b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -/** - * Contract to register and deregister instances with a Service Registry. - * - * @param registration meta data - * @author Spencer Gibb - * @since 1.2.0 - */ -public interface ServiceRegistry { - - /** - * Registers the registration. A registration typically has information about an - * instance, such as its hostname and port. - * @param registration registration meta data - */ - void register(R registration); - - /** - * Deregisters the registration. - * @param registration registration meta data - */ - void deregister(R registration); - - /** - * Closes the ServiceRegistry. This is a lifecycle method. - */ - void close(); - - /** - * Sets the status of the registration. The status values are determined by the - * individual implementations. - * @param registration The registration to update. - * @param status The status to set. - * @see org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint - */ - void setStatus(R registration, String status); - - /** - * Gets the status of a particular registration. - * @param registration The registration to query. - * @param The type of the status. - * @return The status of the registration. - * @see org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint - */ - T getStatus(R registration); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfiguration.java deleted file mode 100644 index 951449fe..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -public class ServiceRegistryAutoConfiguration { - - @ConditionalOnBean(ServiceRegistry.class) - @ConditionalOnClass(Endpoint.class) - protected class ServiceRegistryEndpointConfiguration { - - @Autowired(required = false) - private Registration registration; - - @Bean - @ConditionalOnAvailableEndpoint - public ServiceRegistryEndpoint serviceRegistryEndpoint(ServiceRegistry serviceRegistry) { - ServiceRegistryEndpoint endpoint = new ServiceRegistryEndpoint(serviceRegistry); - endpoint.setRegistration(this.registration); - return endpoint; - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpoint.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpoint.java deleted file mode 100644 index 5bf63ba9..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpoint.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry.endpoint; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.ReadOperation; -import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; -import org.springframework.boot.actuate.endpoint.web.WebEndpointResponse; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -import org.springframework.http.HttpStatus; -import org.springframework.util.Assert; - -/** - * Endpoint to display and set the service instance status using the ServiceRegistry. - * - * @author Spencer Gibb - */ -@SuppressWarnings("unchecked") -@Endpoint(id = "serviceregistry") -public class ServiceRegistryEndpoint { - - private final ServiceRegistry serviceRegistry; - - private Registration registration; - - public ServiceRegistryEndpoint(ServiceRegistry serviceRegistry) { - this.serviceRegistry = serviceRegistry; - } - - public void setRegistration(Registration registration) { - this.registration = registration; - } - - @WriteOperation - public WebEndpointResponse setStatus(String status) { - Assert.notNull(status, "status may not by null"); - - if (this.registration == null) { - return new WebEndpointResponse<>("no registration found", HttpStatus.NOT_FOUND.value()); - } - - this.serviceRegistry.setStatus(this.registration, status); - return new WebEndpointResponse<>(); - } - - @ReadOperation - public WebEndpointResponse getStatus() { - if (this.registration == null) { - return new WebEndpointResponse<>("no registration found", HttpStatus.NOT_FOUND.value()); - } - - return new WebEndpointResponse<>(this.serviceRegistry.getStatus(this.registration)); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessor.java deleted file mode 100644 index 074d6587..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessor.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2015-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor; -import org.springframework.boot.context.properties.bind.BindContext; -import org.springframework.boot.context.properties.bind.BindHandler; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertyName; -import org.springframework.boot.context.properties.source.ConfigurationPropertySource; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.core.Ordered; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; - -/** - * @author Ryan Baxter - */ -// TODO: 4.0.0 move to org.springframework.cloud.commons.config -public abstract class ConfigDataMissingEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { - - /** - * Spring config import property name. - */ - public static final String CONFIG_IMPORT_PROPERTY = "spring.config.import"; - - private static final Bindable CONFIG_DATA_LOCATION_ARRAY = Bindable.of(String[].class); - - private static final String[] EMPTY_ARRAY = new String[0]; - - /** - * Order of post processor, set to run after - * {@link ConfigDataEnvironmentPostProcessor}. - */ - public static final int ORDER = ConfigDataEnvironmentPostProcessor.ORDER + 1000; - - private final Logger LOG = LoggerFactory.getLogger(ConfigDataMissingEnvironmentPostProcessor.class); - - @Override - public int getOrder() { - return ORDER; - } - - protected abstract boolean shouldProcessEnvironment(Environment environment); - - protected abstract String getPrefix(); - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - if (!shouldProcessEnvironment(environment)) { - return; - } - List property = getConfigImports(environment); - if (property == null || property.isEmpty()) { - throw new ImportException("No spring.config.import set", false); - } - if (!property.stream().anyMatch(impt -> ((String) impt).contains(getPrefix()))) { - throw new ImportException("spring.config.import missing " + getPrefix(), true); - } - } - - private List getConfigImports(ConfigurableEnvironment environment) { - MutablePropertySources propertySources = environment.getPropertySources(); - List property = propertySources.stream().filter(this::propertySourceWithConfigImport) - .flatMap(propertySource -> { - List configImports = new ArrayList<>(); - if (propertySource.getProperty(CONFIG_IMPORT_PROPERTY) != null) { - configImports.add(propertySource.getProperty(CONFIG_IMPORT_PROPERTY)); - } - else { - configImports.addAll(Arrays.asList(getConfigImportArray(propertySource))); - } - return configImports.stream(); - }).collect(Collectors.toList()); - return property; - } - - private boolean propertySourceWithConfigImport(PropertySource propertySource) { - if (propertySource instanceof CompositePropertySource) { - return ((CompositePropertySource) propertySource).getPropertySources().stream() - .anyMatch(this::propertySourceWithConfigImport); - } - return propertySource.containsProperty(CONFIG_IMPORT_PROPERTY) - || getConfigImportArray(propertySource).length > 0; - } - - private String[] getConfigImportArray(PropertySource propertySource) { - ConfigurationPropertySource configurationPropertySource = ConfigurationPropertySource.from(propertySource); - if (configurationPropertySource == null) { - return EMPTY_ARRAY; - } - Binder binder = new Binder(configurationPropertySource); - return binder.bind(CONFIG_IMPORT_PROPERTY, CONFIG_DATA_LOCATION_ARRAY, new BindHandler() { - @Override - public Object onFailure(ConfigurationPropertyName name, Bindable target, BindContext context, - Exception error) throws Exception { - LOG.info("Error binding " + CONFIG_IMPORT_PROPERTY, error); - return EMPTY_ARRAY; - } - }).orElse(EMPTY_ARRAY); - } - - public static class ImportException extends RuntimeException { - - /** - * Indicates if prefix is missing. - */ - public final boolean missingPrefix; - - ImportException(String message, boolean missingPrefix) { - super(message); - this.missingPrefix = missingPrefix; - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/CommonsConfigAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/CommonsConfigAutoConfiguration.java deleted file mode 100644 index c2cc85dc..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/CommonsConfigAutoConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.config; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.source.ConfigurationPropertyName; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.lang.Nullable; -import org.springframework.util.ObjectUtils; - -/** - * @author Spencer Gibb - * @since 3.1.0 - */ -@Configuration(proxyBeanMethods = false) -public class CommonsConfigAutoConfiguration { - - @Bean - public DefaultsBindHandlerAdvisor defaultsBindHandlerAdvisor( - @Nullable DefaultsBindHandlerAdvisor.MappingsProvider[] providers) { - Map additionalMappings = new HashMap<>(); - if (!ObjectUtils.isEmpty(providers)) { - for (DefaultsBindHandlerAdvisor.MappingsProvider mappingsProvider : providers) { - additionalMappings.putAll(mappingsProvider.getDefaultMappings()); - } - } - return new DefaultsBindHandlerAdvisor(additionalMappings); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/DefaultsBindHandlerAdvisor.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/DefaultsBindHandlerAdvisor.java deleted file mode 100644 index 7afe8959..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/config/DefaultsBindHandlerAdvisor.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.config; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.boot.context.properties.ConfigurationPropertiesBindHandlerAdvisor; -import org.springframework.boot.context.properties.bind.AbstractBindHandler; -import org.springframework.boot.context.properties.bind.BindContext; -import org.springframework.boot.context.properties.bind.BindHandler; -import org.springframework.boot.context.properties.bind.BindResult; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.source.ConfigurationPropertyName; -import org.springframework.boot.context.properties.source.ConfigurationPropertyName.Form; -import org.springframework.util.CollectionUtils; - -/** - * @author Oleg Zhurakousky - * @since 3.1.0 - */ -public class DefaultsBindHandlerAdvisor implements ConfigurationPropertiesBindHandlerAdvisor { - - private final Map mappings; - - public DefaultsBindHandlerAdvisor(Map additionalMappings) { - this.mappings = new LinkedHashMap<>(); - if (!CollectionUtils.isEmpty(additionalMappings)) { - this.mappings.putAll(additionalMappings); - } - } - - @Override - public BindHandler apply(BindHandler bindHandler) { - - BindHandler handler = new AbstractBindHandler(bindHandler) { - @Override - public Bindable onStart(ConfigurationPropertyName name, Bindable target, BindContext context) { - ConfigurationPropertyName defaultName = getDefaultName(name); - if (defaultName != null) { - BindResult result = context.getBinder().bind(defaultName, target); - if (result.isBound()) { - return target.withExistingValue(result.get()); - } - } - return bindHandler.onStart(name, target, context); - } - }; - return handler; - } - - private ConfigurationPropertyName getDefaultName(ConfigurationPropertyName name) { - for (Map.Entry mapping : this.mappings.entrySet()) { - ConfigurationPropertyName from = mapping.getKey(); - ConfigurationPropertyName to = mapping.getValue(); - if ((from.isAncestorOf(name) && name.getNumberOfElements() > from.getNumberOfElements())) { - ConfigurationPropertyName defaultName = to; - for (int i = from.getNumberOfElements() + 1; i < name.getNumberOfElements(); i++) { - defaultName = defaultName.append(name.getElement(i, Form.UNIFORM)); - } - return defaultName; - } - } - return null; - } - - /** - * Provides mappings including the default mappings. - */ - public interface MappingsProvider { - - Map getDefaultMappings(); - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/CloudFlux.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/CloudFlux.java deleted file mode 100644 index 324d4242..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/CloudFlux.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.publisher; - -import org.reactivestreams.Publisher; -import reactor.core.publisher.Flux; - -/** - * INTERNAL USAGE ONLY. This functionality will be ported to reactor-core and will be - * removed in a future release. - * - * @author Tim Ysewyn - */ -public abstract class CloudFlux extends Flux { - - /** - * Pick the first {@link Publisher} to emit an onNext/onError signal and replay all - * signals from that {@link Publisher}, effectively behaving like the fastest of these - * competing sources. If all the sources complete empty, a single completion signal is - * sent. Note that if all the sources are empty (never emit an element, ie. no onNext) - * AND at least one is also infinite (no onComplete/onError signal), the resulting - * {@link Flux} will be infinite and empty (like {@link Flux#never()}). - * @param sources The competing source publishers - * @param The type of values in both source and output sequences - * @return a new {@link Flux} behaving like the fastest of its sources - */ - @SafeVarargs - public static Flux firstNonEmpty(Publisher... sources) { - return onAssembly(new FluxFirstNonEmptyEmitting<>(sources)); - } - - /** - * Pick the first {@link Publisher} to emit an onNext/onError signal and replay all - * signals from that {@link Publisher}, effectively behaving like the fastest of these - * competing sources. If all the sources complete empty, a single completion signal is - * sent. Note that if all the sources are empty (never emit an element, ie. no onNext) - * AND at least one is also infinite (no onComplete/onError signal), the resulting - * {@link Flux} will be infinite and empty (like {@link Flux#never()}). - * @param sources The competing source publishers - * @param The type of values in both source and output sequences - * @return a new {@link reactor.core.publisher.Flux} behaving like the fastest of its - * sources - */ - public static Flux firstNonEmpty(Iterable> sources) { - return onAssembly(new FluxFirstNonEmptyEmitting<>(sources)); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmitting.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmitting.java deleted file mode 100644 index ed33b4b3..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmitting.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.publisher; - -import java.util.Iterator; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import java.util.stream.Stream; - -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscription; -import reactor.core.CoreSubscriber; -import reactor.core.Scannable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Operators; -import reactor.util.annotation.Nullable; - -/** - * @author Tim Ysewyn - */ -final class FluxFirstNonEmptyEmitting extends Flux implements Scannable, Publisher { - - final Publisher[] array; - - final Iterable> iterable; - - @SafeVarargs - FluxFirstNonEmptyEmitting(Publisher... array) { - this.array = Objects.requireNonNull(array, "array"); - this.iterable = null; - } - - FluxFirstNonEmptyEmitting(Iterable> iterable) { - this.array = null; - this.iterable = Objects.requireNonNull(iterable); - } - - @SuppressWarnings("unchecked") - @Override - public void subscribe(CoreSubscriber actual) { - Publisher[] a = array; - int n; - if (a == null) { - n = 0; - a = new Publisher[8]; - - Iterator> it; - - try { - it = Objects.requireNonNull(iterable.iterator(), "The iterator returned is null"); - } - catch (Throwable e) { - Operators.error(actual, Operators.onOperatorError(e, actual.currentContext())); - return; - } - - for (;;) { - - boolean b; - - try { - b = it.hasNext(); - } - catch (Throwable e) { - Operators.error(actual, Operators.onOperatorError(e, actual.currentContext())); - return; - } - - if (!b) { - break; - } - - Publisher p; - - try { - p = Objects.requireNonNull(it.next(), "The Publisher returned by the iterator is null"); - } - catch (Throwable e) { - Operators.error(actual, Operators.onOperatorError(e, actual.currentContext())); - return; - } - - if (n == a.length) { - Publisher[] c = new Publisher[n + (n >> 2)]; - System.arraycopy(a, 0, c, 0, n); - a = c; - } - a[n++] = p; - } - - } - else { - n = a.length; - } - - if (n == 0) { - Operators.complete(actual); - return; - } - if (n == 1) { - Publisher p = a[0]; - - if (p == null) { - Operators.error(actual, new NullPointerException("The single source Publisher is null")); - } - else { - p.subscribe(actual); - } - return; - } - - RaceCoordinator coordinator = new RaceCoordinator<>(n); - - coordinator.subscribe(a, n, actual); - } - - @Override - public Object scanUnsafe(Attr key) { - return null; // no particular key to be represented, still useful in hooks - } - - @Override - public String stepName() { - return "source(" + getClass().getSimpleName() + ")"; - } - - static final class RaceCoordinator implements Subscription, Scannable { - - final FirstNonEmptyEmittingSubscriber[] subscribers; - - volatile boolean cancelled; - - volatile int wip; - - volatile int competingSubscribers; - - @SuppressWarnings("rawtypes") - static final AtomicIntegerFieldUpdater WIP = AtomicIntegerFieldUpdater - .newUpdater(RaceCoordinator.class, "wip"); - - static final AtomicIntegerFieldUpdater COMPETING_SUBSCRIBERS = AtomicIntegerFieldUpdater - .newUpdater(RaceCoordinator.class, "competingSubscribers"); - - @SuppressWarnings("unchecked") - RaceCoordinator(int n) { - subscribers = new FirstNonEmptyEmittingSubscriber[n]; - wip = Integer.MIN_VALUE; - competingSubscribers = n; - } - - @Override - public Stream inners() { - return Stream.of(subscribers); - } - - @Override - @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.CANCELLED) { - return cancelled; - } - - return null; - } - - void subscribe(Publisher[] sources, int n, CoreSubscriber actual) { - FirstNonEmptyEmittingSubscriber[] a = subscribers; - - for (int i = 0; i < n; i++) { - a[i] = new FirstNonEmptyEmittingSubscriber<>(actual, this, i); - } - - actual.onSubscribe(this); - - for (int i = 0; i < n; i++) { - if (cancelled || wip != Integer.MIN_VALUE) { - return; - } - - Publisher p = sources[i]; - - if (p == null) { - if (WIP.compareAndSet(this, Integer.MIN_VALUE, -1)) { - actual.onError(new NullPointerException("The " + i + " th Publisher source is null")); - } - return; - } - - p.subscribe(a[i]); - } - - } - - @Override - public void request(long n) { - if (Operators.validate(n)) { - int w = wip; - if (w >= 0) { - subscribers[w].request(n); - } - else { - for (FirstNonEmptyEmittingSubscriber s : subscribers) { - s.request(n); - } - } - } - } - - @Override - public void cancel() { - if (cancelled) { - return; - } - cancelled = true; - - int w = wip; - if (w >= 0) { - subscribers[w].cancel(); - } - else { - for (FirstNonEmptyEmittingSubscriber s : subscribers) { - s.cancel(); - } - } - } - - boolean tryWin(int index) { - if (wip == Integer.MIN_VALUE) { - if (WIP.compareAndSet(this, Integer.MIN_VALUE, index)) { - - FirstNonEmptyEmittingSubscriber[] a = subscribers; - int n = a.length; - - for (int i = 0; i < n; i++) { - if (i != index) { - a[i].cancel(); - } - } - - return true; - } - } - return false; - } - - int resignFromRace() { - return COMPETING_SUBSCRIBERS.decrementAndGet(this); - } - - } - - static final class FirstNonEmptyEmittingSubscriber extends Operators.DeferredSubscription - implements CoreSubscriber, Scannable, Subscription { - - final RaceCoordinator parent; - - final CoreSubscriber actual; - - final int index; - - boolean won; - - FirstNonEmptyEmittingSubscriber(CoreSubscriber actual, RaceCoordinator parent, int index) { - this.actual = actual; - this.parent = parent; - this.index = index; - } - - @Override - @Nullable - public Object scanUnsafe(Attr key) { - if (key == Attr.ACTUAL) { - return actual; - } - if (key == Attr.CANCELLED) { - return parent.cancelled; - } - return super.scanUnsafe(key); - } - - @Override - public void onSubscribe(Subscription s) { - set(s); - } - - @Override - public void onNext(T t) { - if (won) { - actual.onNext(t); - } - else if (parent.tryWin(index)) { - won = true; - actual.onNext(t); - } - } - - @Override - public void onError(Throwable t) { - if (won) { - actual.onError(t); - } - else if (parent.tryWin(index)) { - won = true; - actual.onError(t); - } - } - - @Override - public void onComplete() { - if (won || parent.resignFromRace() == 0) { - actual.onComplete(); - } - } - - @Override - public String stepName() { - return "CloudFlux.firstNonEmpty"; - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/AccessTokenContextRelay.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/AccessTokenContextRelay.java deleted file mode 100644 index e65706ee..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/AccessTokenContextRelay.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-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.commons.security; - -/** - * Convenience class for relaying an access token from the {@link SecurityContext} to the - * {@link OAuth2ClientContext}. If successful then subsequent calls to an - * {@link OAuth2RestTemplate} using the context contained here will use the same access - * token. This is mostly useful for relaying calls to a resource server downstream to - * other resource servers. If the access token expires there is no way to refresh it, so - * expect an exception from downstream (propagating it to the caller is the best strategy, - * so they can refresh it and try again). - * - * @author Dave Syer - * - */ -public class AccessTokenContextRelay { - - /* - * private OAuth2ClientContext context; - * - * public AccessTokenContextRelay(OAuth2ClientContext context) { this.context = - * context; } - * - *//** - * Attempt to copy an access token from the security context into the oauth2 - * context. - * @return true if the token was copied - *//* - * public boolean copyToken() { if (context.getAccessToken() == null) { - * Authentication authentication = - * SecurityContextHolder.getContext().getAuthentication(); if (authentication - * != null) { Object details = authentication.getDetails(); if (details - * instanceof OAuth2AuthenticationDetails) { OAuth2AuthenticationDetails - * holder = (OAuth2AuthenticationDetails) details; String token = - * holder.getTokenValue(); DefaultOAuth2AccessToken accessToken = new - * DefaultOAuth2AccessToken(token); String tokenType = holder.getTokenType(); - * if (tokenType != null) { accessToken.setTokenType(tokenType); } - * context.setAccessToken(accessToken); return true; } } } return false; } - */ - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfiguration.java deleted file mode 100644 index c3e4e60c..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfiguration.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2012-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.commons.security; - -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 jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - -import org.springframework.boot.autoconfigure.condition.AllNestedConditions; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.HandlerInterceptor; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; - -/** - * Adds an MVC interceptor for relaying OAuth2 access tokens into the client context (if - * there is one). In this way an incoming request to a resource server can be relayed - * downstream just be using @EnableOAuth2Client and an - * OAuth2RestTemplate. An MVC interceptor is used so as to have a minimal - * impact on the call stack. If you are not using MVC you could use a custom filter or AOP - * interceptor wrapping the same call to an {@link AccessTokenContextRelay}. - * - *
- * - * N.B. an app that is using {@link UserInfoTokenServices} generally doesn't need this - * interceptor, but it doesn't hurt to include it. - * - * @author Dave Syer - * - */ -@Configuration(proxyBeanMethods = false) -// @AutoConfigureAfter(OAuth2AutoConfiguration.class) -// @ResourceServerTokenRelayAutoConfiguration.ConditionalOnOAuth2ClientInResourceServer -// @ConditionalOnClass(ResourceServerConfiguration.class) -@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) -@ConditionalOnProperty(value = "spring.cloud.mvc.token-relay.enabled", matchIfMissing = true) -public class ResourceServerTokenRelayAutoConfiguration { - - /* - * @Bean public AccessTokenContextRelay accessTokenContextRelay(OAuth2ClientContext - * context) { return new AccessTokenContextRelay(context); } - */ - - /** - * A {@link WebMvcConfigurer} for the access token interceptor. - * - * @author Dave Syer - * - */ - @Configuration(proxyBeanMethods = false) - public static class ResourceServerTokenRelayRegistrationAutoConfiguration implements WebMvcConfigurer { - - // @Autowired - // AccessTokenContextRelay accessTokenContextRelay; - - @Override - public void addInterceptors(InterceptorRegistry registry) { - registry.addInterceptor(new HandlerInterceptor() { - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { - // accessTokenContextRelay.copyToken(); - return true; - } - }); - } - - } - - @Target({ ElementType.TYPE, ElementType.METHOD }) - @Retention(RetentionPolicy.RUNTIME) - @Documented - @Conditional(OAuth2OnClientInResourceServerCondition.class) - @interface ConditionalOnOAuth2ClientInResourceServer { - - } - - private static class OAuth2OnClientInResourceServerCondition extends AllNestedConditions { - - OAuth2OnClientInResourceServerCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - /* - * @ConditionalOnBean(ResourceServerConfiguration.class) static class Server { - * - * } - * - * @ConditionalOnBean(OAuth2ClientConfiguration.class) static class Client { - * - * } - */ - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/IdUtils.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/IdUtils.java deleted file mode 100644 index fe6c2b78..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/IdUtils.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import org.springframework.core.env.PropertyResolver; -import org.springframework.util.StringUtils; - -/** - * @author Spencer Gibb - */ -public final class IdUtils { - - private static final String SEPARATOR = ":"; - - // @checkstyle:off - public static final String DEFAULT_SERVICE_ID_STRING = "${vcap.application.name:${spring.application.name:application}}:${vcap.application.instance_index:${spring.application.index:${local.server.port:${server.port:8080}}}}:${vcap.application.instance_id:${cachedrandom.${vcap.application.name:${spring.application.name:application}}.value}}"; - - public static final String DEFAULT_SERVICE_ID_WITH_ACTIVE_PROFILES_STRING = "${vcap.application.name:${spring.application.name:application}:${spring.profiles.active}}:${vcap.application.instance_index:${spring.application.index:${local.server.port:${server.port:8080}}}}:${vcap.application.instance_id:${cachedrandom.${vcap.application.name:${spring.application.name:application}}.value}}"; - - // @checkstyle:on - - private IdUtils() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - public static String getDefaultInstanceId(PropertyResolver resolver) { - return getDefaultInstanceId(resolver, true); - } - - public static String getDefaultInstanceId(PropertyResolver resolver, boolean includeHostname) { - String vcapInstanceId = resolver.getProperty("vcap.application.instance_id"); - if (StringUtils.hasText(vcapInstanceId)) { - return vcapInstanceId; - } - - String hostname = null; - if (includeHostname) { - hostname = resolver.getProperty("spring.cloud.client.hostname"); - } - String appName = resolver.getProperty("spring.application.name"); - - String namePart = combineParts(hostname, SEPARATOR, appName); - - String indexPart = resolver.getProperty("spring.application.instance_id", resolver.getProperty("server.port")); - - return combineParts(namePart, SEPARATOR, indexPart); - } - - /** - * Gets the resolved service id. - * @param resolver A property resolved - * @return A unique id that can be used to uniquely identify a service - */ - public static String getResolvedServiceId(PropertyResolver resolver) { - final String unresolvedServiceId; - // addition of active profiles at the 2nd position of the service ID breaks - // backwards-compatibility, - // so we fall back to the old implementation in case no profiles are active - if (StringUtils.hasText(resolver.getProperty("spring.profiles.active"))) { - unresolvedServiceId = getUnresolvedServiceIdWithActiveProfiles(); - } - else { - unresolvedServiceId = getUnresolvedServiceId(); - } - return resolver.resolvePlaceholders(unresolvedServiceId); - } - - /** - * Gets the unresolved template for the service id without active profiles. - * @return The combination of properties to create a unique service id. - */ - public static String getUnresolvedServiceId() { - return DEFAULT_SERVICE_ID_STRING; - } - - /** - * Gets the unresolved template for the service id including active profiles. - * @return The combination of properties to create a unique service id. - */ - public static String getUnresolvedServiceIdWithActiveProfiles() { - return DEFAULT_SERVICE_ID_WITH_ACTIVE_PROFILES_STRING; - } - - public static String combineParts(String firstPart, String separator, String secondPart) { - String combined = null; - if (firstPart != null && secondPart != null) { - combined = firstPart + separator + secondPart; - } - else if (firstPart != null) { - combined = firstPart; - } - else if (secondPart != null) { - combined = secondPart; - } - return combined; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java deleted file mode 100644 index cd5e782a..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import java.io.Closeable; -import java.io.IOException; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.UnknownHostException; -import java.nio.ByteBuffer; -import java.util.Enumeration; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * @author Spencer Gibb - */ -public class InetUtils implements Closeable { - - // TODO: maybe shutdown the thread pool if it isn't being used? - private final ExecutorService executorService; - - private final InetUtilsProperties properties; - - private final Log log = LogFactory.getLog(InetUtils.class); - - public InetUtils(final InetUtilsProperties properties) { - this.properties = properties; - this.executorService = Executors.newSingleThreadExecutor(r -> { - Thread thread = new Thread(r); - thread.setName(InetUtilsProperties.PREFIX); - thread.setDaemon(true); - return thread; - }); - } - - @Override - public void close() { - this.executorService.shutdown(); - } - - public HostInfo findFirstNonLoopbackHostInfo() { - InetAddress address = findFirstNonLoopbackAddress(); - if (address != null) { - return convertAddress(address); - } - HostInfo hostInfo = new HostInfo(); - hostInfo.setHostname(this.properties.getDefaultHostname()); - hostInfo.setIpAddress(this.properties.getDefaultIpAddress()); - return hostInfo; - } - - public InetAddress findFirstNonLoopbackAddress() { - InetAddress result = null; - try { - int lowest = Integer.MAX_VALUE; - for (Enumeration nics = NetworkInterface.getNetworkInterfaces(); nics - .hasMoreElements();) { - NetworkInterface ifc = nics.nextElement(); - if (ifc.isUp()) { - this.log.trace("Testing interface: " + ifc.getDisplayName()); - if (ifc.getIndex() < lowest || result == null) { - lowest = ifc.getIndex(); - } - else if (result != null) { - continue; - } - - // @formatter:off - if (!ignoreInterface(ifc.getDisplayName())) { - for (Enumeration addrs = ifc - .getInetAddresses(); addrs.hasMoreElements();) { - InetAddress address = addrs.nextElement(); - if (address instanceof Inet4Address - && !address.isLoopbackAddress() - && isPreferredAddress(address)) { - this.log.trace("Found non-loopback interface: " - + ifc.getDisplayName()); - result = address; - } - } - } - // @formatter:on - } - } - } - catch (IOException ex) { - this.log.error("Cannot get first non-loopback address", ex); - } - - if (result != null) { - return result; - } - - try { - return InetAddress.getLocalHost(); - } - catch (UnknownHostException e) { - this.log.warn("Unable to retrieve localhost"); - } - - return null; - } - - // For testing. - boolean isPreferredAddress(InetAddress address) { - - if (this.properties.isUseOnlySiteLocalInterfaces()) { - final boolean siteLocalAddress = address.isSiteLocalAddress(); - if (!siteLocalAddress) { - this.log.trace("Ignoring address: " + address.getHostAddress()); - } - return siteLocalAddress; - } - final List preferredNetworks = this.properties.getPreferredNetworks(); - if (preferredNetworks.isEmpty()) { - return true; - } - for (String regex : preferredNetworks) { - final String hostAddress = address.getHostAddress(); - if (hostAddress.matches(regex) || hostAddress.startsWith(regex)) { - return true; - } - } - this.log.trace("Ignoring address: " + address.getHostAddress()); - return false; - } - - // For testing - boolean ignoreInterface(String interfaceName) { - for (String regex : this.properties.getIgnoredInterfaces()) { - if (interfaceName.matches(regex)) { - this.log.trace("Ignoring interface: " + interfaceName); - return true; - } - } - return false; - } - - public HostInfo convertAddress(final InetAddress address) { - HostInfo hostInfo = new HostInfo(); - Future result = this.executorService.submit(address::getHostName); - - String hostname; - try { - hostname = result.get(this.properties.getTimeoutSeconds(), TimeUnit.SECONDS); - } - catch (Exception e) { - this.log.info("Cannot determine local hostname"); - hostname = "localhost"; - } - hostInfo.setHostname(hostname); - hostInfo.setIpAddress(address.getHostAddress()); - return hostInfo; - } - - /** - * Host information pojo. - */ - public static class HostInfo { - - /** - * Should override the host info. - */ - public boolean override; - - private String ipAddress; - - private String hostname; - - public HostInfo(String hostname) { - this.hostname = hostname; - } - - public HostInfo() { - } - - public int getIpAddressAsInt() { - InetAddress inetAddress = null; - String host = this.ipAddress; - if (host == null) { - host = this.hostname; - } - try { - inetAddress = InetAddress.getByName(host); - } - catch (final UnknownHostException e) { - throw new IllegalArgumentException(e); - } - return ByteBuffer.wrap(inetAddress.getAddress()).getInt(); - } - - public boolean isOverride() { - return this.override; - } - - public void setOverride(boolean override) { - this.override = override; - } - - public String getIpAddress() { - return this.ipAddress; - } - - public void setIpAddress(String ipAddress) { - this.ipAddress = ipAddress; - } - - public String getHostname() { - return this.hostname; - } - - public void setHostname(String hostname) { - this.hostname = hostname; - } - - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java deleted file mode 100644 index 65ea4257..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import java.net.InetAddress; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Properties for {@link InetUtils}. - * - * @author Spencer Gibb - */ -@ConfigurationProperties(InetUtilsProperties.PREFIX) -public class InetUtilsProperties { - - /** - * Prefix for the Inet Utils properties. - */ - public static final String PREFIX = "spring.cloud.inetutils"; - - /** - * The default hostname. Used in case of errors. - */ - private String defaultHostname = "localhost"; - - /** - * The default IP address. Used in case of errors. - */ - private String defaultIpAddress = "127.0.0.1"; - - /** - * Timeout, in seconds, for calculating hostname. - */ - @Value("${spring.util.timeout.sec:${SPRING_UTIL_TIMEOUT_SEC:1}}") - private int timeoutSeconds = 1; - - /** - * List of Java regular expressions for network interfaces that will be ignored. - */ - private List ignoredInterfaces = new ArrayList<>(); - - /** - * Whether to use only interfaces with site local addresses. See - * {@link InetAddress#isSiteLocalAddress()} for more details. - */ - private boolean useOnlySiteLocalInterfaces = false; - - /** - * List of Java regular expressions for network addresses that will be preferred. - */ - private List preferredNetworks = new ArrayList<>(); - - public static String getPREFIX() { - return PREFIX; - } - - public String getDefaultHostname() { - return this.defaultHostname; - } - - public void setDefaultHostname(String defaultHostname) { - this.defaultHostname = defaultHostname; - } - - public String getDefaultIpAddress() { - return this.defaultIpAddress; - } - - public void setDefaultIpAddress(String defaultIpAddress) { - this.defaultIpAddress = defaultIpAddress; - } - - public int getTimeoutSeconds() { - return this.timeoutSeconds; - } - - public void setTimeoutSeconds(int timeoutSeconds) { - this.timeoutSeconds = timeoutSeconds; - } - - public List getIgnoredInterfaces() { - return this.ignoredInterfaces; - } - - public void setIgnoredInterfaces(List ignoredInterfaces) { - this.ignoredInterfaces = ignoredInterfaces; - } - - public boolean isUseOnlySiteLocalInterfaces() { - return this.useOnlySiteLocalInterfaces; - } - - public void setUseOnlySiteLocalInterfaces(boolean useOnlySiteLocalInterfaces) { - this.useOnlySiteLocalInterfaces = useOnlySiteLocalInterfaces; - } - - public List getPreferredNetworks() { - return this.preferredNetworks; - } - - public void setPreferredNetworks(List preferredNetworks) { - this.preferredNetworks = preferredNetworks; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/SpringFactoryImportSelector.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/SpringFactoryImportSelector.java deleted file mode 100644 index d8237adf..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/SpringFactoryImportSelector.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.context.EnvironmentAware; -import org.springframework.context.annotation.DeferredImportSelector; -import org.springframework.core.GenericTypeResolver; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.env.Environment; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.util.Assert; - -/** - * Selects configurations to load, defined by the generic type T. Loads implementations - * using {@link SpringFactoriesLoader}. - * - * @param type of annotation class - * @author Spencer Gibb - * @author Dave Syer - */ -public abstract class SpringFactoryImportSelector - implements DeferredImportSelector, BeanClassLoaderAware, EnvironmentAware { - - private final Log log = LogFactory.getLog(SpringFactoryImportSelector.class); - - private ClassLoader beanClassLoader; - - private Class annotationClass; - - private Environment environment; - - @SuppressWarnings("unchecked") - protected SpringFactoryImportSelector() { - this.annotationClass = (Class) GenericTypeResolver.resolveTypeArgument(this.getClass(), - SpringFactoryImportSelector.class); - } - - @Override - public String[] selectImports(AnnotationMetadata metadata) { - if (!isEnabled()) { - return new String[0]; - } - AnnotationAttributes attributes = AnnotationAttributes - .fromMap(metadata.getAnnotationAttributes(this.annotationClass.getName(), true)); - - Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is " + metadata.getClassName() - + " annotated with @" + getSimpleName() + "?"); - - // Find all possible auto configuration classes, filtering duplicates - List factories = new ArrayList<>(new LinkedHashSet<>( - SpringFactoriesLoader.loadFactoryNames(this.annotationClass, this.beanClassLoader))); - - if (factories.isEmpty() && !hasDefaultFactory()) { - throw new IllegalStateException("Annotation @" + getSimpleName() - + " found, but there are no implementations. Did you forget to include a starter?"); - } - - if (factories.size() > 1) { - // there should only ever be one DiscoveryClient, but there might be more than - // one factory - this.log.warn("More than one implementation " + "of @" + getSimpleName() - + " (now relying on @Conditionals to pick one): " + factories); - } - - return factories.toArray(new String[factories.size()]); - } - - protected boolean hasDefaultFactory() { - return false; - } - - protected abstract boolean isEnabled(); - - protected String getSimpleName() { - return this.annotationClass.getSimpleName(); - } - - protected Class getAnnotationClass() { - return this.annotationClass; - } - - protected Environment getEnvironment() { - return this.environment; - } - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - @Override - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/TaskSchedulerWrapper.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/TaskSchedulerWrapper.java deleted file mode 100644 index 20685db6..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/TaskSchedulerWrapper.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.util.Assert; - -/** - * Wrapper that downstream projects can use to keep {@link ThreadPoolTaskScheduler} local. - * - * Implementation adapted from Spring Vault. - * - */ -public class TaskSchedulerWrapper implements InitializingBean, DisposableBean { - - private final T taskScheduler; - - public TaskSchedulerWrapper(T taskScheduler) { - Assert.notNull(taskScheduler, "ThreadPoolTaskScheduler must not be null"); - this.taskScheduler = taskScheduler; - } - - public T getTaskScheduler() { - return this.taskScheduler; - } - - @Override - public void destroy() throws Exception { - if (taskScheduler instanceof DisposableBean) { - ((DisposableBean) this.taskScheduler).destroy(); - } - } - - @Override - public void afterPropertiesSet() throws Exception { - if (taskScheduler instanceof InitializingBean) { - ((InitializingBean) this.taskScheduler).afterPropertiesSet(); - } - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/UtilAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/UtilAutoConfiguration.java deleted file mode 100644 index 349111de..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/UtilAutoConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(value = "spring.cloud.util.enabled", matchIfMissing = true) -@AutoConfigureOrder(0) -@EnableConfigurationProperties -public class UtilAutoConfiguration { - - @Bean - public InetUtilsProperties inetUtilsProperties() { - return new InetUtilsProperties(); - } - - @Bean - @ConditionalOnMissingBean - public InetUtils inetUtils(InetUtilsProperties properties) { - return new InetUtils(properties); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java deleted file mode 100644 index 4306d43b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.Arrays; -import java.util.List; - -/** - * Exception thrown when the current setup is not compatible. - * - * @author Marcin Grzejszczak - * @author Olga Maciaszek-Sharma - * @since 1.3.6 - */ -class CompatibilityNotMetException extends RuntimeException { - - final List results; - - CompatibilityNotMetException(List results) { - super("Spring Cloud/ Spring Boot version compatibility checks have failed: " - + Arrays.toString(results.toArray())); - this.results = results; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java deleted file mode 100644 index ba50a484..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityNotMetFailureAnalyzer.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.List; - -import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; -import org.springframework.boot.diagnostics.FailureAnalysis; - -/** - * Analyzer for the {@link CompatibilityNotMetException}. Prints a list of found issues - * and actions that should be taken to fix them. - * - * @author Marcin Grzejszczak - * @since 1.3.6 - */ -public final class CompatibilityNotMetFailureAnalyzer extends AbstractFailureAnalyzer { - - @Override - protected FailureAnalysis analyze(Throwable rootFailure, CompatibilityNotMetException cause) { - return new FailureAnalysis(getDescription(cause), getAction(cause), cause); - } - - private String getDescription(CompatibilityNotMetException ex) { - return String.format( - "Your project setup is incompatible with our requirements " + "due to following reasons:%s", - descriptions(ex.results)); - } - - private String descriptions(List results) { - StringBuilder builder = new StringBuilder("\n\n"); - for (VerificationResult result : results) { - builder.append("- ").append(result.description).append("\n"); - } - return builder.toString(); - } - - private String getAction(CompatibilityNotMetException ex) { - return String.format("Consider applying the following actions:%s", actions(ex.results)); - } - - private String actions(List results) { - StringBuilder builder = new StringBuilder("\n\n"); - for (VerificationResult result : results) { - builder.append("- ").append(result.action).append("\n"); - } - return builder.toString(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java deleted file mode 100644 index d242c143..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityPredicate.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -/** - * So that can be used for jdk 7 - otherwise we would use a predicate. - * - * @author Marcin Grzejszczak - */ -interface CompatibilityPredicate { - - boolean isCompatible(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java deleted file mode 100644 index f9a0c3f5..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifier.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -/** - * Implementations will verify the compatibility and return a result that says whether the - * check is compatible or not for the current release train. - * - * @author Marcin Grzejszczak - * @since 1.3.6 - */ -interface CompatibilityVerifier { - - VerificationResult verify(); - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java deleted file mode 100644 index d9e758ad..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.List; - -import org.springframework.boot.autoconfigure.AutoConfigureOrder; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * {@link EnableAutoConfiguration Auto-configuration} that fails the build fast for - * incompatible versions of dependencies (e.g. invalid version of Boot). - * - * @author Marcin Grzejszczak - * @since 1.3.6 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(value = "spring.cloud.compatibility-verifier.enabled", matchIfMissing = true) -@AutoConfigureOrder(0) -@EnableConfigurationProperties(CompatibilityVerifierProperties.class) -public class CompatibilityVerifierAutoConfiguration { - - @Bean - CompositeCompatibilityVerifier compositeCompatibilityVerifier(List verifiers) { - CompositeCompatibilityVerifier verifier = new CompositeCompatibilityVerifier(verifiers); - verifier.verifyDependencies(); - return verifier; - } - - @Bean - SpringBootVersionVerifier springBootVersionVerifier(CompatibilityVerifierProperties properties) { - return new SpringBootVersionVerifier(properties.getCompatibleBootVersions()); - } - - @Bean - SleuthPresentVerifier sleuthPresentVerifier() { - return new SleuthPresentVerifier(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java deleted file mode 100644 index 26fc65e8..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompatibilityVerifierProperties.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.List; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * @author Marcin Grzejszczak - */ -@ConfigurationProperties("spring.cloud.compatibility-verifier") -public class CompatibilityVerifierProperties { - - /** - * Enables creation of Spring Cloud compatibility verification. - */ - private boolean enabled; - - /** - * Default accepted versions for the Spring Boot dependency. You can set {@code x} for - * the patch version if you don't want to specify a concrete value. Example: - * {@code 3.4.x} - */ - private List compatibleBootVersions = List.of("3.2.x"); - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public List getCompatibleBootVersions() { - return this.compatibleBootVersions; - } - - public void setCompatibleBootVersions(List compatibleBootVersions) { - this.compatibleBootVersions = compatibleBootVersions; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java deleted file mode 100644 index fb1127c6..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/CompositeCompatibilityVerifier.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Iterates over {@link CompatibilityVerifier} and prepares a report if exceptions were - * found. - */ -class CompositeCompatibilityVerifier { - - private static final Log log = LogFactory.getLog(CompositeCompatibilityVerifier.class); - - private final List verifiers; - - CompositeCompatibilityVerifier(List verifiers) { - this.verifiers = verifiers; - } - - void verifyDependencies() { - List errors = verifierErrors(); - if (errors.isEmpty()) { - if (log.isDebugEnabled()) { - log.debug("All conditions are passing"); - } - return; - } - throw new CompatibilityNotMetException(errors); - } - - private List verifierErrors() { - List errors = new ArrayList<>(); - for (CompatibilityVerifier verifier : this.verifiers) { - VerificationResult result = verifier.verify(); - if (result.isNotCompatible()) { - errors.add(result); - } - } - return errors; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SSLContextFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SSLContextFactory.java deleted file mode 100644 index 74cc5d8e..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SSLContextFactory.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2017-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.io.IOException; -import java.io.InputStream; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.UnrecoverableKeyException; - -import javax.net.ssl.SSLContext; - -import org.apache.hc.core5.ssl.SSLContextBuilder; - -import org.springframework.core.io.Resource; - -public class SSLContextFactory { - - private TlsProperties properties; - - public SSLContextFactory(TlsProperties properties) { - this.properties = properties; - } - - public SSLContext createSSLContext() throws GeneralSecurityException, IOException { - SSLContextBuilder builder = new SSLContextBuilder(); - char[] keyPassword = properties.keyPassword(); - KeyStore keyStore = createKeyStore(); - - try { - builder.loadKeyMaterial(keyStore, keyPassword); - } - catch (UnrecoverableKeyException e) { - if (keyPassword.length == 0) { - // Retry if empty password, see - // https://rt.openssl.org/Ticket/Display.html?id=1497&user=guest&pass=guest - builder.loadKeyMaterial(keyStore, new char[] { '\0' }); - } - else { - throw e; - } - } - - KeyStore trust = createTrustStore(); - if (trust != null) { - builder.loadTrustMaterial(trust, null); - } - - return builder.build(); - } - - public KeyStore createKeyStore() throws GeneralSecurityException, IOException { - if (properties.getKeyStore() == null) { - throw new KeyStoreException("Keystore not specified."); - } - if (!properties.getKeyStore().exists()) { - throw new KeyStoreException("Keystore not exists: " + properties.getKeyStore()); - } - - KeyStore result = KeyStore.getInstance(properties.getKeyStoreType()); - char[] keyStorePassword = properties.keyStorePassword(); - - try { - loadKeyStore(result, properties.getKeyStore(), keyStorePassword); - } - catch (IOException e) { - // Retry if empty password, see - // https://rt.openssl.org/Ticket/Display.html?id=1497&user=guest&pass=guest - if (keyStorePassword.length == 0) { - loadKeyStore(result, properties.getKeyStore(), new char[] { '\0' }); - } - else { - throw e; - } - } - - return result; - } - - private static void loadKeyStore(KeyStore keyStore, Resource keyStoreResource, char[] keyStorePassword) - throws IOException, GeneralSecurityException { - try (InputStream inputStream = keyStoreResource.getInputStream()) { - keyStore.load(inputStream, keyStorePassword); - } - } - - public KeyStore createTrustStore() throws GeneralSecurityException, IOException { - if (properties.getTrustStore() == null) { - return null; - } - if (!properties.getTrustStore().exists()) { - throw new KeyStoreException("KeyStore not exists: " + properties.getTrustStore()); - } - - KeyStore result = KeyStore.getInstance(properties.getTrustStoreType()); - try (InputStream input = properties.getTrustStore().getInputStream()) { - result.load(input, properties.trustStorePassword()); - } - return result; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SleuthPresentVerifier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SleuthPresentVerifier.java deleted file mode 100644 index 2a9e10d5..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SleuthPresentVerifier.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import org.springframework.util.ClassUtils; - -/** - * Verifies if Spring Cloud Sleuth is present on the classpath. - */ -class SleuthPresentVerifier implements CompatibilityVerifier { - - private static final String TRACER_CLASS = "org.springframework.cloud.sleuth.Tracer"; - - private static final String ERROR_DESCRIPTION = "Spring Cloud Sleuth is not compatible with this Spring Cloud release train"; - - private static final String ACTION = """ - Migrate from Spring Cloud Sleuth to Micrometer Tracing . - You can check the Sleuth 3.1 Migration Guide over here [https://github.com/micrometer-metrics/tracing/wiki/Spring-Cloud-Sleuth-3.1-Migration-Guide].\s - If you want to disable this check, just set the property [spring.cloud.compatibility-verifier.enabled=false]"""; - - @Override - public VerificationResult verify() { - boolean present = sleuthPresent(); - if (!present) { - return VerificationResult.compatible(); - } - return VerificationResult.notCompatible(ERROR_DESCRIPTION, ACTION); - } - - boolean sleuthPresent() { - return ClassUtils.isPresent(TRACER_CLASS, null); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java deleted file mode 100644 index 4f9a4a3b..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/SpringBootVersionVerifier.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.SpringBootVersion; -import org.springframework.boot.autoconfigure.validation.ValidationConfigurationCustomizer; -import org.springframework.util.StringUtils; - -/** - * Verifies if Spring Boot has proper version. - */ -class SpringBootVersionVerifier implements CompatibilityVerifier { - - private static final Log log = LogFactory.getLog(SpringBootVersionVerifier.class); - - final Map ACCEPTED_VERSIONS = new HashMap<>() { - { - this.put("3.2", is3_2()); - } - }; - - private final List acceptedVersions; - - SpringBootVersionVerifier(List acceptedVersions) { - this.acceptedVersions = acceptedVersions; - } - - @Override - public VerificationResult verify() { - boolean matches = springBootVersionMatches(); - if (matches) { - return VerificationResult.compatible(); - } - return VerificationResult.notCompatible(errorDescription(), action()); - } - - private Boolean bootVersionFromManifest(String s) { - String version = getVersionFromManifest(); - if (log.isDebugEnabled()) { - log.debug("Version found in Boot manifest [" + version + "]"); - } - if (!StringUtils.hasText(version)) { - log.info("Cannot check Boot version from manifest"); - return null; - } - return version.startsWith(stripWildCardFromVersion(s)); - } - - String getVersionFromManifest() { - return SpringBootVersion.getVersion(); - } - - CompatibilityPredicate is3_2() { - return new CompatibilityPredicate() { - - @Override - public String toString() { - return "Predicate for Boot 3.2"; - } - - @Override - public boolean isCompatible() { - try { - Class.forName("org.springframework.boot.autoconfigure.web.client.RestClientSsl"); - return true; - } - catch (ClassNotFoundException e) { - return false; - } - - } - }; - } - - CompatibilityPredicate is3_1() { - return new CompatibilityPredicate() { - - @Override - public String toString() { - return "Predicate for Boot 3.1"; - } - - @Override - public boolean isCompatible() { - try { - // since 3.1 - ValidationConfigurationCustomizer.class.getMethod("setIgnoreRegistrationFailure", boolean.class); - return true; - - } - catch (NoSuchMethodException e) { - return false; - } - - } - }; - } - - private String errorDescription() { - String versionFromManifest = getVersionFromManifest(); - if (StringUtils.hasText(versionFromManifest)) { - return String.format("Spring Boot [%s] is not compatible with this Spring Cloud release train", - versionFromManifest); - } - return "Spring Boot is not compatible with this Spring Cloud release train"; - } - - private String action() { - return String.format( - """ - Change Spring Boot version to one of the following versions %s . - You can find the latest Spring Boot versions here [%s].\s - If you want to learn more about the Spring Cloud Release train compatibility, you can visit this page [%s] and check the [Release Trains] section. - If you want to disable this check, just set the property [spring.cloud.compatibility-verifier.enabled=false]""", - this.acceptedVersions, "https://spring.io/projects/spring-boot#learn", - "https://spring.io/projects/spring-cloud#overview"); - } - - private boolean springBootVersionMatches() { - for (String acceptedVersion : this.acceptedVersions) { - Boolean versionFromManifest = bootVersionFromManifest(acceptedVersion); - // if manifest has version and matches, return - // otherwise need to check other versions in list - // if all return false, then the return false at end will apply - if (versionFromManifest != null && versionFromManifest) { - return true; - } - else if (versionFromManifest == null) { - // only check these if the manifest does not have a version. - // otherwise this could lead to false positives for future - // versions of boot - CompatibilityPredicate predicate = this.ACCEPTED_VERSIONS - .get(stripWildCardFromVersion(acceptedVersion)); - if (predicate != null && predicate.isCompatible()) { - if (log.isDebugEnabled()) { - log.debug("Predicate [" + predicate + "] was matched"); - } - return true; - } - } - } - return false; - } - - static String stripWildCardFromVersion(String version) { - if (version.endsWith(".x")) { - return version.substring(0, version.indexOf(".x")); - } - return version; - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/TlsProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/TlsProperties.java deleted file mode 100644 index 0eca22c4..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/TlsProperties.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2017-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.Map; - -import org.springframework.core.io.Resource; - -/** - * Common client TLS properties. - */ -public class TlsProperties { - - private static final String DEFAULT_STORE_TYPE = "PKCS12"; - - private static final Map EXTENSION_STORE_TYPES = extTypes(); - - private boolean enabled; - - private Resource keyStore; - - private String keyStoreType; - - private String keyStorePassword = ""; - - private String keyPassword = ""; - - private Resource trustStore; - - private String trustStoreType; - - private String trustStorePassword = ""; - - private static Map extTypes() { - - return Map.of("p12", "PKCS12", "pfx", "PKCS12", "jks", "JKS"); - } - - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Resource getKeyStore() { - return keyStore; - } - - public void setKeyStore(Resource keyStore) { - this.keyStore = keyStore; - } - - public String getKeyStoreType() { - if (keyStore != null && keyStoreType == null) { - keyStoreType = storeTypeOf(keyStore); - } - return keyStoreType; - } - - public void setKeyStoreType(String keyStoreType) { - this.keyStoreType = keyStoreType; - } - - public String getKeyStorePassword() { - return keyStorePassword; - } - - public void setKeyStorePassword(String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } - - public char[] keyStorePassword() { - return keyStorePassword.toCharArray(); - } - - public String getKeyPassword() { - return keyPassword; - } - - public void setKeyPassword(String keyPassword) { - this.keyPassword = keyPassword; - } - - public char[] keyPassword() { - return keyPassword.toCharArray(); - } - - public Resource getTrustStore() { - return trustStore; - } - - public void setTrustStore(Resource trustStore) { - this.trustStore = trustStore; - } - - public String getTrustStoreType() { - if (trustStore != null && trustStoreType == null) { - trustStoreType = storeTypeOf(trustStore); - } - return trustStoreType; - } - - public void setTrustStoreType(String trustStoreType) { - this.trustStoreType = trustStoreType; - } - - public String getTrustStorePassword() { - return trustStorePassword; - } - - public void setTrustStorePassword(String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } - - public char[] trustStorePassword() { - return trustStorePassword.toCharArray(); - } - - private String storeTypeOf(Resource resource) { - String extension = fileExtensionOf(resource); - String type = EXTENSION_STORE_TYPES.get(extension); - - return (type == null) ? DEFAULT_STORE_TYPE : type; - } - - private String fileExtensionOf(Resource resource) { - String name = resource.getFilename(); - int index = name.lastIndexOf('.'); - - return index < 0 ? "" : name.substring(index + 1).toLowerCase(); - } - -} diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java deleted file mode 100644 index 55aa64fc..00000000 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/configuration/VerificationResult.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.Objects; - -import org.springframework.core.style.ToStringCreator; -import org.springframework.util.StringUtils; - -/** - * @author Marcin Grzejszczak - * @author Olga Maciaszek-Sharma - */ -final class VerificationResult { - - final String description; - - final String action; - - // if OK - private VerificationResult() { - this.description = ""; - this.action = ""; - } - - // if not OK - private VerificationResult(String errorDescription, String action) { - this.description = errorDescription; - this.action = action; - } - - static VerificationResult compatible() { - return new VerificationResult(); - } - - static VerificationResult notCompatible(String errorDescription, String action) { - return new VerificationResult(errorDescription, action); - } - - boolean isNotCompatible() { - return StringUtils.hasText(this.description) || StringUtils.hasText(this.action); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof VerificationResult that)) { - return false; - } - return description.equals(that.description) && action.equals(that.action); - } - - @Override - public int hashCode() { - return Objects.hash(description, action); - } - - @Override - public String toString() { - ToStringCreator toStringCreator = new ToStringCreator(this); - toStringCreator.append("description", description); - toStringCreator.append("action", action); - return toStringCreator.toString(); - } - -} diff --git a/spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 9bdc61cd..00000000 --- a/spring-cloud-commons/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,175 +0,0 @@ -{ - "properties": [ - { - "defaultValue": "true", - "name": "spring.cloud.refresh.enabled", - "description": "Enables autoconfiguration for the refresh scope and associated features.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.httpclientfactories.apache.enabled", - "description": "Enables creation of Apache Http Client factory beans.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": "true", - "name": "spring.cloud.httpclientfactories.ok.enabled", - "description": "Enables creation of OK Http Client factory beans.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.util.enabled", - "description": "Enables creation of Spring Cloud utility beans.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.features.enabled", - "description": "Enables the features endpoint.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.discovery.enabled", - "description": "Enables discovery client health indicators.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.discovery.client.composite-indicator.enabled", - "description": "Enables discovery client composite health indicator.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": false, - "name": "management.endpoint.env.post.enabled", - "description": "Enables writable environment endpoint.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.retry.enabled", - "description": "Enables LoadBalancer retries.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.health-check.initial-delay", - "defaultValue": 0, - "description": "Initial delay value for the HealthCheck scheduler.", - "type": "java.time.Duration" - }, - { - "name": "spring.cloud.loadbalancer.health-check.interval ", - "defaultValue": "25s", - "description": "Interval for rerunning the HealthCheck scheduler.", - "type": "java.time.Duration" - }, - { - "name": "spring.cloud.loadbalancer.health-check.path", - "description": "Path at which the health-check request should be made. Can be set up per `serviceId`. A `default` value can be set up as well. If none is set up, `/actuator/health` will be used.", - "type": "java.util.Map" - }, - { - "name": "spring.cloud.loadbalancer.health-check.port", - "description": "Path at which the health-check request should be made. If none is set, the port under which the requested service is available at the service instance.", - "type": "java.lang.Integer" - }, - { - "name": "spring.cloud.loadbalancer.health-check.refetch-instances", - "defaultValue": false, - "description": "Indicates whether the instances should be refetched by the `HealthCheckServiceInstanceListSupplier`. This can be used if the instances can be updated and the underlying delegate does not provide an ongoing flux.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.health-check.refetch-instances-interval", - "defaultValue": "25s", - "description": "Interval for refetching available service instances.", - "type": "java.time.Duration" - }, - { - "name": "spring.cloud.loadbalancer.health-check.repeat-health-check", - "defaultValue": true, - "description": "Indicates whether health checks should keep repeating. It might be useful to set it to `false` if periodically refetching the instances, as every refetch will also trigger a healthcheck.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.retry.backoff.enabled", - "defaultValue": false, - "description": "Indicates whether Reactor Retry backoffs should be applied.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.retry.backoff.jitter", - "defaultValue": 0.5, - "description": "Used to set `RetryBackoffSpec.jitter`.", - "type": "java.lang.Double" - }, - { - "name": "spring.cloud.loadbalancer.retry.backoff.max-backoff", - "defaultValue": "Long.MAX ms", - "description": "Used to set `RetryBackoffSpec.maxBackoff`.", - "type": "java.time.Duration" - }, - { - "name": "spring.cloud.loadbalancer.retry.backoff.min-backoff", - "defaultValue": "5 ms", - "description": "Used to set `RetryBackoffSpec#minBackoff`.", - "type": "java.time.Duration" - }, - { - "name": "spring.cloud.loadbalancer.retry.max-retries-on-next-service-instance", - "defaultValue": 1, - "description": "Number of retries to be executed on the next `ServiceInstance`. A `ServiceInstance` is chosen before each retry call.", - "type": "java.lang.Integer" - }, - { - "name": "spring.cloud.loadbalancer.retry.max-retries-on-same-service-instance", - "defaultValue": 0, - "description": "Number of retries to be executed on the same `ServiceInstance`.", - "type": "java.lang.Integer" - }, - { - "name": "spring.cloud.loadbalancer.retry.retry-on-all-operations", - "defaultValue": false, - "description": "Indicates retries should be attempted on operations other than `HttpMethod.GET`.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.retry.retryable-status-codes", - "defaultValue": "{}", - "description": "A `Set` of status codes that should trigger a retry.", - "type": "java.util.Set" - }, - { - "name": "spring.cloud.loadbalancer.sticky-session.add-service-instance-cookie", - "defaultValue": false, - "description": "Indicates whether a cookie with the newly selected instance should be added by LoadBalancer.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.sticky-session.instance-id-cookie-name", - "defaultValue": "sc-lb-instance-id", - "description": "The name of the cookie holding the preferred instance id.", - "type": "java.lang.String" - }, - { - "name": "spring.cloud.loadbalancer.x-forwarded.enabled", - "defaultValue": false, - "description": "To Enable X-Forwarded Headers.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.retry.retry-on-all-exceptions", - "defaultValue": false, - "description": "Indicates retries should be attempted for all exceptions, not only those specified in `retryableExceptions`.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.retry.retryable-exceptions", - "defaultValue": "{}", - "description": "A `Set` of `Throwable` classes that should trigger a retry.", - "type": "java.util.Set" - } - ] -} diff --git a/spring-cloud-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-commons/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 69967501..00000000 --- a/spring-cloud-commons/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,6 +0,0 @@ -# Environment Post Processors -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.cloud.client.HostInfoEnvironmentPostProcessor -# Failure Analyzers -org.springframework.boot.diagnostics.FailureAnalyzer=\ -org.springframework.cloud.configuration.CompatibilityNotMetFailureAnalyzer diff --git a/spring-cloud-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 721734ba..00000000 --- a/spring-cloud-commons/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,17 +0,0 @@ -org.springframework.cloud.client.CommonsClientAutoConfiguration -org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration -org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration -org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration -org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration -org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration -org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration -org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration -org.springframework.cloud.client.loadbalancer.LoadBalancerDefaultMappingsProviderAutoConfiguration -org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration -org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerClientAutoConfiguration -org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration -org.springframework.cloud.commons.util.UtilAutoConfiguration -org.springframework.cloud.configuration.CompatibilityVerifierAutoConfiguration -org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration -org.springframework.cloud.commons.security.ResourceServerTokenRelayAutoConfiguration -org.springframework.cloud.commons.config.CommonsConfigAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/CommonsClientAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/CommonsClientAutoConfigurationTests.java deleted file mode 100644 index 96d04f36..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/CommonsClientAutoConfigurationTests.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.actuator.FeaturesEndpoint; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicator; -import org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthContributor; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.context.annotation.Bean; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Tim Ysewyn - */ -public class CommonsClientAutoConfigurationTests { - - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(CommonsClientAutoConfiguration.class, - SimpleDiscoveryClientAutoConfiguration.class, UtilAutoConfiguration.class)); - - @Test - public void beansCreatedNormally() { - applicationContextRunner.withConfiguration(AutoConfigurations.of(HealthEndpointAutoConfiguration.class)) - .withPropertyValues("management.endpoints.web.exposure.include=features").run(ctxt -> { - then(ctxt.getBean(DiscoveryClientHealthIndicator.class)).isNotNull(); - then(ctxt.getBean(DiscoveryCompositeHealthContributor.class)).isNotNull(); - then(ctxt.getBean(FeaturesEndpoint.class)).isNotNull(); - then(ctxt.getBeansOfType(HasFeatures.class).values()).isNotEmpty(); - }); - } - - @Test - public void disableAll() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.enabled=false", - "management.endpoints.web.exposure.include=features").run(ctxt -> { - assertThat(ctxt).doesNotHaveBean(DiscoveryClientHealthIndicator.class); - assertThat(ctxt).doesNotHaveBean(DiscoveryCompositeHealthContributor.class); - then(ctxt.getBean(FeaturesEndpoint.class)).isNotNull(); - // features actuator is independent of discovery - assertThat(ctxt).doesNotHaveBean(HasFeatures.class); - }); - } - - @Test - public void disableBlocking() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.blocking.enabled=false", - "management.endpoints.web.exposure.include=features").run(ctxt -> { - assertThat(ctxt).doesNotHaveBean(DiscoveryClientHealthIndicator.class); - assertThat(ctxt).doesNotHaveBean(DiscoveryCompositeHealthContributor.class); - then(ctxt.getBean(FeaturesEndpoint.class)).isNotNull(); - // features actuator is independent of discovery - assertThat(ctxt).doesNotHaveBean(HasFeatures.class); - }); - } - - @Test - public void disableAllIndividually() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.client.health-indicator.enabled=false", - "spring.cloud.discovery.client.composite-indicator.enabled=false", - "spring.cloud.features.enabled=false").run(ctxt -> { - assertThat(ctxt).doesNotHaveBean(DiscoveryClientHealthIndicator.class); - assertThat(ctxt).doesNotHaveBean(DiscoveryCompositeHealthContributor.class); - assertThat(ctxt).doesNotHaveBean(FeaturesEndpoint.class); - }); - } - - @Test - public void disableHealthIndicator() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.client.health-indicator.enabled=false") - .run(ctxt -> { - assertThat(ctxt).doesNotHaveBean(DiscoveryClientHealthIndicator.class); - assertThat(ctxt).doesNotHaveBean(DiscoveryCompositeHealthContributor.class); - }); - } - - @Test - public void worksWithoutActuator() { - applicationContextRunner.withClassLoader(new FilteredClassLoader("org.springframework.boot.actuate")) - .run(context -> { - assertThat(context).doesNotHaveBean(DiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(DiscoveryCompositeHealthContributor.class); - then(context.getBeansOfType(HasFeatures.class).values()).isEmpty(); - }); - } - - @Test - public void conditionalOnDiscoveryEnabledWorks() { - applicationContextRunner.withUserConfiguration(DiscoveryEnabledConfig.class) - .withPropertyValues("spring.cloud.discovery.enabled=false") - .run(context -> assertThat(context).doesNotHaveBean(TestBean.class)); - applicationContextRunner.withUserConfiguration(DiscoveryEnabledConfig.class) - .withPropertyValues("spring.cloud.discovery.enabled=true") - .run(context -> assertThat(context.getBean(TestBean.class)).isNotNull()); - } - - @Test - public void conditionalOnBlockingDiscoveryEnabledWorks() { - applicationContextRunner.withUserConfiguration(BlockingDiscoveryEnabledConfig.class) - .withPropertyValues("spring.cloud.discovery.blocking.enabled=false") - .run(context -> assertThat(context).doesNotHaveBean(TestBean.class)); - applicationContextRunner.withUserConfiguration(BlockingDiscoveryEnabledConfig.class) - .withPropertyValues("spring.cloud.discovery.blocking.enabled=true") - .run(context -> assertThat(context.getBean(TestBean.class)).isNotNull()); - } - - @TestConfiguration - @ConditionalOnDiscoveryEnabled - protected static class DiscoveryEnabledConfig { - - @Bean - TestBean testBean() { - return new TestBean(); - } - - } - - @TestConfiguration - @ConditionalOnBlockingDiscoveryEnabled - protected static class BlockingDiscoveryEnabledConfig { - - @Bean - TestBean testBean() { - return new TestBean(); - } - - } - - private static class TestBean { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessorTests.java deleted file mode 100644 index a319673f..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/HostInfoEnvironmentPostProcessorTests.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.SpringApplication; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.StandardEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - */ -public class HostInfoEnvironmentPostProcessorTests { - - private HostInfoEnvironmentPostProcessor processor = new HostInfoEnvironmentPostProcessor(); - - private ConfigurableEnvironment environment = new StandardEnvironment(); - - @Test - public void hostname() { - this.processor.postProcessEnvironment(this.environment, new SpringApplication()); - then(this.environment.getProperty("spring.cloud.client.hostname")).isNotNull(); - } - - @Test - public void ipAddress() { - this.processor.postProcessEnvironment(this.environment, new SpringApplication()); - String address = this.environment.getProperty("spring.cloud.client.ip-address"); - then(address).isNotNull(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfigurationTests.java deleted file mode 100644 index 4922b980..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/ReactiveCommonsClientAutoConfigurationTests.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2019-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.actuator.FeaturesEndpoint; -import org.springframework.cloud.client.actuator.HasFeatures; -import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryClientHealthIndicator; -import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryCompositeHealthContributor; -import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.context.annotation.Bean; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Tim Ysewyn - */ -public class ReactiveCommonsClientAutoConfigurationTests { - - ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(CommonsClientAutoConfiguration.class, - SimpleReactiveDiscoveryClientAutoConfiguration.class, UtilAutoConfiguration.class, - ReactiveCommonsClientAutoConfiguration.class)); - - @Test - public void beansCreatedNormally() { - applicationContextRunner.withPropertyValues("management.endpoints.web.exposure.include=features") - .run(context -> { - then(context.getBean(ReactiveDiscoveryClientHealthIndicator.class)).isNotNull(); - then(context.getBean(ReactiveDiscoveryCompositeHealthContributor.class)).isNotNull(); - then(context.getBean(FeaturesEndpoint.class)).isNotNull(); - then(context.getBeansOfType(HasFeatures.class).values()).isNotEmpty(); - }); - } - - @Test - public void disableAll() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.enabled=false", - "management.endpoints.web.exposure.include=features").run(context -> { - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryCompositeHealthContributor.class); - // features actuator is independent of discovery - then(context.getBean(FeaturesEndpoint.class)).isNotNull(); - assertThat(context).doesNotHaveBean(HasFeatures.class); - }); - } - - @Test - public void disableReactive() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.reactive.enabled=false", - "management.endpoints.web.exposure.include=features").run(context -> { - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryCompositeHealthContributor.class); - // features actuator is independent of discovery - then(context.getBean(FeaturesEndpoint.class)).isNotNull(); - assertThat(context).doesNotHaveBean(HasFeatures.class); - }); - } - - @Test - public void disableAllIndividually() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.client.health-indicator.enabled=false", - "spring.cloud.discovery.client.composite-indicator.enabled=false", - "spring.cloud.features.enabled=false").run(context -> { - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryCompositeHealthContributor.class); - assertThat(context).doesNotHaveBean(FeaturesEndpoint.class); - }); - } - - @Test - public void disableHealthIndicator() { - applicationContextRunner.withPropertyValues("spring.cloud.discovery.client.health-indicator.enabled=false") - .run(context -> { - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryCompositeHealthContributor.class); - }); - } - - @Test - public void worksWithoutActuator() { - applicationContextRunner.withClassLoader(new FilteredClassLoader("org.springframework.boot.actuate")) - .run(context -> { - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryCompositeHealthContributor.class); - then(context.getBeansOfType(HasFeatures.class).values()).isEmpty(); - }); - } - - @Test - public void worksWithoutWebflux() { - applicationContextRunner.withClassLoader(new FilteredClassLoader("org.springframework.web.reactive")) - .run(context -> { - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryCompositeHealthContributor.class); - assertThat(context).doesNotHaveBean(HasFeatures.class); - }); - } - - @Test - public void conditionalOnReactiveDiscoveryEnabledWorks() { - ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withUserConfiguration(ReactiveDiscoveryEnabledConfig.class); - contextRunner.withPropertyValues("spring.cloud.discovery.reactive.enabled=false") - .run(context -> assertThat(context).doesNotHaveBean(TestBean.class)); - contextRunner.withPropertyValues("spring.cloud.discovery.reactive.enabled=true") - .run(context -> assertThat(context.getBean(TestBean.class)).isNotNull()); - } - - @TestConfiguration - @ConditionalOnDiscoveryEnabled - protected static class DiscoveryEnabledConfig { - - @Bean - TestBean testBean() { - return new TestBean(); - } - - } - - @TestConfiguration - @ConditionalOnReactiveDiscoveryEnabled - protected static class ReactiveDiscoveryEnabledConfig { - - @Bean - TestBean testBean() { - return new TestBean(); - } - - } - - private static class TestBean { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/actuator/FeaturesEndpointTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/actuator/FeaturesEndpointTests.java deleted file mode 100644 index 22b399ca..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/actuator/FeaturesEndpointTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.actuator; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - */ -public class FeaturesEndpointTests { - - private AnnotationConfigApplicationContext context; - - @BeforeEach - public void setup() { - this.context = new AnnotationConfigApplicationContext(); - this.context.register(JacksonAutoConfiguration.class, FeaturesConfig.class, Config.class); - this.context.refresh(); - } - - @AfterEach - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void invokeWorks() { - FeaturesEndpoint.Features features = this.context.getBean(FeaturesEndpoint.class).features(); - then(features).isNotNull(); - then(features.getEnabled()).hasSize(2).contains(newFeature("foo", Foo.class), - newFeature("Baz Feature", Baz.class)); - then(features.getDisabled()).hasSize(1).contains("Bar"); - } - - private FeaturesEndpoint.Feature newFeature(String name, Class type) { - return new FeaturesEndpoint.Feature(name, type.getCanonicalName(), null, null); - } - - @Configuration(proxyBeanMethods = false) - public static class FeaturesConfig { - - @Bean - Foo foo() { - return new Foo(); - } - - @Bean - HasFeatures localFeatures() { - HasFeatures features = HasFeatures.namedFeatures(new NamedFeature("foo", Foo.class), - new NamedFeature("Baz Feature", Baz.class)); - features.getAbstractFeatures().add(Bar.class); - return features; - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - public static class Config { - - @Autowired(required = false) - private List hasFeatures = new ArrayList<>(); - - @Bean - public FeaturesEndpoint cloudEndpoint() { - return new FeaturesEndpoint(this.hasFeatures); - } - - } - - public static class Foo { - - } - - public static class Bar { - - } - - public static class Baz { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/CustomizerTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/CustomizerTests.java deleted file mode 100644 index 5462abbe..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/CustomizerTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -public class CustomizerTests { - - @Test - public void testCustomizedOnlyOnce() { - AtomicInteger counter = new AtomicInteger(0); - final Customizer customizer = Customizer.once(AtomicInteger::incrementAndGet, Object::hashCode); - customizer.customize(counter); - customizer.customize(counter); - customizer.customize(counter); - Assertions.assertThat(counter.get()).isEqualTo(1); - - AtomicInteger anotherCounter = new AtomicInteger(0); - customizer.customize(anotherCounter); - customizer.customize(anotherCounter); - Assertions.assertThat(counter.get()).isEqualTo(1); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreakerTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreakerTests.java deleted file mode 100644 index 6d4197f5..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/circuitbreaker/observation/ObservedCircuitBreakerTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.circuitbreaker.observation; - -import java.util.function.Function; -import java.util.function.Supplier; - -import io.micrometer.common.KeyValues; -import io.micrometer.observation.Observation; -import io.micrometer.observation.tck.ObservationContextAssert; -import io.micrometer.observation.tck.TestObservationRegistry; -import io.micrometer.observation.tck.TestObservationRegistryAssert; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; - -import static org.assertj.core.api.BDDAssertions.then; - -class ObservedCircuitBreakerTests { - - TestObservationRegistry registry = TestObservationRegistry.create(); - - @Test - void should_wrap_circuit_breaker_in_observation() { - CircuitBreaker delegate = new CircuitBreaker() { - @Override - public T run(Supplier toRun, Function fallback) { - return toRun.get(); - } - }; - ObservedCircuitBreaker circuitBreaker = new ObservedCircuitBreaker(delegate, registry); - - String result = circuitBreaker.run(() -> "hello"); - - then(result).isEqualTo("hello"); - TestObservationRegistryAssert.assertThat(registry).hasSingleObservationThat() - .hasNameEqualTo("spring.cloud.circuitbreaker") - .hasLowCardinalityKeyValue("spring.cloud.circuitbreaker.type", "supplier") - .hasContextualNameEqualTo("circuit-breaker"); - } - - @Test - void should_wrap_circuit_breaker_in_observation_with_custom_convention() { - CircuitBreaker delegate = new CircuitBreaker() { - @Override - public T run(Supplier toRun, Function fallback) { - return toRun.get(); - } - }; - ObservedCircuitBreaker circuitBreaker = new ObservedCircuitBreaker(delegate, registry); - circuitBreaker.setCustomConvention(new CircuitBreakerObservationConvention() { - - @Override - public KeyValues getLowCardinalityKeyValues(CircuitBreakerObservationContext context) { - return KeyValues.of("bar", "baz"); - } - - @Override - public String getName() { - return "foo"; - } - }); - - String result = circuitBreaker.run(() -> "hello"); - - then(result).isEqualTo("hello"); - TestObservationRegistryAssert.assertThat(registry).hasSingleObservationThat().hasNameEqualTo("foo") - .hasLowCardinalityKeyValue("bar", "baz").hasContextualNameEqualTo("circuit-breaker"); - } - - @Test - void should_wrap_circuit_breaker_with_fallback_in_observation() { - TestObservationRegistry registry = TestObservationRegistry.create(); - CircuitBreaker delegate = new CircuitBreaker() { - @Override - public T run(Supplier toRun, Function fallback) { - try { - return toRun.get(); - } - catch (Throwable t) { - return fallback.apply(t); - } - } - }; - ObservedCircuitBreaker circuitBreaker = new ObservedCircuitBreaker(delegate, registry); - - Observation parent = Observation.createNotStarted("parent", registry); - String result = parent.observe(() -> circuitBreaker.run(() -> { - throw new IllegalStateException("BOOM!"); - }, throwable -> "goodbye")); - - then(result).isEqualTo("goodbye"); - - TestObservationRegistryAssert.then(registry).hasNumberOfObservationsEqualTo(3) - .hasHandledContextsThatSatisfy(contexts -> { - ObservationContextAssert.then(contexts.get(0)).hasNameEqualTo("parent"); - ObservationContextAssert.then(contexts.get(1)).hasNameEqualTo("spring.cloud.circuitbreaker") - .hasContextualNameEqualTo("circuit-breaker") - .hasLowCardinalityKeyValue("spring.cloud.circuitbreaker.type", "supplier") - .hasParentObservationEqualTo(parent); - ObservationContextAssert.then(contexts.get(2)).hasNameEqualTo("spring.cloud.circuitbreaker") - .hasContextualNameEqualTo("circuit-breaker fallback") - .hasLowCardinalityKeyValue("spring.cloud.circuitbreaker.type", "function") - .hasParentObservationEqualTo(parent); - }); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/AutoRegisterPropertyFalseTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/AutoRegisterPropertyFalseTests.java deleted file mode 100644 index a2ad236e..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/AutoRegisterPropertyFalseTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import org.junit.jupiter.api.Test; - -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.serviceregistry.AutoServiceRegistration; -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Ryan Baxter - */ -@SpringBootTest(properties = { "spring.cloud.service-registry.auto-registration.enabled: false" }) -public class AutoRegisterPropertyFalseTests { - - @Autowired(required = false) - AutoServiceRegistrationAutoConfiguration autoConfiguration; - - @Autowired(required = false) - AutoServiceRegistration autoServiceRegistration; - - @Autowired(required = false) - AutoServiceRegistrationProperties autoServiceRegistrationProperties; - - @Value("${spring.cloud.service-registry.auto-registration.enabled}") - Boolean autoRegisterProperty; - - @Test - public void veryifyBeans() { - then(this.autoConfiguration).isNull(); - then(this.autoServiceRegistration).isNull(); - then(this.autoServiceRegistrationProperties).isNull(); - then(this.autoRegisterProperty).isFalse(); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - public static class App { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientAutoRegisterFalseTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientAutoRegisterFalseTests.java deleted file mode 100644 index 9aeca7f2..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientAutoRegisterFalseTests.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import org.junit.jupiter.api.Test; - -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.serviceregistry.AutoServiceRegistration; -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration; -import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Ryan Baxter - */ -@SpringBootTest -public class EnableDiscoveryClientAutoRegisterFalseTests { - - @Autowired(required = false) - AutoServiceRegistrationAutoConfiguration autoConfiguration; - - @Autowired(required = false) - AutoServiceRegistration autoServiceRegistration; - - @Autowired(required = false) - AutoServiceRegistrationProperties autoServiceRegistrationProperties; - - @Value("${spring.cloud.service-registry.auto-registration.enabled}") - Boolean autoRegisterProperty; - - @Test - public void veryifyBeans() { - then(this.autoConfiguration).isNull(); - then(this.autoServiceRegistration).isNull(); - then(this.autoServiceRegistrationProperties).isNull(); - then(this.autoRegisterProperty).isFalse(); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - @EnableDiscoveryClient(autoRegister = false) - public static class App { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelectorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelectorTests.java deleted file mode 100644 index 2c398c86..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientImportSelectorTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.mock.env.MockEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.BDDMockito.given; - -/** - * @author Spencer Gibb - */ -public class EnableDiscoveryClientImportSelectorTests { - - private final EnableDiscoveryClientImportSelector importSelector = new EnableDiscoveryClientImportSelector(); - - private final MockEnvironment environment = new MockEnvironment(); - - @Mock - private AnnotationMetadata annotationMetadata; - - @Mock - private AnnotationAttributes annotationAttributes; - - @BeforeEach - public void setup() { - MockitoAnnotations.openMocks(this); - this.importSelector.setBeanClassLoader(getClass().getClassLoader()); - this.importSelector.setEnvironment(this.environment); - } - - @Test - public void autoRegistrationIsEnabled() { - configureAnnotation(true); - String[] imports = this.importSelector.selectImports(this.annotationMetadata); - then(this.environment.getProperty("spring.cloud.service-registry.auto-registration.enabled", Boolean.class, - true)).isTrue(); - then(imports).hasSize(1); - } - - @Test - public void autoRegistrationIsDisabled() { - configureAnnotation(false); - String[] imports = this.importSelector.selectImports(this.annotationMetadata); - then(this.environment.getProperty("spring.cloud.service-registry.auto-registration.enabled", Boolean.class)) - .isFalse(); - then(imports).isEmpty(); - } - - private void configureAnnotation(boolean autoRegistration) { - String annotationName = EnableDiscoveryClient.class.getName(); - given(this.annotationMetadata.isAnnotated(annotationName)).willReturn(true); - given(this.annotationMetadata.getAnnotationAttributes(annotationName, true)) - .willReturn(this.annotationAttributes); - given(this.annotationAttributes.getBoolean("autoRegister")).willReturn(autoRegistration); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientMissingImplTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientMissingImplTests.java deleted file mode 100644 index 53b6401d..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/EnableDiscoveryClientMissingImplTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.NestedRuntimeException; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * Tests that if @EnableDiscoveryClient is used, but there is no - * implementation on the classpath, then fail. - * - * @author Spencer Gibb - */ -public class EnableDiscoveryClientMissingImplTests { - - @Test - public void testContextFails() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder().sources(App.class) - .web(WebApplicationType.NONE).run()) { - // do sth - } - catch (NestedRuntimeException e) { - Throwable rootCause = e.getRootCause(); - then(rootCause instanceof IllegalStateException).isTrue(); - then(rootCause.getMessage().contains("no implementations")).isTrue(); - } - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - @EnableDiscoveryClient - // this will fail with @EnableDiscoveryClient and no implementation (nothing in - // spring.factories) - public static class App { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/ManagementServerPortUtilsTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/ManagementServerPortUtilsTests.java deleted file mode 100644 index a7c9e2e9..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/ManagementServerPortUtilsTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery; - -import org.junit.jupiter.api.Test; - -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.test.ClassPathExclusions; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@ClassPathExclusions({ "spring-boot-actuator-autoconfigure-*" }) -public class ManagementServerPortUtilsTests { - - @Test - public void contextStarts() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder().web(WebApplicationType.NONE) - .sources(TestApp.class).run()) { - - then(ManagementServerPortUtils.hasActuator).isFalse(); - } - } - - @SpringBootConfiguration - @EnableAutoConfiguration - protected static class TestApp { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java deleted file mode 100644 index f2000500..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientAutoConfigurationTests.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * Composite Discovery Client should be the one found by default. - * - * @author Biju Kunjummen - */ - -@SpringBootTest -public class CompositeDiscoveryClientAutoConfigurationTests { - - @Autowired - private DiscoveryClient discoveryClient; - - @Test - public void compositeDiscoveryClientShouldBeTheDefault() { - then(this.discoveryClient).isInstanceOf(CompositeDiscoveryClient.class); - CompositeDiscoveryClient compositeDiscoveryClient = (CompositeDiscoveryClient) this.discoveryClient; - then(compositeDiscoveryClient.getDiscoveryClients()).hasSize(2); - then(compositeDiscoveryClient.getDiscoveryClients().get(0).description()) - .isEqualTo("A custom discovery client"); - } - - @Test - public void simpleDiscoveryClientShouldBeHaveTheLowestPrecedence() { - CompositeDiscoveryClient compositeDiscoveryClient = (CompositeDiscoveryClient) this.discoveryClient; - then(compositeDiscoveryClient.getDiscoveryClients().get(0).description()) - .isEqualTo("A custom discovery client"); - then(compositeDiscoveryClient.getDiscoveryClients().get(1)).isInstanceOf(SimpleDiscoveryClient.class); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - public static class Config { - - @Bean - public DiscoveryClient customDiscoveryClient1() { - return new DiscoveryClient() { - @Override - public String description() { - return "A custom discovery client"; - } - - @Override - public List getInstances(String serviceId) { - return null; - } - - @Override - public List getServices() { - return null; - } - }; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientOrderTest.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientOrderTest.java deleted file mode 100644 index 3ceed9e3..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientOrderTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.CUSTOM_DISCOVERY_CLIENT; -import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.CUSTOM_SERVICE_ID; -import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.DEFAULT_ORDER_DISCOVERY_CLIENT; -import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.FOURTH_DISCOVERY_CLIENT; - -/** - * Tests for the support of ordered {@link DiscoveryClient} instances in - * {@link CompositeDiscoveryClient}. - * - * @author Olga Maciaszek-Sharma - */ -@SpringBootTest(properties = "spring.cloud.discovery.client.simple.order:2", - classes = { CompositeDiscoveryClientTestsConfig.class }) -public class CompositeDiscoveryClientOrderTest { - - @Autowired - DiscoveryClient discoveryClient; - - @Test - public void shouldGetOrderedDiscoveryClients() { - // when: - List discoveryClients = ((CompositeDiscoveryClient) this.discoveryClient) - .getDiscoveryClients(); - - // then: - then(discoveryClients.get(0).description()).isEqualTo(CUSTOM_DISCOVERY_CLIENT); - then(discoveryClients.get(1).description()).isEqualTo(DEFAULT_ORDER_DISCOVERY_CLIENT); - then(discoveryClients.get(2).description()).isEqualTo("Simple Discovery Client"); - then(discoveryClients.get(3).description()).isEqualTo(FOURTH_DISCOVERY_CLIENT); - } - - @Test - public void shouldOnlyReturnServiceInstancesForTheHighestPrecedenceDiscoveryClient() { - // when: - List serviceInstances = this.discoveryClient.getInstances(CUSTOM_SERVICE_ID); - - // then: - then(serviceInstances).hasSize(1); - then(serviceInstances.get(0).getPort()).isEqualTo(123); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java deleted file mode 100644 index b260dbf6..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite; - -import java.net.URI; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.CUSTOM_SERVICE_ID; - -/** - * Tests for behavior of Composite Discovery Client. - * - * @author Biju Kunjummen - */ - -@SpringBootTest( - properties = { "spring.application.name=service0", - "spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s11:8080", - "spring.cloud.discovery.client.simple.instances.service1[1].uri=https://s12:8443", - "spring.cloud.discovery.client.simple.instances.service2[0].uri=https://s21:8080", - "spring.cloud.discovery.client.simple.instances.service2[1].uri=https://s22:443" }, - classes = { CompositeDiscoveryClientTestsConfig.class }) -public class CompositeDiscoveryClientTests { - - @Autowired - private DiscoveryClient discoveryClient; - - @Test - public void getInstancesByServiceIdShouldDelegateCall() { - then(this.discoveryClient).isInstanceOf(CompositeDiscoveryClient.class); - - then(this.discoveryClient.getInstances("service1")).hasSize(2); - - ServiceInstance s1 = this.discoveryClient.getInstances("service1").get(0); - then(s1.getHost()).isEqualTo("s11"); - then(s1.getPort()).isEqualTo(8080); - then(s1.getUri()).isEqualTo(URI.create("http://s11:8080")); - then(s1.isSecure()).isEqualTo(false); - } - - @Test - public void getServicesShouldAggregateAllServiceNames() { - then(this.discoveryClient.getServices()).containsOnlyOnce("service1", "service2", "custom"); - } - - @Test - public void getDescriptionShouldBeComposite() { - then(this.discoveryClient.description()).isEqualTo("Composite Discovery Client"); - } - - @Test - public void getInstancesShouldRespectOrder() { - then(this.discoveryClient.getInstances(CUSTOM_SERVICE_ID)).hasSize(1); - then(this.discoveryClient.getInstances(CUSTOM_SERVICE_ID)).hasSize(1); - } - - @Test - public void getInstancesByUnknownServiceIdShouldReturnAnEmptyList() { - then(this.discoveryClient.getInstances("unknown")).hasSize(0); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTestsConfig.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTestsConfig.java deleted file mode 100644 index e7a5ef0a..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientTestsConfig.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite; - -import java.util.Collections; -import java.util.List; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static java.util.Collections.singletonList; - -/** - * Test configuration for {@link CompositeDiscoveryClient} tests. - * - * @author Olga Maciaszek-Sharma - * @author Tim Ysewyn - */ -@Configuration(proxyBeanMethods = false) -@EnableAutoConfiguration -public class CompositeDiscoveryClientTestsConfig { - - static final String DEFAULT_ORDER_DISCOVERY_CLIENT = "Default order discovery client"; - static final String CUSTOM_DISCOVERY_CLIENT = "A custom discovery client"; - static final String FOURTH_DISCOVERY_CLIENT = "Fourth discovery client"; - static final String CUSTOM_SERVICE_ID = "custom"; - - @Bean - public DiscoveryClient customDiscoveryClient() { - return aDiscoveryClient(-1, CUSTOM_DISCOVERY_CLIENT); - } - - @Bean - public DiscoveryClient thirdOrderCustomDiscoveryClient() { - return aDiscoveryClient(3, FOURTH_DISCOVERY_CLIENT); - } - - @Bean - public DiscoveryClient defaultOrderDiscoveryClient() { - return aDiscoveryClient(null, DEFAULT_ORDER_DISCOVERY_CLIENT); - } - - private DiscoveryClient aDiscoveryClient(Integer order, String description) { - return new DiscoveryClient() { - @Override - public String description() { - return description; - } - - @Override - public List getInstances(String serviceId) { - if (serviceId.equals(CUSTOM_SERVICE_ID)) { - ServiceInstance s1 = new DefaultServiceInstance("customInstance", CUSTOM_SERVICE_ID, "host", 123, - false); - return singletonList(s1); - } - return Collections.emptyList(); - } - - @Override - public List getServices() { - return singletonList(CUSTOM_SERVICE_ID); - } - - @Override - public int getOrder() { - return order != null ? order : DiscoveryClient.super.getOrder(); - } - }; - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientUnitTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientUnitTests.java deleted file mode 100644 index 953cfbeb..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClientUnitTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Mockito tests for Composite Discovery Client - * - * @author Sean Ruffatti - */ -@ExtendWith(MockitoExtension.class) -public class CompositeDiscoveryClientUnitTests { - - private CompositeDiscoveryClient underTest; - - @Mock - private DiscoveryClient client1; - - @Mock - private DiscoveryClient client2; - - @BeforeEach - void setUp() { - underTest = new CompositeDiscoveryClient(Arrays.asList(client1, client2)); - } - - @Test - void shouldRetrieveInstancesByServiceId() { - ServiceInstance serviceInstance1 = new DefaultServiceInstance("instance1", "serviceId", "https://s1", 8443, - true); - when(client1.getInstances("serviceId")).thenReturn(Collections.singletonList(serviceInstance1)); - - List serviceInstances = underTest.getInstances("serviceId"); - - then(serviceInstances.get(0).getInstanceId()).isEqualTo("instance1"); - then(serviceInstances.get(0).getServiceId()).isEqualTo("serviceId"); - then(serviceInstances.get(0).getHost()).isEqualTo("https://s1"); - then(serviceInstances.get(0).getPort()).isEqualTo(8443); - } - - @Test - void shouldReturnServiceIds() { - when(client1.getServices()).thenReturn(Collections.singletonList("serviceId1")); - when(client2.getServices()).thenReturn(Collections.singletonList("serviceId2")); - - List services = underTest.getServices(); - - then(services.size()).isEqualTo(2); - then(services).containsOnlyOnce("serviceId1", "serviceId2"); - } - - @Test - void shouldReturnAllDiscoveryClients() { - then(underTest.getDiscoveryClients()).containsOnlyOnce(client1, client2); - } - - @Test - void shouldCallProbeOnAllDiscoveryClients() { - underTest.probe(); - - // Every DiscoveryClient bean should invoke DiscoveryClient.probe() when - // CompositeDiscoveryClient.probe() is invoked. - verify(client1, times(1)).probe(); - verify(client1, times(0)).getServices(); - verify(client2, times(1)).probe(); - verify(client2, times(0)).getServices(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfigurationTests.java deleted file mode 100644 index 4ab9b6c6..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientAutoConfigurationTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite.reactive; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.context.annotation.Bean; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Tim Ysewyn - */ -class ReactiveCompositeDiscoveryClientAutoConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ReactiveCompositeDiscoveryClientAutoConfiguration.class)); - - @Test - public void shouldCreateCompositeReactiveDiscoveryClientWithoutDelegates() { - this.contextRunner.run((context) -> { - ReactiveDiscoveryClient client = context.getBean(ReactiveDiscoveryClient.class); - assertThat(client).isNotNull(); - assertThat(client).isInstanceOf(ReactiveCompositeDiscoveryClient.class); - assertThat(((ReactiveCompositeDiscoveryClient) client).getDiscoveryClients()).isEmpty(); - }); - } - - @Test - public void shouldCreateCompositeReactiveDiscoveryClientWithDelegate() { - this.contextRunner.withUserConfiguration(Configuration.class).run((context) -> { - ReactiveDiscoveryClient client = context.getBean(ReactiveDiscoveryClient.class); - assertThat(client).isNotNull(); - assertThat(client).isInstanceOf(ReactiveCompositeDiscoveryClient.class); - assertThat(((ReactiveCompositeDiscoveryClient) client).getDiscoveryClients()).hasSize(1); - }); - } - - @TestConfiguration - static class Configuration { - - @Bean - ReactiveDiscoveryClient discoveryClient() { - return new ReactiveDiscoveryClient() { - @Override - public String description() { - return "Reactive Test Discovery Client"; - } - - @Override - public Flux getInstances(String serviceId) { - return Flux.empty(); - } - - @Override - public Flux getServices() { - return Flux.empty(); - } - }; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientTests.java deleted file mode 100644 index 36f70730..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/composite/reactive/ReactiveCompositeDiscoveryClientTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.composite.reactive; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; -import reactor.test.publisher.TestPublisher; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; - -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -/** - * @author Tim Ysewyn - */ -@ExtendWith(MockitoExtension.class) -class ReactiveCompositeDiscoveryClientTests { - - @Mock - private ReactiveDiscoveryClient discoveryClient1; - - @Mock - private ReactiveDiscoveryClient discoveryClient2; - - @Test - public void shouldReturnEmptyFluxOfServices() { - ReactiveCompositeDiscoveryClient client = new ReactiveCompositeDiscoveryClient(emptyList()); - - Flux services = client.getServices(); - - StepVerifier.create(services).expectComplete().verify(); - } - - @Test - public void shouldReturnFluxOfServices() { - TestPublisher discoveryClient1Publisher = TestPublisher.createCold(); - discoveryClient1Publisher.emit("serviceAFromClient1"); - discoveryClient1Publisher.emit("serviceBFromClient1"); - discoveryClient1Publisher.complete(); - - TestPublisher discoveryClient2Publisher = TestPublisher.createCold(); - discoveryClient2Publisher.emit("serviceCFromClient2"); - discoveryClient2Publisher.complete(); - - when(discoveryClient1.getServices()).thenReturn(discoveryClient1Publisher.flux()); - when(discoveryClient2.getServices()).thenReturn(discoveryClient2Publisher.flux()); - - ReactiveCompositeDiscoveryClient client = new ReactiveCompositeDiscoveryClient( - asList(discoveryClient1, discoveryClient2)); - - assertThat(client.description()).isEqualTo("Composite Reactive Discovery Client"); - - Flux services = client.getServices(); - - StepVerifier.create(services).expectNext("serviceAFromClient1").expectNext("serviceBFromClient1") - .expectNext("serviceCFromClient2").expectComplete().verify(); - } - - @Test - public void shouldReturnEmptyFluxOfServiceInstances() { - ReactiveCompositeDiscoveryClient client = new ReactiveCompositeDiscoveryClient(emptyList()); - - Flux instances = client.getInstances("service"); - - StepVerifier.create(instances).expectComplete().verify(); - } - - @Test - public void shouldReturnFluxOfServiceInstances() { - DefaultServiceInstance serviceInstance1 = new DefaultServiceInstance("instance", "service", "localhost", 8080, - false); - DefaultServiceInstance serviceInstance2 = new DefaultServiceInstance("instance2", "service", "localhost", 8080, - false); - TestPublisher discoveryClient1Publisher = TestPublisher.createCold(); - discoveryClient1Publisher.emit(serviceInstance1); - discoveryClient1Publisher.emit(serviceInstance2); - discoveryClient1Publisher.complete(); - - TestPublisher discoveryClient2Publisher = TestPublisher.createCold(); - discoveryClient2Publisher.complete(); - - when(discoveryClient1.getInstances("service")).thenReturn(discoveryClient1Publisher.flux()); - when(discoveryClient2.getInstances("service")).thenReturn(discoveryClient2Publisher.flux()); - - ReactiveCompositeDiscoveryClient client = new ReactiveCompositeDiscoveryClient( - asList(discoveryClient1, discoveryClient2)); - - Flux instances = client.getInstances("service"); - - StepVerifier.create(instances).expectNext(serviceInstance1).expectNext(serviceInstance2).expectComplete() - .verify(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitorTests.java deleted file mode 100644 index 7536a6ba..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/event/HeartbeatMonitorTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.event; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - */ -public class HeartbeatMonitorTests { - - private HeartbeatMonitor monitor = new HeartbeatMonitor(); - - @Test - public void onAndOff() { - then(this.monitor.update("foo")).isTrue(); - then(this.monitor.update("foo")).isFalse(); - } - - @Test - public void toggle() { - then(this.monitor.update("foo")).isTrue(); - then(this.monitor.update("bar")).isTrue(); - } - - @Test - public void nullInitialValue() { - then(this.monitor.update(null)).isFalse(); - } - - @Test - public void nullSecondValue() { - then(this.monitor.update("foo")).isTrue(); - then(this.monitor.update(null)).isFalse(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java deleted file mode 100644 index eefea584..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.health.CompositeHealthContributor; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.Status; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.CommonsClientAutoConfiguration; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -/** - * @author Spencer Gibb - */ -// @checkstyle:off -@SpringBootTest(classes = { DiscoveryClientHealthIndicatorTests.Config.class, CommonsClientAutoConfiguration.class }, - properties = "spring.cloud.discovery.client.health-indicator.include-description:true") -// @checkstyle:on -public class DiscoveryClientHealthIndicatorTests { - - @Autowired - private DiscoveryCompositeHealthContributor healthContributor; - - @Autowired - private DiscoveryClientHealthIndicator clientHealthIndicator; - - @Test - public void testHealthIndicatorDescriptionDisabled() { - then(this.healthContributor).as("healthIndicator was null").isNotNull(); - assertHealth(getHealth("testDiscoveryHealthIndicator"), Status.UNKNOWN); - assertHealth(getHealth("discoveryClient"), Status.UNKNOWN); - - this.clientHealthIndicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - - assertHealth(getHealth("testDiscoveryHealthIndicator"), Status.UNKNOWN); - Status status = assertHealth(getHealth("discoveryClient"), Status.UP); - then(status.getDescription()).as("status description was wrong").isEqualTo("TestDiscoveryClient"); - } - - private Health getHealth(String name) { - HealthContributor delegate = ((CompositeHealthContributor) this.healthContributor).getContributor(name); - return ((HealthIndicator) delegate).health(); - } - - private Status assertHealth(Health health, Status expected) { - then(health).as("health was null").isNotNull(); - Status status = health.getStatus(); - then(status).as("status was null").isNotNull(); - then(status.getCode()).isEqualTo(expected.getCode()).as("status code was wrong"); - return status; - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - public static class Config { - - @Bean - public DiscoveryClient discoveryClient() { - DiscoveryClient mock = mock(DiscoveryClient.class); - given(mock.description()).willReturn("TestDiscoveryClient"); - given(mock.getServices()).willReturn(List.of("TestService1")); - return mock; - } - - @Bean - public DiscoveryHealthIndicator discoveryHealthIndicator() { - return new DiscoveryHealthIndicator() { - - @Override - public String getName() { - return "testDiscoveryHealthIndicator"; - } - - @Override - public Health health() { - return new Health.Builder().unknown().build(); - } - - }; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorUnitTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorUnitTests.java deleted file mode 100644 index 088da422..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryClientHealthIndicatorUnitTests.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health; - -import java.util.Collections; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.when; - -/** - * Unit tests for {@link DiscoveryClientHealthIndicator}. - * - * @author Chris Bono - */ -@ExtendWith(MockitoExtension.class) -class DiscoveryClientHealthIndicatorUnitTests { - - @Mock - private ObjectProvider discoveryClientProvider; - - @Mock - private DiscoveryClient discoveryClient; - - @Mock - private DiscoveryClientHealthIndicatorProperties properties; - - @InjectMocks - private DiscoveryClientHealthIndicator indicator; - - @BeforeEach - public void prepareMocks() { - lenient().when(discoveryClientProvider.getIfAvailable()).thenReturn(discoveryClient); - } - - @Test - public void shouldReturnUnknownStatusWhenNotInitialized() { - Health expectedHealth = Health.status(new Status(Status.UNKNOWN.getCode(), "Discovery Client not initialized")) - .build(); - Health health = indicator.health(); - assertThat(health).isEqualTo(expectedHealth); - } - - @Test - public void shouldReturnUpStatusWhenNotUsingServicesQueryAndProbeSucceeds() { - when(properties.isUseServicesQuery()).thenReturn(false); - Health expectedHealth = Health.status(new Status(Status.UP.getCode(), "")).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Health health = indicator.health(); - - assertThat(health).isEqualTo(expectedHealth); - } - - @Test - public void shouldReturnDownStatusWhenNotUsingServicesQueryAndProbeFails() { - when(properties.isUseServicesQuery()).thenReturn(false); - RuntimeException ex = new RuntimeException("something went wrong"); - doThrow(ex).when(discoveryClient).probe(); - Health expectedHealth = Health.down(ex).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Health health = indicator.health(); - - assertThat(health).isEqualTo(expectedHealth); - } - - @Test - public void shouldReturnUpStatusWhenUsingServicesQueryAndNoServicesReturned() { - when(properties.isUseServicesQuery()).thenReturn(true); - when(discoveryClient.getServices()).thenReturn(Collections.emptyList()); - Health expectedHealth = Health.status(new Status(Status.UP.getCode(), "")).withDetail("services", emptyList()) - .build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Health health = indicator.health(); - - assertThat(health).isEqualTo(expectedHealth); - } - - @Test - public void shouldReturnUpStatusWhenUsingServicesQueryAndServicesReturned() { - when(properties.isUseServicesQuery()).thenReturn(true); - when(properties.isIncludeDescription()).thenReturn(true); - when(discoveryClient.description()).thenReturn("Mocked Service Discovery Client"); - when(discoveryClient.getServices()).thenReturn(singletonList("service")); - Health expectedHealth = Health.status(new Status(Status.UP.getCode(), "Mocked Service Discovery Client")) - .withDetail("services", singletonList("service")).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Health health = indicator.health(); - - assertThat(health).isEqualTo(expectedHealth); - } - - @Test - public void shouldReturnDownStatusWhenUsingServicesQueryAndCallFails() { - when(properties.isUseServicesQuery()).thenReturn(true); - RuntimeException ex = new RuntimeException("something went wrong"); - when(discoveryClient.getServices()).thenThrow(ex); - Health expectedHealth = Health.down(ex).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Health health = indicator.health(); - - assertThat(health).isEqualTo(expectedHealth); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributorTests.java deleted file mode 100644 index 258f7bd4..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/DiscoveryCompositeHealthContributorTests.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.actuate.health.NamedContributor; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; - -/** - * Tests for {@link DiscoveryCompositeHealthContributor}. - * - * @author Phillip Webb - */ -public class DiscoveryCompositeHealthContributorTests { - - @Test - public void createWhenIndicatorsAreNullThrowsException() { - assertThatIllegalArgumentException().isThrownBy(() -> new DiscoveryCompositeHealthContributor(null)) - .withMessage("'indicators' must not be null"); - } - - @Test - public void getContributorReturnsContributor() { - TestDiscoveryHealthIndicator indicator = new TestDiscoveryHealthIndicator("test", Health.up().build()); - DiscoveryCompositeHealthContributor composite = new DiscoveryCompositeHealthContributor(List.of(indicator)); - HealthIndicator adapted = (HealthIndicator) composite.getContributor("test"); - assertThat(adapted).isNotNull(); - assertThat(adapted.health()).isSameAs(indicator.health()); - } - - @Test - public void getContributorWhenMissingReturnsNull() { - TestDiscoveryHealthIndicator indicator = new TestDiscoveryHealthIndicator("test", Health.up().build()); - DiscoveryCompositeHealthContributor composite = new DiscoveryCompositeHealthContributor(List.of(indicator)); - assertThat((HealthIndicator) composite.getContributor("missing")).isNull(); - } - - @Test - public void iteratorIteratesNamedContributors() { - TestDiscoveryHealthIndicator indicator1 = new TestDiscoveryHealthIndicator("test1", Health.up().build()); - TestDiscoveryHealthIndicator indicator2 = new TestDiscoveryHealthIndicator("test2", Health.down().build()); - DiscoveryCompositeHealthContributor composite = new DiscoveryCompositeHealthContributor( - Arrays.asList(indicator1, indicator2)); - List> contributors = new ArrayList<>(); - for (NamedContributor contributor : composite) { - contributors.add(contributor); - } - assertThat(contributors).hasSize(2); - assertThat(contributors).extracting("name").containsExactlyInAnyOrder("test1", "test2"); - // TODO: HealthContributor no longer has a health method - // assertThat(contributors).extracting("contributor").extracting("health") - // .containsExactlyInAnyOrder(indicator1.health(), indicator2.health()); - } - - private static class TestDiscoveryHealthIndicator implements DiscoveryHealthIndicator { - - private final String name; - - private final Health health; - - TestDiscoveryHealthIndicator(String name, Health health) { - super(); - this.name = name; - this.health = health; - } - - @Override - public String getName() { - return this.name; - } - - @Override - public Health health() { - return this.health; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicatorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicatorTests.java deleted file mode 100644 index 0da5afdb..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryClientHealthIndicatorTests.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health.reactive; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties; -import org.springframework.core.Ordered; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -/** - * @author Tim Ysewyn - * @author Chris Bono - * @author Olga Maciaszek-Sharma - */ -@ExtendWith(MockitoExtension.class) -class ReactiveDiscoveryClientHealthIndicatorTests { - - @Mock - private ReactiveDiscoveryClient discoveryClient; - - @Mock - private DiscoveryClientHealthIndicatorProperties properties; - - @InjectMocks - private ReactiveDiscoveryClientHealthIndicator indicator; - - @Test - public void shouldReturnCorrectOrder() { - assertThat(indicator.getOrder()).isEqualTo(Ordered.HIGHEST_PRECEDENCE); - indicator.setOrder(0); - assertThat(indicator.getOrder()).isEqualTo(0); - } - - @Test - public void shouldUseClientDescriptionForIndicatorName() { - when(discoveryClient.description()).thenReturn("Mocked Service Discovery Client"); - assertThat(indicator.getName()).isEqualTo("Mocked Service Discovery Client"); - } - - @Test - public void shouldReturnUnknownStatusWhenNotInitialized() { - Health expectedHealth = Health.status(new Status(Status.UNKNOWN.getCode(), "Discovery Client not initialized")) - .build(); - Mono health = indicator.health(); - StepVerifier.create(health).expectNext(expectedHealth).expectComplete().verify(); - } - - @Test - public void shouldReturnUpStatusWhenNotUsingServicesQueryAndProbeSucceeds() { - when(properties.isUseServicesQuery()).thenReturn(false); - ReactiveDiscoveryClient discoveryClient = new TestDiscoveryClient(); - ReactiveDiscoveryClientHealthIndicator indicator = new ReactiveDiscoveryClientHealthIndicator(discoveryClient, - properties); - Health expectedHealth = Health.status(new Status(Status.UP.getCode(), "")).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Mono health = indicator.health(); - - StepVerifier.create(health).expectNext(expectedHealth).expectComplete().verify(); - } - - @Test - public void shouldReturnDownStatusWhenNotUsingServicesQueryAndProbeFails() { - ExceptionThrowingDiscoveryClient discoveryClient = new ExceptionThrowingDiscoveryClient(); - ReactiveDiscoveryClientHealthIndicator indicator = new ReactiveDiscoveryClientHealthIndicator(discoveryClient, - properties); - Health expectedHealth = Health.down(discoveryClient.exception).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Mono health = indicator.health(); - - StepVerifier.create(health).expectNext(expectedHealth).expectComplete().verify(); - } - - @Test - public void shouldReturnUpStatusWhenUsingServicesQueryAndNoServicesReturned() { - when(properties.isUseServicesQuery()).thenReturn(true); - when(discoveryClient.getServices()).thenReturn(Flux.empty()); - Health expectedHealth = Health.status(new Status(Status.UP.getCode(), "")).withDetail("services", emptyList()) - .build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Mono health = indicator.health(); - - StepVerifier.create(health).expectNext(expectedHealth).expectComplete().verify(); - } - - @Test - public void shouldReturnUpStatusWhenUsingServicesQueryAndServicesReturned() { - when(properties.isUseServicesQuery()).thenReturn(true); - when(properties.isIncludeDescription()).thenReturn(true); - when(discoveryClient.getServices()).thenReturn(Flux.just("service")); - when(discoveryClient.description()).thenReturn("Mocked Service Discovery Client"); - Health expectedHealth = Health.status(new Status(Status.UP.getCode(), "Mocked Service Discovery Client")) - .withDetail("services", singletonList("service")).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Mono health = indicator.health(); - - StepVerifier.create(health).expectNext(expectedHealth).expectComplete().verify(); - } - - @Test - public void shouldReturnDownStatusWhenUsingServicesQueryAndCallFails() { - when(properties.isUseServicesQuery()).thenReturn(true); - RuntimeException ex = new RuntimeException("something went wrong"); - when(discoveryClient.getServices()).thenReturn(Flux.error(ex)); - Health expectedHealth = Health.down(ex).build(); - - indicator.onApplicationEvent(new InstanceRegisteredEvent<>(this, null)); - Mono health = indicator.health(); - - StepVerifier.create(health).expectNext(expectedHealth).expectComplete().verify(); - } - - static class TestDiscoveryClient implements ReactiveDiscoveryClient { - - @Override - public String description() { - return "Test"; - } - - @Override - public Flux getInstances(String serviceId) { - return Flux.just(new DefaultServiceInstance()); - } - - @Override - public Flux getServices() { - return Flux.just("Test"); - } - - } - - static class ExceptionThrowingDiscoveryClient implements ReactiveDiscoveryClient { - - RuntimeException exception = new RuntimeException("something went wrong"); - - @Override - public String description() { - return "Exception"; - } - - @Override - public Flux getInstances(String serviceId) { - throw new RuntimeException("Test!"); - } - - @Override - public Flux getServices() { - throw new RuntimeException("something went wrong"); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributorTests.java deleted file mode 100644 index cd7a0cb2..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/health/reactive/ReactiveDiscoveryCompositeHealthContributorTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.health.reactive; - -import java.util.Iterator; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.NamedContributor; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.actuate.health.ReactiveHealthIndicator; - -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Tim Ysewyn - */ -class ReactiveDiscoveryCompositeHealthContributorTests { - - @Test - void shouldReturnEmptyIterator() { - ReactiveDiscoveryCompositeHealthContributor healthContributor = new ReactiveDiscoveryCompositeHealthContributor( - emptyList()); - assertThat(healthContributor.iterator().hasNext()).isFalse(); - } - - @Test - void shouldReturnNullForUnknownContributor() { - ReactiveDiscoveryCompositeHealthContributor healthContributor = new ReactiveDiscoveryCompositeHealthContributor( - emptyList()); - assertThat(healthContributor.getContributor("unknown")).isNull(); - } - - @Test - void shouldReturnKnownContributor() { - ReactiveDiscoveryHealthIndicator indicator = mock(ReactiveDiscoveryHealthIndicator.class); - Health health = Health.up().build(); - when(indicator.getName()).thenReturn("known"); - when(indicator.health()).thenReturn(Mono.just(health)); - - ReactiveDiscoveryCompositeHealthContributor healthContributor = new ReactiveDiscoveryCompositeHealthContributor( - singletonList(indicator)); - - assertThat(healthContributor.getContributor("known")).isNotNull(); - Iterator> iterator = healthContributor.iterator(); - assertThat(iterator.hasNext()).isTrue(); - NamedContributor contributor = iterator.next(); - assertThat(contributor).isNotNull(); - assertThat(contributor.getName()).isEqualTo("known"); - assertThat(contributor.getContributor()).isNotNull(); - assertThat(contributor.getContributor()).isInstanceOf(ReactiveHealthIndicator.class); - ReactiveHealthIndicator healthIndicator = (ReactiveHealthIndicator) contributor.getContributor(); - StepVerifier.create(healthIndicator.getHealth(true)).expectNext(health).expectComplete().verify(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java deleted file mode 100644 index 16bc9a06..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * DiscoveryClient implementation defaults to {@link CompositeDiscoveryClient}. - * - * @author Biju Kunjummen - */ -@SpringBootTest(classes = DiscoveryClientAutoConfigurationDefaultTests.Config.class) -public class DiscoveryClientAutoConfigurationDefaultTests { - - @Autowired - private DiscoveryClient discoveryClient; - - @Test - public void simpleDiscoveryClientShouldBeTheDefault() { - then(this.discoveryClient).isInstanceOf(CompositeDiscoveryClient.class); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - public static class Config { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ReactiveSimpleDiscoveryPropertiesAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ReactiveSimpleDiscoveryPropertiesAutoConfigurationTests.java deleted file mode 100644 index 45d8f0b8..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ReactiveSimpleDiscoveryPropertiesAutoConfigurationTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -import org.junit.jupiter.api.Test; - -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.server.LocalServerPort; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Ryan Baxter - */ -@SpringBootTest(classes = ReactiveSimpleDiscoveryPropertiesAutoConfigurationTests.Config.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = "spring.main.web-application-type=reactive") -public class ReactiveSimpleDiscoveryPropertiesAutoConfigurationTests { - - @Autowired - private SimpleDiscoveryProperties discoveryProperties; - - @LocalServerPort - private int port; - - @Test - public void testPort() { - then(discoveryProperties.getLocal().getPort()).isEqualTo(port); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - public static class Config { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ServletSimpleDiscoveryPropertiesAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ServletSimpleDiscoveryPropertiesAutoConfigurationTests.java deleted file mode 100644 index 23d73d73..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/ServletSimpleDiscoveryPropertiesAutoConfigurationTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -import org.junit.jupiter.api.Test; - -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.server.LocalServerPort; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Ryan Baxter - */ -@SpringBootTest(classes = ServletSimpleDiscoveryPropertiesAutoConfigurationTests.Config.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class ServletSimpleDiscoveryPropertiesAutoConfigurationTests { - - @Autowired - private SimpleDiscoveryProperties discoveryProperties; - - @LocalServerPort - private int port; - - @Test - public void testPort() { - then(discoveryProperties.getLocal().getPort()).isEqualTo(port); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - public static class Config { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java deleted file mode 100644 index 699e8b0e..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -import java.net.URI; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * Tests for mapping properties to instances in {@link SimpleDiscoveryClient}. - * - * @author Biju Kunjummen - */ - -@SpringBootTest(properties = { "spring.application.name=service0", - "spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s11:8080", - "spring.cloud.discovery.client.simple.instances.service1[1].uri=https://s12:8443", - "spring.cloud.discovery.client.simple.instances.service2[0].uri=https://s21:8080", - "spring.cloud.discovery.client.simple.instances.service2[1].uri=https://s22:443" }) -public class SimpleDiscoveryClientPropertiesMappingTests { - - @Autowired - private SimpleDiscoveryProperties props; - - @Autowired - private SimpleDiscoveryClient discoveryClient; - - @Test - public void propsShouldGetCleanlyMapped() { - then(this.props.getInstances().size()).isEqualTo(2); - then(this.props.getInstances().get("service1").size()).isEqualTo(2); - then(this.props.getInstances().get("service1").get(0).getHost()).isEqualTo("s11"); - then(this.props.getInstances().get("service1").get(0).getPort()).isEqualTo(8080); - then(this.props.getInstances().get("service1").get(0).getUri()).isEqualTo(URI.create("http://s11:8080")); - then(this.props.getInstances().get("service1").get(0).isSecure()).isEqualTo(false); - - then(this.props.getInstances().get("service2").size()).isEqualTo(2); - then(this.props.getInstances().get("service2").get(0).getHost()).isEqualTo("s21"); - then(this.props.getInstances().get("service2").get(0).getPort()).isEqualTo(8080); - then(this.props.getInstances().get("service2").get(0).getUri()).isEqualTo(URI.create("https://s21:8080")); - then(this.props.getInstances().get("service2").get(0).isSecure()).isEqualTo(true); - } - - @Test - public void testDiscoveryClientShouldResolveSimpleValues() { - then(this.discoveryClient.description()).isEqualTo("Simple Discovery Client"); - then(this.discoveryClient.getInstances("service1")).hasSize(2); - - ServiceInstance s1 = this.discoveryClient.getInstances("service1").get(0); - then(s1.getHost()).isEqualTo("s11"); - then(s1.getPort()).isEqualTo(8080); - then(s1.getUri()).isEqualTo(URI.create("http://s11:8080")); - then(s1.isSecure()).isEqualTo(false); - } - - @Test - public void testGetServices() { - then(this.discoveryClient.getServices()).containsExactlyInAnyOrder("service1", "service2"); - } - - @Test - public void testGetANonExistentServiceShouldReturnAnEmptyList() { - then(this.discoveryClient.getInstances("nonexistent")).isNotNull(); - then(this.discoveryClient.getInstances("nonexistent")).isEmpty(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - public static class SampleConfig { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientTests.java deleted file mode 100644 index 537a3d8b..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple; - -import java.net.URI; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Biju Kunjummen - * @author Charu Covindane - * @author Neil Powell - */ -public class SimpleDiscoveryClientTests { - - private SimpleDiscoveryClient simpleDiscoveryClient; - - @BeforeEach - public void setUp() { - SimpleDiscoveryProperties simpleDiscoveryProperties = new SimpleDiscoveryProperties(); - - Map> map = new HashMap<>(); - DefaultServiceInstance service1Inst1 = new DefaultServiceInstance(null, null, "host1", 8080, false); - DefaultServiceInstance service1Inst2 = new DefaultServiceInstance(null, null, "host2", 0, true); - DefaultServiceInstance service1Inst3 = new DefaultServiceInstance(null, null, "host3", 0, false); - map.put("service1", Arrays.asList(service1Inst1, service1Inst2, service1Inst3)); - simpleDiscoveryProperties.setInstances(map); - simpleDiscoveryProperties.afterPropertiesSet(); - this.simpleDiscoveryClient = new SimpleDiscoveryClient(simpleDiscoveryProperties); - } - - @Test - public void shouldBeAbleToRetrieveServiceDetailsByName() { - List instances = this.simpleDiscoveryClient.getInstances("service1"); - then(instances.size()).isEqualTo(3); - then(instances.get(0).getServiceId()).isEqualTo("service1"); - then(instances.get(0).getHost()).isEqualTo("host1"); - then(instances.get(0).getPort()).isEqualTo(8080); - then(instances.get(0).getUri()).isEqualTo(URI.create("http://host1:8080")); - then(instances.get(0).isSecure()).isEqualTo(false); - then(instances.get(0).getMetadata()).isNotNull(); - - then(instances.get(1).getServiceId()).isEqualTo("service1"); - then(instances.get(1).getHost()).isEqualTo("host2"); - then(instances.get(1).getPort()).isEqualTo(0); - then(instances.get(1).getUri()).isEqualTo(URI.create("https://host2:443")); - then(instances.get(1).isSecure()).isEqualTo(true); - then(instances.get(1).getMetadata()).isNotNull(); - - then(instances.get(2).getServiceId()).isEqualTo("service1"); - then(instances.get(2).getHost()).isEqualTo("host3"); - then(instances.get(2).getPort()).isEqualTo(0); - then(instances.get(2).getUri()).isEqualTo(URI.create("http://host3:80")); - then(instances.get(2).isSecure()).isEqualTo(false); - then(instances.get(2).getMetadata()).isNotNull(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfigurationTests.java deleted file mode 100644 index b6ba733a..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientAutoConfigurationTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple.reactive; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.commons.util.InetUtils; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Tim Ysewyn - */ -class SimpleReactiveDiscoveryClientAutoConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(SimpleReactiveDiscoveryClientAutoConfiguration.class, UtilAutoConfiguration.class)); - - @Test - public void shouldUseDefaults() { - this.contextRunner.run((context) -> { - ReactiveDiscoveryClient client = context.getBean(ReactiveDiscoveryClient.class); - assertThat(client).isNotNull(); - assertThat(client.getOrder()).isEqualTo(ReactiveDiscoveryClient.DEFAULT_ORDER); - InetUtils inet = context.getBean(InetUtils.class); - assertThat(inet).isNotNull(); - SimpleReactiveDiscoveryProperties properties = context.getBean(SimpleReactiveDiscoveryProperties.class); - assertThat(properties).isNotNull(); - assertThat(properties.getLocal().getServiceId()).isEqualTo("application"); - assertThat(properties.getLocal().getHost()).isEqualTo(inet.findFirstNonLoopbackHostInfo().getHostname()); - assertThat(properties.getLocal().getPort()).isEqualTo(8080); - }); - } - - @Test - public void shouldUseCustomConfiguration() { - this.contextRunner.withUserConfiguration(Configuration.class) - .withPropertyValues("spring.application.name=my-service", - "spring.cloud.discovery.client.simple.order=1", "server.port=8443") - .run((context) -> { - ReactiveDiscoveryClient client = context.getBean(ReactiveDiscoveryClient.class); - assertThat(client).isNotNull(); - assertThat(client.getOrder()).isEqualTo(1); - InetUtils inet = context.getBean(InetUtils.class); - assertThat(inet).isNotNull(); - SimpleReactiveDiscoveryProperties properties = context - .getBean(SimpleReactiveDiscoveryProperties.class); - assertThat(properties).isNotNull(); - assertThat(properties.getLocal().getServiceId()).isEqualTo("my-service"); - assertThat(properties.getLocal().getHost()) - .isEqualTo(inet.findFirstNonLoopbackHostInfo().getHostname()); - assertThat(properties.getLocal().getPort()).isEqualTo(8443); - }); - } - - @TestConfiguration - @EnableConfigurationProperties(ServerProperties.class) - static class Configuration { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientTests.java deleted file mode 100644 index 628fef18..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/reactive/SimpleReactiveDiscoveryClientTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.discovery.simple.reactive; - -import java.util.Arrays; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; - -import static java.util.Collections.singletonMap; -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Tim Ysewyn - * @author Charu Covindane - */ -public class SimpleReactiveDiscoveryClientTests { - - private final DefaultServiceInstance service1Inst1 = new DefaultServiceInstance(null, null, "host1", 8080, false); - - private final DefaultServiceInstance service1Inst2 = new DefaultServiceInstance(null, null, "host2", 8443, true); - - private SimpleReactiveDiscoveryClient client; - - @BeforeEach - public void setUp() { - SimpleReactiveDiscoveryProperties simpleReactiveDiscoveryProperties = new SimpleReactiveDiscoveryProperties(); - simpleReactiveDiscoveryProperties - .setInstances(singletonMap("service", Arrays.asList(service1Inst1, service1Inst2))); - simpleReactiveDiscoveryProperties.afterPropertiesSet(); - this.client = new SimpleReactiveDiscoveryClient(simpleReactiveDiscoveryProperties); - } - - @Test - public void verifyDefaults() { - assertThat(client.description()).isEqualTo("Simple Reactive Discovery Client"); - assertThat(client.getOrder()).isEqualTo(ReactiveDiscoveryClient.DEFAULT_ORDER); - } - - @Test - public void shouldReturnFluxOfServices() { - Flux services = this.client.getServices(); - StepVerifier.create(services).expectNext("service").expectComplete().verify(); - } - - @Test - public void shouldReturnEmptyFluxForNonExistingService() { - Flux instances = this.client.getInstances("undefined"); - StepVerifier.create(instances).expectComplete().verify(); - } - - @Test - public void shouldReturnFluxOfServiceInstances() { - Flux services = this.client.getInstances("service"); - StepVerifier.create(services).expectNext(service1Inst1).expectNext(service1Inst2).expectComplete().verify(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfigurationIntegrationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfigurationIntegrationTests.java deleted file mode 100644 index 10b38141..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/CloudHypermediaAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration.CloudHypermediaProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * Integration tests for {@link CloudHypermediaAutoConfiguration}. - * - * @author Oliver Gierke - * @author Tim Ysewyn - */ -public class CloudHypermediaAutoConfigurationIntegrationTests { - - private static ConfigurableApplicationContext getApplicationContext(Class configuration) { - return new SpringApplicationBuilder(configuration).properties("server.port=0").run(); - } - - @Test - public void picksUpHypermediaProperties() { - - try (ConfigurableApplicationContext context = getApplicationContext(ConfigWithRemoteResource.class)) { - - CloudHypermediaProperties properties = context.getBean(CloudHypermediaProperties.class); - - then(properties.getRefresh().getInitialDelay()).isEqualTo(50000); - then(properties.getRefresh().getFixedDelay()).isEqualTo(10000); - } - } - - @Test - public void doesNotCreateCloudHypermediaPropertiesifNotActive() { - - try (ConfigurableApplicationContext context = getApplicationContext(Config.class)) { - then(context.getBeanNamesForType(CloudHypermediaProperties.class)).hasSize(0); - } - } - - @Test - public void doesNotRegisterResourceRefresherIfNoDiscoveredResourceIsDefined() { - - try (ConfigurableApplicationContext context = getApplicationContext(Config.class)) { - - then(context.getBeansOfType(RemoteResource.class).values()).hasSize(0); - then(context.getBeanNamesForType(RemoteResourceRefresher.class)).hasSize(0); - } - } - - @Test - public void registersResourceRefresherIfDiscoverredResourceIsDefined() { - - try (ConfigurableApplicationContext context = getApplicationContext(ConfigWithRemoteResource.class)) { - - then(context.getBeansOfType(RemoteResource.class).values()).hasSize(1); - then(context.getBean(RemoteResourceRefresher.class)).isNotNull(); - } - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class Config { - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class ConfigWithRemoteResource { - - @Bean - public RemoteResource resource() { - - ServiceInstanceProvider provider = new StaticServiceInstanceProvider( - new DefaultServiceInstance("instance", "service", "localhost", 80, false)); - return new DiscoveredResource(provider, traverson -> traverson.follow("rel")); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DiscoveredResourceUnitTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DiscoveredResourceUnitTests.java deleted file mode 100644 index 35484df7..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DiscoveredResourceUnitTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.hateoas.Link; -import org.springframework.hateoas.client.Traverson; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestOperations; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Oliver Gierke - * @author Tim Ysewyn - */ -@ExtendWith(MockitoExtension.class) -public class DiscoveredResourceUnitTests { - - @Mock - ServiceInstanceProvider provider; - - @Mock - TraversalDefinition traversal; - - @Mock - Traverson.TraversalBuilder builder; - - @Mock - RestOperations operations; - - DiscoveredResource resource; - - @BeforeEach - public void setUp() { - lenient().when(this.traversal.buildTraversal(any(Traverson.class))).thenReturn(this.builder); - - this.resource = new DiscoveredResource(this.provider, this.traversal); - this.resource.setRestOperations(this.operations); - } - - @Test - public void isUndiscoveredByDefault() { - then(this.resource.getLink()).isNull(); - } - - @Test - public void verificationTriggersDiscovery() { - - Link link = Link.of("target", "rel"); - - when(this.provider.getServiceInstance()) - .thenReturn(new DefaultServiceInstance("instance", "service", "localhost", 8080, false)); - when(this.builder.asTemplatedLink()).thenReturn(link); - - this.resource.verifyOrDiscover(); - - then(this.resource.getLink()).isEqualTo(link); - verify(this.provider, times(1)).getServiceInstance(); - verify(this.traversal, times(1)).buildTraversal(any(Traverson.class)); - } - - @Test - public void triggersVerificationOnSubsequentCall() { - - verificationTriggersDiscovery(); - - this.resource.verifyOrDiscover(); - - then(this.resource.getLink()).isNotNull(); - verify(this.operations, times(1)).headForHeaders(anyString()); - } - - @Test - public void resetsLinkOnFailedVerification() { - - verificationTriggersDiscovery(); - - doThrow(RestClientException.class).when(this.operations).headForHeaders(anyString()); - this.resource.verifyOrDiscover(); - - then(this.resource.getLink()).isNull(); - } - - @Test - public void failedDiscoveryTraversalCausesLinkToStayNull() { - - doThrow(RuntimeException.class).when(this.provider).getServiceInstance(); - - this.resource.verifyOrDiscover(); - - then(this.resource.getLink()).isNull(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProviderUnitTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProviderUnitTests.java deleted file mode 100644 index eec0c01c..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/hypermedia/DynamicServiceInstanceProviderUnitTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.hypermedia; - -import java.util.Arrays; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Oliver Gierke - */ -@ExtendWith(MockitoExtension.class) -public class DynamicServiceInstanceProviderUnitTests { - - @Mock - DiscoveryClient client; - - @Test - public void returnsNoServiceInCaseNoneIsAvailable() { - then(new DynamicServiceInstanceProvider(this.client, "service").getServiceInstance()).isNull(); - } - - @Test - public void returnsFirstServiceInCaseMultipleOnesAreAvailable() { - - ServiceInstance first = mock(ServiceInstance.class); - ServiceInstance second = mock(ServiceInstance.class); - - when(this.client.getInstances(anyString())).thenReturn(Arrays.asList(first, second)); - - then(new DynamicServiceInstanceProvider(this.client, "service").getServiceInstance()).isEqualTo(first); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/AbstractLoadBalancerAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/AbstractLoadBalancerAutoConfigurationTests.java deleted file mode 100644 index a4be354d..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/AbstractLoadBalancerAutoConfigurationTests.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.net.URI; -import java.util.Collection; -import java.util.Map; -import java.util.Random; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer.REQUEST; - -/** - * @author Ryan Baxter - * @author Tim Ysewyn - * @author Olga Maciaszek-Sharma - */ -public abstract class AbstractLoadBalancerAutoConfigurationTests { - - @Test - public void restTemplateGetsLoadBalancerInterceptor() { - ConfigurableApplicationContext context = init(OneRestTemplate.class); - final Map restTemplates = context.getBeansOfType(RestTemplate.class); - - then(restTemplates).isNotNull(); - then(restTemplates.values()).hasSize(1); - RestTemplate restTemplate = restTemplates.values().iterator().next(); - then(restTemplate).isNotNull(); - - assertLoadBalanced(restTemplate); - } - - protected abstract void assertLoadBalanced(RestTemplate restTemplate); - - @Test - public void multipleRestTemplates() { - ConfigurableApplicationContext context = init(TwoRestTemplates.class); - final Map restTemplates = context.getBeansOfType(RestTemplate.class); - - then(restTemplates).isNotNull(); - Collection templates = restTemplates.values(); - then(templates).hasSize(2); - - TwoRestTemplates.Two two = context.getBean(TwoRestTemplates.Two.class); - - then(two.loadBalanced).isNotNull(); - assertLoadBalanced(two.loadBalanced); - - then(two.nonLoadBalanced).isNotNull(); - then(two.nonLoadBalanced.getInterceptors()).isEmpty(); - } - - protected ConfigurableApplicationContext init(Class config) { - return init(config, "spring.aop.proxyTargetClass=true"); - } - - protected ConfigurableApplicationContext init(Class config, String... props) { - return new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(props) - .sources(config, LoadBalancerAutoConfiguration.class).run(); - } - - @Configuration(proxyBeanMethods = false) - protected static class OneRestTemplate { - - @LoadBalanced - @Bean - RestTemplate loadBalancedRestTemplate() { - return new RestTemplate(); - } - - @Bean - LoadBalancerClient loadBalancerClient() { - return new NoopLoadBalancerClient(); - } - - @Bean - ReactiveLoadBalancer.Factory loadBalancerFactory(LoadBalancerProperties properties) { - return new TestLoadBalancerFactory(properties); - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(OneRestTemplate.class) - protected static class TwoRestTemplates { - - @Primary - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } - - @Configuration(proxyBeanMethods = false) - protected static class Two { - - @Autowired - RestTemplate nonLoadBalanced; - - @Autowired - @LoadBalanced - RestTemplate loadBalanced; - - } - - } - - private static class NoopLoadBalancerClient implements LoadBalancerClient { - - private final Random random = new Random(); - - @Override - public ServiceInstance choose(String serviceId) { - return choose(serviceId, REQUEST); - } - - @Override - public ServiceInstance choose(String serviceId, Request request) { - return new DefaultServiceInstance(serviceId, serviceId, serviceId, this.random.nextInt(40000), false); - } - - @Override - public T execute(String serviceId, LoadBalancerRequest request) { - try { - return request.apply(choose(serviceId, REQUEST)); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) { - try { - return request.apply(choose(serviceId, REQUEST)); - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public URI reconstructURI(ServiceInstance instance, URI original) { - return DefaultServiceInstance.getUri(instance); - } - - } - - private static class TestLoadBalancerFactory implements ReactiveLoadBalancer.Factory { - - private final LoadBalancerProperties properties; - - TestLoadBalancerFactory(LoadBalancerProperties properties) { - this.properties = properties; - } - - @Override - public ReactiveLoadBalancer getInstance(String serviceId) { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - public Object getInstance(String name, Class clazz, Class[] generics) { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - public Map getInstances(String name, Class type) { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - public LoadBalancerProperties getProperties(String serviceId) { - return properties; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeExceptionTest.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeExceptionTest.java deleted file mode 100644 index a51f3330..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/ClientHttpResponseStatusCodeExceptionTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.http.HttpHeaders; -import org.springframework.http.client.AbstractClientHttpResponse; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Ryan Baxter - */ -@ExtendWith(MockitoExtension.class) -public class ClientHttpResponseStatusCodeExceptionTest { - - @Test - public void testCreation() throws Exception { - MyClientHttpResponse response = new MyClientHttpResponse(); - then(response.isClosed()).isFalse(); - ClientHttpResponseStatusCodeException exp = new ClientHttpResponseStatusCodeException("service", response, - response.getStatusText().getBytes()); - ClientHttpResponse expResponse = exp.getResponse(); - then(expResponse.getStatusCode().value()).isEqualTo(response.getRawStatusCode()); - then(expResponse.getStatusText()).isEqualTo(response.getStatusText()); - then(expResponse.getHeaders()).isEqualTo(response.getHeaders()); - then(new String(StreamUtils.copyToByteArray(expResponse.getBody()))).isEqualTo(response.getStatusText()); - } - - static class MyClientHttpResponse extends AbstractClientHttpResponse { - - private boolean closed = false; - - @Override - public int getRawStatusCode() { - return 200; - } - - @Override - public String getStatusText() { - return "foo"; - } - - @Override - public void close() { - this.closed = true; - } - - public boolean isClosed() { - return this.closed; - } - - @Override - public InputStream getBody() throws IOException { - return new ByteArrayInputStream(getStatusText().getBytes()); - } - - @Override - public HttpHeaders getHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.add("foo", "bar"); - return headers; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicyTest.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicyTest.java deleted file mode 100644 index 7c135d2c..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/InterceptorRetryPolicyTest.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryContext; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -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 Ryan Baxter - * @author Olga Maciaszek-Sharma - */ -@ExtendWith(MockitoExtension.class) -public class InterceptorRetryPolicyTest { - - private HttpRequest request; - - private LoadBalancedRetryPolicy policy; - - private ServiceInstanceChooser serviceInstanceChooser; - - private String serviceName; - - @BeforeEach - public void setup() { - request = mock(HttpRequest.class); - policy = mock(LoadBalancedRetryPolicy.class); - serviceInstanceChooser = mock(ServiceInstanceChooser.class); - serviceName = "foo"; - } - - @AfterEach - public void teardown() { - request = null; - policy = null; - serviceInstanceChooser = null; - serviceName = null; - } - - @Test - public void canRetryBeforeExecution() { - when(policy.retryableException(any())).thenReturn(true); - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - LoadBalancedRetryContext context = mock(LoadBalancedRetryContext.class); - when(context.getRetryCount()).thenReturn(0); - - then(interceptorRetryPolicy.canRetry(context)).isTrue(); - verify(context, times(1)).setServiceInstance(eq(null)); - } - - @Test - public void canRetryNextServer() { - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - LoadBalancedRetryContext context = mock(LoadBalancedRetryContext.class); - when(context.getRetryCount()).thenReturn(1); - when(policy.canRetryNextServer(eq(context))).thenReturn(true); - when(policy.retryableException(any())).thenReturn(true); - - then(interceptorRetryPolicy.canRetry(context)).isTrue(); - } - - @Test - public void cannotRetryOnException() { - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - LoadBalancedRetryContext context = mock(LoadBalancedRetryContext.class); - when(policy.retryableException(any())).thenReturn(false); - - then(interceptorRetryPolicy.canRetry(context)).isFalse(); - } - - @Test - public void cannotRetry() { - when(policy.retryableException(any())).thenReturn(true); - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - LoadBalancedRetryContext context = mock(LoadBalancedRetryContext.class); - when(context.getRetryCount()).thenReturn(1); - - then(interceptorRetryPolicy.canRetry(context)).isFalse(); - } - - @Test - public void open() { - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - - RetryContext context = interceptorRetryPolicy.open(null); - - then(context).isInstanceOf(LoadBalancedRetryContext.class); - } - - @Test - public void close() { - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - LoadBalancedRetryContext context = mock(LoadBalancedRetryContext.class); - - interceptorRetryPolicy.close(context); - - verify(policy, times(1)).close(eq(context)); - } - - @Test - public void registerThrowable() { - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - LoadBalancedRetryContext context = mock(LoadBalancedRetryContext.class); - Throwable thrown = new Exception(); - - interceptorRetryPolicy.registerThrowable(context, thrown); - - verify(context, times(1)).registerThrowable(eq(thrown)); - verify(policy, times(1)).registerThrowable(eq(context), eq(thrown)); - } - - @Test - public void equals() { - InterceptorRetryPolicy interceptorRetryPolicy = new InterceptorRetryPolicy(request, policy, - serviceInstanceChooser, serviceName); - - then(interceptorRetryPolicy.equals(null)).isFalse(); - then(interceptorRetryPolicy.equals(new Object())).isFalse(); - then(interceptorRetryPolicy.equals(interceptorRetryPolicy)).isTrue(); - then(interceptorRetryPolicy - .equals(new InterceptorRetryPolicy(request, policy, serviceInstanceChooser, serviceName))).isTrue(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContextTest.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContextTest.java deleted file mode 100644 index 6025411e..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryContextTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.http.HttpRequest; -import org.springframework.retry.RetryContext; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - */ -@ExtendWith(MockitoExtension.class) -public class LoadBalancedRetryContextTest { - - private RetryContext context; - - private HttpRequest request; - - @BeforeEach - public void setUp() throws Exception { - this.context = mock(RetryContext.class); - this.request = mock(HttpRequest.class); - } - - @AfterEach - public void tearDown() { - this.context = null; - this.request = null; - } - - @Test - public void getRequest() { - LoadBalancedRetryContext lbContext = new LoadBalancedRetryContext(this.context, this.request); - then(lbContext.getRequest()).isEqualTo(this.request); - } - - @Test - public void setRequest() { - LoadBalancedRetryContext lbContext = new LoadBalancedRetryContext(this.context, this.request); - HttpRequest newRequest = mock(HttpRequest.class); - lbContext.setRequest(newRequest); - then(lbContext.getRequest()).isEqualTo(newRequest); - } - - @Test - public void getServiceInstance() { - LoadBalancedRetryContext lbContext = new LoadBalancedRetryContext(this.context, this.request); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - lbContext.setServiceInstance(serviceInstance); - then(lbContext.getServiceInstance()).isEqualTo(serviceInstance); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfigurationTests.java deleted file mode 100644 index 40436e92..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerAutoConfigurationTests.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.List; - -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - */ -@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" }) -public class LoadBalancerAutoConfigurationTests extends AbstractLoadBalancerAutoConfigurationTests { - - @Override - protected void assertLoadBalanced(RestTemplate restTemplate) { - List interceptors = restTemplate.getInterceptors(); - then(interceptors).hasSize(1); - ClientHttpRequestInterceptor interceptor = interceptors.get(0); - then(interceptor).isInstanceOf(LoadBalancerInterceptor.class); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryConfigurationTests.java deleted file mode 100644 index 9f736755..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryConfigurationTests.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class LoadBalancerRequestFactoryConfigurationTests { - - @Mock - private HttpRequest request; - - @Mock - private HttpRequest transformedRequest; - - @Mock - private HttpRequest transformedRequest2; - - @Mock - private ClientHttpRequestExecution execution; - - @Mock - private ServiceInstance instance; - - private final byte[] body = new byte[] {}; - - private ArgumentCaptor httpRequestCaptor; - - private LoadBalancerRequest lbRequest; - - @BeforeEach - public void setup() { - this.httpRequestCaptor = ArgumentCaptor.forClass(HttpRequest.class); - } - - protected ConfigurableApplicationContext init(Class config) { - ConfigurableApplicationContext context = new SpringApplicationBuilder().web(WebApplicationType.NONE) - .properties("spring.aop.proxyTargetClass=true").sources(config, LoadBalancerAutoConfiguration.class) - .run(); - - LoadBalancerRequestFactory lbReqFactory = context.getBean(LoadBalancerRequestFactory.class); - this.lbRequest = lbReqFactory.createRequest(this.request, this.body, this.execution); - return context; - } - - @Test - public void transformer() throws Exception { - ConfigurableApplicationContext context = init(Transformer.class); - - LoadBalancerRequestTransformer transformer = context.getBean("transformer", - LoadBalancerRequestTransformer.class); - when(transformer.transformRequest(any(ServiceRequestWrapper.class), eq(this.instance))) - .thenReturn(this.transformedRequest); - - this.lbRequest.apply(this.instance); - - verify(this.execution).execute(this.httpRequestCaptor.capture(), eq(this.body)); - then(this.httpRequestCaptor.getValue()) - .as("transformer should have transformed the ServiceRequestWrapper into transformedRequest") - .isEqualTo(this.transformedRequest); - } - - @Test - public void noTransformer() throws Exception { - init(NoTransformer.class); - - this.lbRequest.apply(this.instance); - - verify(this.execution).execute(this.httpRequestCaptor.capture(), eq(this.body)); - then(this.httpRequestCaptor.getValue().getClass()).as("ServiceRequestWrapper should be executed") - .isEqualTo(ServiceRequestWrapper.class); - } - - @Test - public void transformersAreOrdered() throws Exception { - ConfigurableApplicationContext context = init(TransformersAreOrdered.class); - - LoadBalancerRequestTransformer transformer = context.getBean("transformer", - LoadBalancerRequestTransformer.class); - when(transformer.transformRequest(any(ServiceRequestWrapper.class), eq(this.instance))) - .thenReturn(this.transformedRequest); - LoadBalancerRequestTransformer transformer2 = context.getBean("transformer2", - LoadBalancerRequestTransformer.class); - when(transformer2.transformRequest(this.transformedRequest, this.instance)) - .thenReturn(this.transformedRequest2); - - this.lbRequest.apply(this.instance); - - verify(this.execution).execute(this.httpRequestCaptor.capture(), eq(this.body)); - then(this.httpRequestCaptor.getValue()).as("transformer2 should run after transformer") - .isEqualTo(this.transformedRequest2); - } - - @Configuration(proxyBeanMethods = false) - @Import(NoTransformer.class) - static class Transformer { - - @Bean - public LoadBalancerRequestTransformer transformer() { - return mock(LoadBalancerRequestTransformer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - @Import(Transformer.class) - static class TransformersAreOrdered { - - @Bean - @Order(LoadBalancerRequestTransformer.DEFAULT_ORDER + 1) - public LoadBalancerRequestTransformer transformer2() { - return mock(LoadBalancerRequestTransformer.class); - } - - } - - @Configuration(proxyBeanMethods = false) - static class NoTransformer { - - @Bean - public LoadBalancerClient loadBalancerClient() { - return mock(LoadBalancerClient.class); - } - - @SuppressWarnings("unchecked") - @Bean - ReactiveLoadBalancer.Factory factory() { - return mock(ReactiveLoadBalancer.Factory.class); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryTests.java deleted file mode 100644 index 18a79b16..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRequestFactoryTests.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class LoadBalancerRequestFactoryTests { - - @Mock - private LoadBalancerClient loadBalancer; - - @Mock - private HttpRequest request; - - @Mock - private HttpRequest transformedRequest1; - - @Mock - private HttpRequest transformedRequest2; - - private byte[] body = new byte[] {}; - - @Mock - private ClientHttpRequestExecution execution; - - @Mock - private ServiceInstance instance; - - @Mock - private LoadBalancerRequestTransformer transformer1; - - @Mock - private LoadBalancerRequestTransformer transformer2; - - private ArgumentCaptor httpRequestCaptor; - - @BeforeEach - public void setup() { - this.httpRequestCaptor = ArgumentCaptor.forClass(HttpRequest.class); - } - - @Test - public void testNullTransformers() throws Exception { - executeLbRequest(null); - - verify(this.execution).execute(this.httpRequestCaptor.capture(), eq(this.body)); - then(this.httpRequestCaptor.getValue().getClass()).as("request should be of type ServiceRequestWrapper") - .isEqualTo(ServiceRequestWrapper.class); - } - - @Test - public void testEmptyTransformers() throws Exception { - List transformers = Collections.emptyList(); - - executeLbRequest(transformers); - - verify(this.execution).execute(this.httpRequestCaptor.capture(), eq(this.body)); - then(this.httpRequestCaptor.getValue().getClass()).as("request should be of type ServiceRequestWrapper") - .isEqualTo(ServiceRequestWrapper.class); - } - - @Test - public void testOneTransformer() throws Exception { - List transformers = List.of(this.transformer1); - when(this.transformer1.transformRequest(any(ServiceRequestWrapper.class), eq(this.instance))) - .thenReturn(this.transformedRequest1); - - executeLbRequest(transformers); - - verify(this.execution).execute(this.httpRequestCaptor.capture(), eq(this.body)); - then(this.httpRequestCaptor.getValue()) - .as("transformer1 should have transformed request into transformedRequest1") - .isEqualTo(this.transformedRequest1); - } - - @Test - public void testTwoTransformers() throws Exception { - List transformers = Arrays.asList(this.transformer1, this.transformer2); - when(this.transformer1.transformRequest(any(ServiceRequestWrapper.class), eq(this.instance))) - .thenReturn(this.transformedRequest1); - when(this.transformer2.transformRequest(this.transformedRequest1, this.instance)) - .thenReturn(this.transformedRequest2); - - executeLbRequest(transformers); - - verify(this.execution).execute(this.httpRequestCaptor.capture(), eq(this.body)); - then(this.httpRequestCaptor.getValue()) - .as("transformer2 should have transformed transformedRequest1 into transformedRequest2") - .isEqualTo(this.transformedRequest2); - } - - private void executeLbRequest(List transformers) throws Exception { - LoadBalancerRequestFactory lbReqFactory = new LoadBalancerRequestFactory(this.loadBalancer, transformers); - LoadBalancerRequest lbRequest = lbReqFactory.createRequest(this.request, this.body, - this.execution); - lbRequest.apply(this.instance); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriToolsTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriToolsTests.java deleted file mode 100644 index 7a40ebcb..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/LoadBalancerUriToolsTests.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.net.URI; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LoadBalancerUriTools}. - * - * @author Olga Maciaszek-Sharma - */ -class LoadBalancerUriToolsTests { - - @Test - void originalURIReturnedIfDataMatches() { - TestServiceInstance serviceInstance = new TestServiceInstance(); - URI original = UriComponentsBuilder.fromUriString("http://test.example:8080/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isEqualTo(original); - } - - @Test - void serviceInstanceHostSet() { - TestServiceInstance serviceInstance = new TestServiceInstance(); - URI original = UriComponentsBuilder.fromUriString("http://testHost.example:8080/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getHost()).isEqualTo(serviceInstance.getHost()); - } - - @Test - void serviceInstanceSchemeSet() { - TestServiceInstance serviceInstance = new TestServiceInstance().withScheme("https"); - URI original = UriComponentsBuilder.fromUriString("http://test.example/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getScheme()).isEqualTo(serviceInstance.getScheme()); - } - - @Test - void originalSchemeSetIfServiceInstanceSchemeMissing() { - TestServiceInstance serviceInstance = new TestServiceInstance().withScheme(null); - URI original = UriComponentsBuilder.fromUriString("https://test.example/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getScheme()).isEqualTo(original.getScheme()); - } - - @Test - void secureSchemeSetIfServiceInstanceSchemeMissingAndServiceInstanceSecure() { - TestServiceInstance serviceInstance = new TestServiceInstance().withScheme(null).withSecure(true); - URI original = UriComponentsBuilder.fromUriString("http://test.example/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getScheme()).isEqualTo("https"); - } - - @Test - void secureWsSchemeSetIfServiceInstanceSchemeMissingAndServiceInstanceSecure() { - TestServiceInstance serviceInstance = new TestServiceInstance().withScheme(null).withSecure(true); - URI original = UriComponentsBuilder.fromUriString("ws://test.example/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getScheme()).isEqualTo("wss"); - } - - @Test - void defaultSchemeSetIfMissing() { - TestServiceInstance serviceInstance = new TestServiceInstance().withScheme(null); - URI original = UriComponentsBuilder.fromUriString("//test.example/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getScheme()).isEqualTo("http"); - } - - @Test - void serviceInstancePortSet() { - TestServiceInstance serviceInstance = new TestServiceInstance().withPort(0); - URI original = UriComponentsBuilder.fromUriString("http://test.example:8080/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getPort()).isEqualTo(serviceInstance.getPort()); - } - - @Test - void defaultHttpPortSetIfServiceInstancePortIncorrect() { - TestServiceInstance serviceInstance = new TestServiceInstance().withPort(-1); - URI original = UriComponentsBuilder.fromUriString("http://test.example:8888/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getPort()).isEqualTo(80); - } - - @Test - void defaultHttpsPortSetIfServiceInstancePortIncorrect() { - TestServiceInstance serviceInstance = new TestServiceInstance().withScheme("https").withPort(-1); - URI original = UriComponentsBuilder.fromUriString("http://test.example:8888/xxx").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getPort()).isEqualTo(443); - } - - @Test - void originalUserInfoSet() { - TestServiceInstance serviceInstance = new TestServiceInstance(); - URI original = UriComponentsBuilder - .fromUriString("http://testUser@testHost.example/path?query1=test1&query2=test2#fragment").build() - .toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getRawUserInfo()).isEqualTo(original.getRawUserInfo()); - assertThat(reconstructed.getRawQuery()).isEqualTo(original.getRawQuery()); - assertThat(reconstructed.getRawPath()).isEqualTo(original.getRawPath()); - assertThat(reconstructed.getRawQuery()).isEqualTo(original.getRawQuery()); - assertThat(reconstructed.getRawFragment()).isEqualTo(original.getRawFragment()); - assertThat(reconstructed.getHost()).isEqualTo(serviceInstance.getHost()); - assertThat(reconstructed.getPort()).isEqualTo(serviceInstance.getPort()); - } - - @Test - void reconstructedURIEncodedCorrectly() { - TestServiceInstance serviceInstance = new TestServiceInstance(); - URI original = UriComponentsBuilder - .fromUriString("http://test.example/path%40%21%242?query=val%40%21%242#frag%40%21%242").build().toUri(); - - URI reconstructed = LoadBalancerUriTools.reconstructURI(serviceInstance, original); - - assertThat(reconstructed).isNotNull(); - assertThat(reconstructed.getRawUserInfo()).isEqualTo(original.getRawUserInfo()); - assertThat(reconstructed.getRawQuery()).isEqualTo(original.getRawQuery()); - assertThat(reconstructed.getRawPath()).isEqualTo(original.getRawPath()); - assertThat(reconstructed.getRawQuery()).isEqualTo(original.getRawQuery()); - assertThat(reconstructed.getRawFragment()).isEqualTo(original.getRawFragment()); - assertThat(reconstructed.getHost()).isEqualTo(serviceInstance.getHost()); - assertThat(reconstructed.getPort()).isEqualTo(serviceInstance.getPort()); - } - -} - -class TestServiceInstance implements ServiceInstance { - - private URI uri; - - private String scheme = "http"; - - private int port = 8080; - - private boolean secure; - - private Map metadata = new LinkedHashMap<>(); - - TestServiceInstance withScheme(String scheme) { - this.scheme = scheme; - return this; - } - - TestServiceInstance withPort(int port) { - this.port = port; - return this; - } - - TestServiceInstance withSecure(boolean secure) { - this.secure = secure; - return this; - } - - @Override - public String getServiceId() { - return "test-service"; - } - - @Override - public String getHost() { - String host = "test.example"; - return host; - } - - @Override - public int getPort() { - return port; - } - - @Override - public boolean isSecure() { - return secure; - } - - @Override - public URI getUri() { - return uri; - } - - @Override - public Map getMetadata() { - return metadata; - } - - @Override - public String getScheme() { - return scheme; - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerAutoConfigurationTests.java deleted file mode 100644 index 2f1336e6..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerAutoConfigurationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.retry.backoff.NoBackOffPolicy; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Ryan Baxter - */ -public class RetryLoadBalancerAutoConfigurationTests extends AbstractLoadBalancerAutoConfigurationTests { - - @Override - protected void assertLoadBalanced(RestTemplate restTemplate) { - List interceptors = restTemplate.getInterceptors(); - then(interceptors).hasSize(1); - ClientHttpRequestInterceptor interceptor = interceptors.get(0); - then(interceptor).isInstanceOf(RetryLoadBalancerInterceptor.class); - } - - @Test - public void testRetryDisabled() { - ConfigurableApplicationContext context = init(OneRestTemplate.class, "spring.aop.proxyTargetClass=true", - "spring.cloud.loadbalancer.retry.enabled=false"); - List interceptors = context.getBean(RestTemplate.class).getInterceptors(); - then(interceptors).hasSize(1); - ClientHttpRequestInterceptor interceptor = interceptors.get(0); - then(interceptor).isInstanceOf(LoadBalancerInterceptor.class); - } - - @Test - public void testDefaultBackOffPolicy() { - ConfigurableApplicationContext context = init(OneRestTemplate.class); - LoadBalancedRetryFactory loadBalancedRetryFactory = context.getBean(LoadBalancedRetryFactory.class); - then(loadBalancedRetryFactory).isInstanceOf(LoadBalancedRetryFactory.class); - then(loadBalancedRetryFactory.createBackOffPolicy("foo")).isInstanceOf(NoBackOffPolicy.class); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptorTests.java deleted file mode 100644 index 0b4da563..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/RetryLoadBalancerInterceptorTests.java +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.ArgumentMatchers; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.quality.Strictness; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpRequest; -import org.springframework.http.HttpStatus; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.mock.http.client.MockClientHttpResponse; -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.retry.backoff.NoBackOffPolicy; -import org.springframework.retry.listener.RetryListenerSupport; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.mockito.Mockito.withSettings; - -/** - * @author Ryan Baxter - * @author Gang Li - * @author Olga Maciaszek-Sharma - */ -@SuppressWarnings({ "unchecked", "rawtypes" }) -@ExtendWith(MockitoExtension.class) -public class RetryLoadBalancerInterceptorTests { - - private LoadBalancerClient client; - - private LoadBalancerRequestFactory lbRequestFactory; - - private final LoadBalancedRetryFactory loadBalancedRetryFactory = new LoadBalancedRetryFactory() { - }; - - private LoadBalancerProperties properties; - - private ReactiveLoadBalancer.Factory lbFactory; - - @BeforeEach - public void setUp() { - client = mock(LoadBalancerClient.class); - lbRequestFactory = mock(LoadBalancerRequestFactory.class); - properties = new LoadBalancerProperties(); - properties.getRetry().setRetryOnAllExceptions(true); - lbFactory = mock(ReactiveLoadBalancer.Factory.class, withSettings().strictness(Strictness.LENIENT)); - when(lbFactory.getProperties(any())).thenReturn(properties); - } - - @AfterEach - public void tearDown() { - client = null; - } - - @Test - public void interceptDisableRetry() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo")); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("foo"), any())).thenReturn(serviceInstance); - when(client.execute(eq("foo"), eq(serviceInstance), any(LoadBalancerRequest.class))) - .thenThrow(new IOException()); - properties.getRetry().setEnabled(false); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - loadBalancedRetryFactory, lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - - when(lbRequestFactory.createRequest(any(), any(), any())).thenReturn(mock(LoadBalancerRequest.class)); - - Assertions.assertThrows(IOException.class, () -> interceptor.intercept(request, body, execution)); - verify(lbRequestFactory).createRequest(request, body, execution); - } - - @Test - public void interceptInvalidHost() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo_underscore")); - properties.getRetry().setEnabled(true); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - loadBalancedRetryFactory, lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - Assertions.assertThrows(IllegalStateException.class, () -> interceptor.intercept(request, body, execution)); - } - - @Test - public void interceptNeverRetry() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo")); - ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("foo"), any())).thenReturn(serviceInstance); - when(client.execute(eq("foo"), eq(serviceInstance), any(LoadBalancerRequest.class))) - .thenReturn(clientHttpResponse); - when(lbRequestFactory.createRequest(any(), any(), any())).thenReturn(mock(LoadBalancerRequest.class)); - properties.getRetry().setEnabled(true); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - loadBalancedRetryFactory, lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - interceptor.intercept(request, body, execution); - verify(lbRequestFactory).createRequest(request, body, execution); - } - - @Test - public void interceptSuccess() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo")); - ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - when(policy.retryableException(any())).thenReturn(true); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("foo"), any())).thenReturn(serviceInstance); - when(client.execute(eq("foo"), eq(serviceInstance), any(LoadBalancerRequest.class))) - .thenReturn(clientHttpResponse); - when(lbRequestFactory.createRequest(any(), any(), any())).thenReturn(mock(LoadBalancerRequest.class)); - properties.getRetry().setEnabled(true); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy), lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - ClientHttpResponse rsp = interceptor.intercept(request, body, execution); - then(rsp).isEqualTo(clientHttpResponse); - verify(lbRequestFactory).createRequest(request, body, execution); - } - - @Test - public void interceptRetryOnStatusCode() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo")); - InputStream notFoundStream = mock(InputStream.class); - ClientHttpResponse clientHttpResponseNotFound = new MockClientHttpResponse(notFoundStream, - HttpStatus.NOT_FOUND); - ClientHttpResponse clientHttpResponseOk = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - when(policy.retryableStatusCode(eq(HttpStatus.NOT_FOUND.value()))).thenReturn(true); - when(policy.canRetryNextServer(any(LoadBalancedRetryContext.class))).thenReturn(true); - when(policy.retryableException(any())).thenReturn(true); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("foo"), any())).thenReturn(serviceInstance); - when(client.execute(eq("foo"), eq(serviceInstance), nullable(LoadBalancerRequest.class))) - .thenReturn(clientHttpResponseNotFound).thenReturn(clientHttpResponseOk); - properties.getRetry().setEnabled(true); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy), lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - ClientHttpResponse rsp = interceptor.intercept(request, body, execution); - verify(client, times(2)).execute(eq("foo"), eq(serviceInstance), nullable(LoadBalancerRequest.class)); - verify(notFoundStream, times(1)).close(); - then(rsp).isEqualTo(clientHttpResponseOk); - verify(lbRequestFactory, times(2)).createRequest(request, body, execution); - } - - @Test - public void interceptRetryFailOnStatusCode() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo")); - - InputStream notFoundStream = new ByteArrayInputStream("foo".getBytes()); - ClientHttpResponse clientHttpResponseNotFound = new MockClientHttpResponse(notFoundStream, - HttpStatus.NOT_FOUND); - - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - when(policy.retryableStatusCode(eq(HttpStatus.NOT_FOUND.value()))).thenReturn(true); - when(policy.canRetryNextServer(any(LoadBalancedRetryContext.class))).thenReturn(false); - when(policy.retryableException(any())).thenReturn(true); - - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("foo"), any())).thenReturn(serviceInstance); - when(client.execute(eq("foo"), eq(serviceInstance), - ArgumentMatchers.>any())) - .thenReturn(clientHttpResponseNotFound); - - properties.getRetry().setEnabled(true); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy), lbFactory); - ClientHttpResponse rsp = interceptor.intercept(request, body, execution); - - verify(client, times(1)).execute(eq("foo"), eq(serviceInstance), - ArgumentMatchers.>any()); - verify(lbRequestFactory, times(1)).createRequest(request, body, execution); - verify(policy, times(2)).canRetryNextServer(any(LoadBalancedRetryContext.class)); - - // call twice in a retry attempt - byte[] content = new byte[1024]; - int length = rsp.getBody().read(content); - then(length).isEqualTo("foo".getBytes().length); - then(new String(content, 0, length)).isEqualTo("foo"); - } - - @Test - public void interceptRetry() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo")); - ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - when(policy.canRetryNextServer(any(LoadBalancedRetryContext.class))).thenReturn(true); - when(policy.retryableException(any())).thenReturn(true); - MyBackOffPolicy backOffPolicy = new MyBackOffPolicy(); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("foo"), any())).thenReturn(serviceInstance); - when(client.execute(eq("foo"), eq(serviceInstance), any(LoadBalancerRequest.class))) - .thenThrow(new IOException()).thenReturn(clientHttpResponse); - when(lbRequestFactory.createRequest(any(), any(), any())).thenReturn(mock(LoadBalancerRequest.class)); - properties.getRetry().setEnabled(true); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy, backOffPolicy), lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - ClientHttpResponse rsp = interceptor.intercept(request, body, execution); - verify(client, times(2)).execute(eq("foo"), eq(serviceInstance), any(LoadBalancerRequest.class)); - then(rsp).isEqualTo(clientHttpResponse); - verify(lbRequestFactory, times(2)).createRequest(request, body, execution); - then(backOffPolicy.getBackoffAttempts()).isEqualTo(1); - } - - @Test - public void interceptFailedRetry() throws Exception { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://foo")); - ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - when(policy.canRetryNextServer(any(LoadBalancedRetryContext.class))).thenReturn(false); - when(policy.retryableException(any())).thenReturn(true); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("foo"), any())).thenReturn(serviceInstance); - when(client.execute(eq("foo"), eq(serviceInstance), any(LoadBalancerRequest.class))) - .thenThrow(new IOException()).thenReturn(clientHttpResponse); - when(lbRequestFactory.createRequest(any(), any(), any())).thenReturn(mock(LoadBalancerRequest.class)); - properties.getRetry().setEnabled(true); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy), lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - Assertions.assertThrows(IOException.class, () -> interceptor.intercept(request, body, execution)); - verify(lbRequestFactory).createRequest(request, body, execution); - } - - private static ServiceInstance defaultServiceInstance() { - return new DefaultServiceInstance("testInstance", "test", "testHost", 80, false); - } - - @Test - public void retryListenerTest() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://listener")); - ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - when(policy.canRetryNextServer(any(LoadBalancedRetryContext.class))).thenReturn(true); - when(policy.retryableException(any())).thenReturn(true); - MyBackOffPolicy backOffPolicy = new MyBackOffPolicy(); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("listener"), any())).thenReturn(serviceInstance); - when(client.execute(eq("listener"), eq(serviceInstance), any(LoadBalancerRequest.class))) - .thenThrow(new IOException()).thenReturn(clientHttpResponse); - properties.getRetry().setEnabled(true); - MyRetryListener retryListener = new MyRetryListener(); - when(lbRequestFactory.createRequest(any(), any(), any())).thenReturn(mock(LoadBalancerRequest.class)); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy, backOffPolicy, new RetryListener[] { retryListener }), - lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - ClientHttpResponse rsp = interceptor.intercept(request, body, execution); - verify(client, times(2)).execute(eq("listener"), eq(serviceInstance), any(LoadBalancerRequest.class)); - then(rsp).isEqualTo(clientHttpResponse); - verify(lbRequestFactory, times(2)).createRequest(request, body, execution); - then(backOffPolicy.getBackoffAttempts()).isEqualTo(1); - then(retryListener.getOnError()).isEqualTo(1); - } - - @Test - public void retryWithDefaultConstructorTest() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://default")); - ClientHttpResponse clientHttpResponse = new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - when(policy.canRetryNextServer(any(LoadBalancedRetryContext.class))).thenReturn(true); - MyBackOffPolicy backOffPolicy = new MyBackOffPolicy(); - ServiceInstance serviceInstance = mock(ServiceInstance.class); - when(client.choose(eq("default"), any())).thenReturn(serviceInstance); - when(client.execute(eq("default"), eq(serviceInstance), any(LoadBalancerRequest.class))) - .thenThrow(new IOException()).thenReturn(clientHttpResponse); - properties.getRetry().setEnabled(true); - when(lbRequestFactory.createRequest(any(), any(), any())).thenReturn(mock(LoadBalancerRequest.class)); - when(policy.retryableException(any())).thenReturn(true); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy, backOffPolicy), lbFactory); - byte[] body = new byte[] {}; - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - ClientHttpResponse rsp = interceptor.intercept(request, body, execution); - verify(client, times(2)).execute(eq("default"), eq(serviceInstance), any(LoadBalancerRequest.class)); - then(rsp).isEqualTo(clientHttpResponse); - verify(lbRequestFactory, times(2)).createRequest(request, body, execution); - then(backOffPolicy.getBackoffAttempts()).isEqualTo(1); - } - - @Test - public void retryListenerTestNoRetry() throws Throwable { - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://noRetry")); - LoadBalancedRetryPolicy policy = mock(LoadBalancedRetryPolicy.class); - MyBackOffPolicy backOffPolicy = new MyBackOffPolicy(); - properties.getRetry().setEnabled(true); - RetryListener myRetryListener = new RetryListenerSupport() { - @Override - public boolean open(RetryContext context, RetryCallback callback) { - return false; - } - }; - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - new MyLoadBalancedRetryFactory(policy, backOffPolicy, new RetryListener[] { myRetryListener }), - lbFactory); - ClientHttpRequestExecution execution = mock(ClientHttpRequestExecution.class); - Assertions.assertThrows(TerminatedRetryException.class, - () -> interceptor.intercept(request, new byte[] {}, execution)); - } - - @Test - public void shouldNotDuplicateLifecycleCalls() throws IOException, URISyntaxException { - Map lifecycleProcessors = new HashMap<>(); - lifecycleProcessors.put("testLifecycle", new TestLoadBalancerLifecycle()); - lifecycleProcessors.put("anotherLifecycle", new AnotherLoadBalancerLifecycle()); - when(lbFactory.getInstances("test", LoadBalancerLifecycle.class)).thenReturn(lifecycleProcessors); - HttpRequest request = mock(HttpRequest.class); - when(request.getURI()).thenReturn(new URI("http://test")); - TestLoadBalancerClient client = new TestLoadBalancerClient(); - RetryLoadBalancerInterceptor interceptor = new RetryLoadBalancerInterceptor(client, lbRequestFactory, - loadBalancedRetryFactory, lbFactory); - - interceptor.intercept(request, new byte[] {}, mock(ClientHttpRequestExecution.class)); - - assertThat(((TestLoadBalancerLifecycle) lifecycleProcessors.get("testLifecycle")).getStartLog()).hasSize(1); - assertThat(((TestLoadBalancerLifecycle) lifecycleProcessors.get("testLifecycle")).getStartRequestLog()) - .hasSize(0); - assertThat(((TestLoadBalancerLifecycle) lifecycleProcessors.get("testLifecycle")).getCompleteLog()).hasSize(0); - assertThat(((TestLoadBalancerLifecycle) lifecycleProcessors.get("anotherLifecycle")).getStartLog()).hasSize(1); - assertThat(((TestLoadBalancerLifecycle) lifecycleProcessors.get("anotherLifecycle")).getStartRequestLog()) - .hasSize(0); - assertThat(((TestLoadBalancerLifecycle) lifecycleProcessors.get("anotherLifecycle")).getCompleteLog()) - .hasSize(0); - assertThat(((TestLoadBalancerLifecycle) client.getLifecycleProcessors().get("testLifecycle")).getStartLog()) - .hasSize(0); - assertThat( - ((TestLoadBalancerLifecycle) client.getLifecycleProcessors().get("testLifecycle")).getStartRequestLog()) - .hasSize(1); - assertThat(((TestLoadBalancerLifecycle) client.getLifecycleProcessors().get("testLifecycle")).getCompleteLog()) - .hasSize(1); - assertThat(((TestLoadBalancerLifecycle) client.getLifecycleProcessors().get("anotherLifecycle")).getStartLog()) - .hasSize(0); - assertThat( - ((TestLoadBalancerLifecycle) client.getLifecycleProcessors().get("testLifecycle")).getStartRequestLog()) - .hasSize(1); - assertThat( - ((TestLoadBalancerLifecycle) client.getLifecycleProcessors().get("anotherLifecycle")).getCompleteLog()) - .hasSize(1); - } - - static class MyLoadBalancedRetryFactory implements LoadBalancedRetryFactory { - - private final LoadBalancedRetryPolicy loadBalancedRetryPolicy; - - private BackOffPolicy backOffPolicy; - - private RetryListener[] retryListeners; - - MyLoadBalancedRetryFactory(LoadBalancedRetryPolicy loadBalancedRetryPolicy) { - this.loadBalancedRetryPolicy = loadBalancedRetryPolicy; - } - - MyLoadBalancedRetryFactory(LoadBalancedRetryPolicy loadBalancedRetryPolicy, BackOffPolicy backOffPolicy) { - this(loadBalancedRetryPolicy); - this.backOffPolicy = backOffPolicy; - } - - MyLoadBalancedRetryFactory(LoadBalancedRetryPolicy loadBalancedRetryPolicy, BackOffPolicy backOffPolicy, - RetryListener[] retryListeners) { - this(loadBalancedRetryPolicy, backOffPolicy); - this.retryListeners = retryListeners; - } - - @Override - public LoadBalancedRetryPolicy createRetryPolicy(String service, - ServiceInstanceChooser serviceInstanceChooser) { - return loadBalancedRetryPolicy; - } - - @Override - public BackOffPolicy createBackOffPolicy(String service) { - return Objects.requireNonNullElseGet(backOffPolicy, NoBackOffPolicy::new); - } - - @Override - public RetryListener[] createRetryListeners(String service) { - return Objects.requireNonNullElseGet(retryListeners, () -> new RetryListener[0]); - } - - } - - static class MyBackOffPolicy implements BackOffPolicy { - - private int backoffAttempts = 0; - - @Override - public BackOffContext start(RetryContext retryContext) { - return new BackOffContext() { - @Override - protected Object clone() throws CloneNotSupportedException { - return super.clone(); - } - }; - } - - @Override - public void backOff(BackOffContext backOffContext) throws BackOffInterruptedException { - backoffAttempts++; - } - - int getBackoffAttempts() { - return backoffAttempts; - } - - } - - static class MyRetryListener extends RetryListenerSupport { - - private int onError = 0; - - @Override - public void onError(RetryContext retryContext, RetryCallback retryCallback, - Throwable throwable) { - onError++; - } - - int getOnError() { - return onError; - } - - } - - protected static class TestLoadBalancerClient implements LoadBalancerClient { - - private final Map lifecycleProcessors = new HashMap<>(); - - TestLoadBalancerClient() { - lifecycleProcessors.put("testLifecycle", new TestLoadBalancerLifecycle()); - lifecycleProcessors.put("anotherLifecycle", new AnotherLoadBalancerLifecycle()); - } - - @Override - public T execute(String serviceId, LoadBalancerRequest request) { - throw new UnsupportedOperationException("Not implemented"); - } - - @Override - public T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) { - Set supportedLoadBalancerProcessors = LoadBalancerLifecycleValidator - .getSupportedLifecycleProcessors(lifecycleProcessors, DefaultRequestContext.class, Object.class, - ServiceInstance.class); - supportedLoadBalancerProcessors.forEach(lifecycle -> lifecycle.onStartRequest(new DefaultRequest<>(), - new DefaultResponse(serviceInstance))); - T response = (T) new MockClientHttpResponse(new byte[] {}, HttpStatus.OK); - supportedLoadBalancerProcessors - .forEach(lifecycle -> lifecycle.onComplete(new CompletionContext(CompletionContext.Status.SUCCESS, - new DefaultRequest<>(), new DefaultResponse(defaultServiceInstance())))); - return response; - } - - @Override - public URI reconstructURI(ServiceInstance instance, URI original) { - throw new UnsupportedOperationException("Please, implement me."); - } - - @Override - public ServiceInstance choose(String serviceId) { - return defaultServiceInstance(); - } - - @Override - public ServiceInstance choose(String serviceId, Request request) { - return defaultServiceInstance(); - } - - Map getLifecycleProcessors() { - return lifecycleProcessors; - } - - } - - protected static class TestLoadBalancerLifecycle implements LoadBalancerLifecycle { - - final ConcurrentHashMap> startLog = new ConcurrentHashMap<>(); - - final ConcurrentHashMap> startRequestLog = new ConcurrentHashMap<>(); - - final ConcurrentHashMap> completeLog = new ConcurrentHashMap<>(); - - @Override - public boolean supports(Class requestContextClass, Class responseClass, Class serverTypeClass) { - return DefaultRequestContext.class.isAssignableFrom(requestContextClass) - && Object.class.isAssignableFrom(responseClass) - && ServiceInstance.class.isAssignableFrom(serverTypeClass); - } - - @Override - public void onStart(Request request) { - startLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onStartRequest(Request request, Response lbResponse) { - startRequestLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onComplete(CompletionContext completionContext) { - completeLog.put(getName() + UUID.randomUUID(), completionContext); - } - - ConcurrentHashMap> getStartLog() { - return startLog; - } - - ConcurrentHashMap> getCompleteLog() { - return completeLog; - } - - ConcurrentHashMap> getStartRequestLog() { - return startRequestLog; - } - - protected String getName() { - return getClass().getSimpleName(); - } - - } - - protected static class AnotherLoadBalancerLifecycle extends TestLoadBalancerLifecycle { - - @Override - protected String getName() { - return getClass().getSimpleName(); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/DiscoveryClientBasedReactiveLoadBalancer.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/DiscoveryClientBasedReactiveLoadBalancer.java deleted file mode 100644 index b9d9fb94..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/DiscoveryClientBasedReactiveLoadBalancer.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.util.List; -import java.util.Random; - -import org.reactivestreams.Publisher; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.RetryableRequestContext; - -/** - * A {@link ReactiveLoadBalancer} implementation used for tests. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -class DiscoveryClientBasedReactiveLoadBalancer implements ReactiveLoadBalancer { - - private final Random random = new Random(); - - private final String serviceId; - - private final DiscoveryClient discoveryClient; - - DiscoveryClientBasedReactiveLoadBalancer(String serviceId, DiscoveryClient discoveryClient) { - this.serviceId = serviceId; - this.discoveryClient = discoveryClient; - } - - @Override - public Publisher> choose() { - List instances = discoveryClient.getInstances(serviceId); - if (instances.size() == 0) { - return Mono.just(new EmptyResponse()); - } - int instanceIdx = this.random.nextInt(instances.size()); - return Mono.just(new DefaultResponse(instances.get(instanceIdx))); - } - - @Override - public Publisher> choose(Request request) { - - List instances = discoveryClient.getInstances(serviceId); - if (request.getContext() instanceof RetryableRequestContext context) { - if (context.getPreviousServiceInstance() != null) { - List instancesCopy = discoveryClient.getInstances(serviceId); - instancesCopy.remove(context.getPreviousServiceInstance()); - if (!instancesCopy.isEmpty()) { - instances = instancesCopy; - } - } - } - if (instances.size() == 0) { - return Mono.just(new EmptyResponse()); - } - int instanceIdx = this.random.nextInt(instances.size()); - return Mono.just(new DefaultResponse(instances.get(instanceIdx))); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformerTest.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformerTest.java deleted file mode 100644 index fa13613e..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerClientRequestTransformerTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.net.URI; -import java.util.Arrays; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.ExchangeFunction; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link LoadBalancerClientRequestTransformer}. - * - * @author Toshiaki Maki - */ -class LoadBalancerClientRequestTransformerTest { - - private final LoadBalancerProperties properties = new LoadBalancerProperties(); - - private final LoadBalancerRetryPolicy policy = new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy( - properties); - - private final ReactiveLoadBalancer.Factory factory = mock(ReactiveLoadBalancer.Factory.class); - - private final ClientRequest clientRequest = mock(ClientRequest.class); - - private final ClientResponse clientResponse = mock(ClientResponse.class); - - private final ExchangeFunction next = mock(ExchangeFunction.class); - - @BeforeEach - void setUp() { - when(factory.getInstance("testServiceId")).thenReturn(new TestReactiveLoadBalancer()); - when(factory.getProperties(any())).thenReturn(properties); - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(clientRequest.url()).thenReturn(URI.create("http://testServiceId")); - when(clientRequest.headers()).thenReturn(new HttpHeaders()); - when(clientRequest.cookies()).thenReturn(new LinkedMultiValueMap<>()); - when(next.exchange(any())).thenReturn(Mono.just(clientResponse)); - when(clientResponse.statusCode()).thenReturn(HttpStatus.OK); - } - - @Test - void transformReactorLoadBalancerExchangeFilterFunction() { - ArgumentCaptor captor = ArgumentCaptor.forClass(ClientRequest.class); - ReactorLoadBalancerExchangeFilterFunction filterFunction = new ReactorLoadBalancerExchangeFilterFunction( - factory, Arrays.asList(new Transformer1(), new Transformer2())); - filterFunction.filter(clientRequest, next).subscribe(); - verify(next).exchange(captor.capture()); - HttpHeaders headers = captor.getValue().headers(); - assertThat(headers.getFirst("X-ServiceId")).isEqualTo("testServiceId"); - assertThat(headers.getFirst("X-InstanceId")).isEqualTo("testServiceId"); - } - - @Test - void transformRetryableLoadBalancerExchangeFilterFunction() { - ArgumentCaptor captor = ArgumentCaptor.forClass(ClientRequest.class); - RetryableLoadBalancerExchangeFilterFunction filterFunction = new RetryableLoadBalancerExchangeFilterFunction( - s -> policy, factory, Arrays.asList(new Transformer1(), new Transformer2())); - filterFunction.filter(clientRequest, next).subscribe(); - verify(next).exchange(captor.capture()); - HttpHeaders headers = captor.getValue().headers(); - assertThat(headers.getFirst("X-ServiceId")).isEqualTo("testServiceId"); - assertThat(headers.getFirst("X-InstanceId")).isEqualTo("testServiceId"); - } - - static class Transformer1 implements LoadBalancerClientRequestTransformer { - - @Override - public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { - return ClientRequest.from(request).header("X-ServiceId", instance.getServiceId()).build(); - } - - } - - static class Transformer2 implements LoadBalancerClientRequestTransformer { - - @Override - public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { - return ClientRequest.from(request).header("X-InstanceId", instance.getInstanceId()).build(); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerTestUtils.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerTestUtils.java deleted file mode 100644 index 31311fb7..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/LoadBalancerTestUtils.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.util.List; - -import org.apache.commons.lang3.ArrayUtils; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * Utility class for testing reactive load-balancer clients. - * - * @author Olga Maciaszek-Sharma - */ -final class LoadBalancerTestUtils { - - private LoadBalancerTestUtils() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - static ConfigurableApplicationContext init(Class... configClasses) { - return new SpringApplicationBuilder().web(WebApplicationType.NONE) - .sources(ArrayUtils.add(configClasses, WebClientAutoConfiguration.class)).run(); - } - - @SuppressWarnings("unchecked") - static List getFilters(WebClient.Builder builder) { - return (List) ReflectionTestUtils.getField(builder, "filters"); - } - - static void assertLoadBalanced(WebClient.Builder webClientBuilder, Class exchangeFilterFunctionClass) { - List filters = getFilters(webClientBuilder); - then(filters).hasSize(1); - then(filters.get(0)).isInstanceOf(DeferringLoadBalancerExchangeFilterFunction.class); - DeferringLoadBalancerExchangeFilterFunction interceptor = (DeferringLoadBalancerExchangeFilterFunction) filters - .get(0); - interceptor.tryResolveDelegate(); - then(interceptor.getDelegate()).isInstanceOf(exchangeFilterFunctionClass); - } - - static void assertLoadBalanced(WebClient webClient, Class exchangeFilterFunctionClass) { - assertLoadBalanced((WebClient.Builder) ReflectionTestUtils.getField(webClient, "builder"), - exchangeFilterFunctionClass); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfigurationTests.java deleted file mode 100644 index bf932523..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerClientAutoConfigurationTests.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.time.Duration; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerTestUtils.assertLoadBalanced; -import static org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerTestUtils.getFilters; - -/** - * Tests for {@link ReactorLoadBalancerClientAutoConfiguration}. - * - * @author Olga Maciaszek-Sharma - */ -public class ReactorLoadBalancerClientAutoConfigurationTests { - - @Test - void loadBalancerFilterAddedToWebClientBuilder() { - ConfigurableApplicationContext context = init(OneWebClientBuilder.class); - final Map webClientBuilders = context.getBeansOfType(WebClient.Builder.class); - - then(webClientBuilders).isNotNull().hasSize(1); - WebClient.Builder webClientBuilder = webClientBuilders.values().iterator().next(); - then(webClientBuilder).isNotNull(); - - assertLoadBalanced(webClientBuilder, ReactorLoadBalancerExchangeFilterFunction.class); - - final Map testServiceMap = context - .getBeansOfType(OneWebClientBuilder.TestService.class); - then(testServiceMap).isNotNull().hasSize(1); - OneWebClientBuilder.TestService testService = testServiceMap.values().stream().findFirst().get(); - assertLoadBalanced(testService.webClient, ReactorLoadBalancerExchangeFilterFunction.class); - } - - @Test - void loadBalancerFilterAddedToWebClientBuilderWithRetryEnabled() { - System.setProperty("spring.cloud.loadbalancer.retry.enabled", "true"); - ConfigurableApplicationContext context = init(OneWebClientBuilder.class); - final Map webClientBuilders = context.getBeansOfType(WebClient.Builder.class); - - then(webClientBuilders).isNotNull().hasSize(1); - WebClient.Builder webClientBuilder = webClientBuilders.values().iterator().next(); - then(webClientBuilder).isNotNull(); - - assertLoadBalanced(webClientBuilder, RetryableLoadBalancerExchangeFilterFunction.class); - - final Map testServiceMap = context - .getBeansOfType(OneWebClientBuilder.TestService.class); - then(testServiceMap).isNotNull().hasSize(1); - OneWebClientBuilder.TestService testService = testServiceMap.values().stream().findFirst().get(); - assertLoadBalanced(testService.webClient, RetryableLoadBalancerExchangeFilterFunction.class); - - System.clearProperty("spring.cloud.loadbalancer.retry.enabled"); - } - - @Test - void loadBalancerFilterAddedOnlyToLoadBalancedWebClientBuilder() { - ConfigurableApplicationContext context = init(TwoWebClientBuilders.class); - final Map webClientBuilders = context.getBeansOfType(WebClient.Builder.class); - - then(webClientBuilders).hasSize(2); - - TwoWebClientBuilders.Two two = context.getBean(TwoWebClientBuilders.Two.class); - - then(two.loadBalanced).isNotNull(); - assertLoadBalanced(two.loadBalanced, ReactorLoadBalancerExchangeFilterFunction.class); - - then(two.nonLoadBalanced).isNotNull(); - then(getFilters(two.nonLoadBalanced)).isNullOrEmpty(); - } - - @Test - void loadBalancerFilterAddedOnlyToLoadBalancedWebClientBuilderWithRetryEnabled() { - System.setProperty("spring.cloud.loadbalancer.retry.enabled", "true"); - ConfigurableApplicationContext context = init(TwoWebClientBuilders.class); - final Map webClientBuilders = context.getBeansOfType(WebClient.Builder.class); - - then(webClientBuilders).hasSize(2); - - TwoWebClientBuilders.Two two = context.getBean(TwoWebClientBuilders.Two.class); - - then(two.loadBalanced).isNotNull(); - assertLoadBalanced(two.loadBalanced, RetryableLoadBalancerExchangeFilterFunction.class); - - then(two.nonLoadBalanced).isNotNull(); - then(getFilters(two.nonLoadBalanced)).isNullOrEmpty(); - System.clearProperty("spring.cloud.loadbalancer.retry.enabled"); - } - - @Test - void noCustomWebClientBuilders() { - ConfigurableApplicationContext context = init(NoWebClientBuilder.class); - final Map webClientBuilders = context.getBeansOfType(WebClient.Builder.class); - - then(webClientBuilders).hasSize(1); - - WebClient.Builder builder = context.getBean(WebClient.Builder.class); - - then(builder).isNotNull(); - then(getFilters(builder)).isNullOrEmpty(); - } - - @Test - void defaultPropertiesWorks() { - ConfigurableApplicationContext context = new SpringApplicationBuilder().web(WebApplicationType.NONE) - .sources(OneWebClientBuilder.class, DefaulConfig.class) - .properties("spring.cloud.loadbalancer.health-check.initial-delay=1s", - "spring.cloud.loadbalancer.clients.myclient.health-check.interval=30s") - .run(); - LoadBalancerClientsProperties properties = context.getBean(LoadBalancerClientsProperties.class); - - then(properties.getClients()).containsKey("myclient"); - LoadBalancerProperties clientProperties = properties.getClients().get("myclient"); - // default value - then(clientProperties.getHealthCheck().getInitialDelay()).isEqualTo(Duration.ofSeconds(1)); - // client specific value - then(clientProperties.getHealthCheck().getInterval()).isEqualTo(Duration.ofSeconds(30)); - } - - private ConfigurableApplicationContext init(Class config) { - return LoadBalancerTestUtils.init(config, ReactorLoadBalancerClientAutoConfiguration.class, - LoadBalancerBeanPostProcessorAutoConfiguration.class); - } - - @Configuration - @EnableAutoConfiguration - protected static class DefaulConfig { - - } - - @Configuration - protected static class NoWebClientBuilder { - - @Bean - ReactiveLoadBalancer.Factory reactiveLoadBalancerFactory(LoadBalancerProperties properties) { - return new ReactiveLoadBalancer.Factory<>() { - @Override - public ReactiveLoadBalancer getInstance(String serviceId) { - return new TestReactiveLoadBalancer(); - } - - @Override - public Map getInstances(String name, Class type) { - throw new UnsupportedOperationException("Not implemented"); - } - - @Override - public X getInstance(String name, Class clazz, Class... generics) { - throw new UnsupportedOperationException("Not implemented."); - } - - @Override - public LoadBalancerProperties getProperties(String serviceId) { - return properties; - } - }; - } - - @Bean - LoadBalancedRetryFactory loadBalancedRetryFactory() { - return new LoadBalancedRetryFactory() { - }; - } - - } - - @Configuration - protected static class OneWebClientBuilder extends NoWebClientBuilder { - - @Bean - @LoadBalanced - WebClient.Builder loadBalancedWebClientBuilder() { - return WebClient.builder(); - } - - @Bean - TestService testService() { - return new TestService(loadBalancedWebClientBuilder()); - } - - private static final class TestService { - - public final WebClient webClient; - - private TestService(WebClient.Builder builder) { - this.webClient = builder.build(); - } - - } - - } - - @Configuration - protected static class TwoWebClientBuilders extends OneWebClientBuilder { - - @Primary - @Bean - WebClient.Builder webClientBuilder() { - return WebClient.builder(); - } - - @Configuration - protected static class Two { - - @Autowired - WebClient.Builder nonLoadBalanced; - - @Autowired - @LoadBalanced - WebClient.Builder loadBalanced; - - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunctionTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunctionTests.java deleted file mode 100644 index 45d4b655..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/ReactorLoadBalancerExchangeFilterFunctionTests.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.net.URI; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -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.server.LocalServerPort; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * Tests for {@link ReactorLoadBalancerExchangeFilterFunction}. - * - * @author Olga Maciaszek-Sharma - * @author Charu Covindane - */ -@SuppressWarnings("ConstantConditions") -@SpringBootTest(webEnvironment = RANDOM_PORT) -class ReactorLoadBalancerExchangeFilterFunctionTests { - - @Autowired - private ReactorLoadBalancerExchangeFilterFunction loadBalancerFunction; - - @Autowired - private SimpleDiscoveryProperties properties; - - @Autowired - private LoadBalancerProperties loadBalancerProperties; - - @Autowired - private ReactiveLoadBalancer.Factory factory; - - @LocalServerPort - private int port; - - @BeforeEach - void setUp() { - DefaultServiceInstance instance = new DefaultServiceInstance(); - instance.setServiceId("testservice"); - instance.setUri(URI.create("http://localhost:" + this.port)); - DefaultServiceInstance instanceWithNoLifecycleProcessors = new DefaultServiceInstance(); - instanceWithNoLifecycleProcessors.setServiceId("serviceWithNoLifecycleProcessors"); - instanceWithNoLifecycleProcessors.setUri(URI.create("http://localhost:" + this.port)); - properties.getInstances().put("testservice", Collections.singletonList(instance)); - properties.getInstances().put("serviceWithNoLifecycleProcessors", - Collections.singletonList(instanceWithNoLifecycleProcessors)); - } - - @Test - void correctResponseReturnedForExistingHostAndInstancePresent() { - ClientResponse clientResponse = WebClient.builder().baseUrl("http://testservice").filter(loadBalancerFunction) - .build().get().uri("/hello").exchange().block(); - then(clientResponse.statusCode()).isEqualTo(HttpStatus.OK); - then(clientResponse.bodyToMono(String.class).block()).isEqualTo("Hello World"); - } - - @Test - void serviceUnavailableReturnedWhenNoInstancePresent() { - ClientResponse clientResponse = WebClient.builder().baseUrl("http://xxx").filter(this.loadBalancerFunction) - .build().get().exchange().block(); - then(clientResponse.statusCode()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); - } - - @Test - @Disabled // FIXME 3.0.0 - void badRequestReturnedForIncorrectHost() { - ClientResponse clientResponse = WebClient.builder().baseUrl("http:///xxx").filter(this.loadBalancerFunction) - .build().get().exchange().block(); - then(clientResponse.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - } - - @Test - void exceptionNotThrownWhenFactoryReturnsNullLifecycleProcessorsMap() { - assertThatCode(() -> WebClient.builder().baseUrl("http://serviceWithNoLifecycleProcessors") - .filter(loadBalancerFunction).build().get().uri("/hello").exchange().block()) - .doesNotThrowAnyException(); - } - - @Test - void loadBalancerLifecycleCallbacksExecuted() { - final String callbackTestHint = "callbackTestHint"; - loadBalancerProperties.getHint().put("testservice", "callbackTestHint"); - ClientResponse clientResponse = WebClient.builder().baseUrl("http://testservice").filter(loadBalancerFunction) - .build().get().uri("/callback").exchange().block(); - - Collection> lifecycleLogRequests = ((TestLoadBalancerLifecycle) factory - .getInstances("testservice", LoadBalancerLifecycle.class).get("loadBalancerLifecycle")).getStartLog() - .values(); - Collection> lifecycleStartedLogRequests = ((TestLoadBalancerLifecycle) factory - .getInstances("testservice", LoadBalancerLifecycle.class).get("loadBalancerLifecycle")) - .getStartRequestLog().values(); - Collection> anotherLifecycleLogRequests = ((AnotherLoadBalancerLifecycle) factory - .getInstances("testservice", LoadBalancerLifecycle.class).get("anotherLoadBalancerLifecycle")) - .getCompleteLog().values(); - then(clientResponse.statusCode()).isEqualTo(HttpStatus.OK); - assertThat(lifecycleLogRequests).extracting(request -> ((DefaultRequestContext) request.getContext()).getHint()) - .contains(callbackTestHint); - assertThat(lifecycleStartedLogRequests) - .extracting(request -> ((DefaultRequestContext) request.getContext()).getHint()) - .contains(callbackTestHint); - assertThat(anotherLifecycleLogRequests) - .extracting(completionContext -> ((ResponseData) completionContext.getClientResponse()).getRequestData() - .getUrl().toString()) - .contains("http://testservice/callback"); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @EnableDiscoveryClient - @EnableAutoConfiguration - @SpringBootConfiguration(proxyBeanMethods = false) - @RestController - static class Config { - - @GetMapping("/hello") - public String hello() { - return "Hello World"; - } - - @GetMapping("/callback") - String callbackTestResult() { - return "callbackTestResult"; - } - - @Bean - ReactiveLoadBalancer.Factory reactiveLoadBalancerFactory(DiscoveryClient discoveryClient, - LoadBalancerProperties properties) { - return new ReactiveLoadBalancer.Factory<>() { - - private final TestLoadBalancerLifecycle testLoadBalancerLifecycle = new TestLoadBalancerLifecycle(); - - private final TestLoadBalancerLifecycle anotherLoadBalancerLifecycle = new AnotherLoadBalancerLifecycle(); - - @Override - public ReactiveLoadBalancer getInstance(String serviceId) { - return new DiscoveryClientBasedReactiveLoadBalancer(serviceId, discoveryClient); - } - - @Override - public Map getInstances(String name, Class type) { - if (name.equals("serviceWithNoLifecycleProcessors")) { - return null; - } - Map lifecycleProcessors = new HashMap<>(); - lifecycleProcessors.put("loadBalancerLifecycle", testLoadBalancerLifecycle); - lifecycleProcessors.put("anotherLoadBalancerLifecycle", anotherLoadBalancerLifecycle); - return lifecycleProcessors; - } - - @Override - public X getInstance(String name, Class clazz, Class... generics) { - return null; - } - - @Override - public LoadBalancerProperties getProperties(String serviceId) { - return properties; - } - }; - } - - } - - protected static class TestLoadBalancerLifecycle implements LoadBalancerLifecycle { - - final Map> startLog = new ConcurrentHashMap<>(); - - final Map> startRequestLog = new ConcurrentHashMap<>(); - - final Map> completeLog = new ConcurrentHashMap<>(); - - @Override - public void onStart(Request request) { - startLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onStartRequest(Request request, Response lbResponse) { - startRequestLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onComplete(CompletionContext completionContext) { - completeLog.put(getName() + UUID.randomUUID(), completionContext); - } - - Map> getStartLog() { - return startLog; - } - - Map> getCompleteLog() { - return completeLog; - } - - Map> getStartRequestLog() { - return startRequestLog; - } - - protected String getName() { - return this.getClass().getSimpleName(); - } - - } - - protected static class AnotherLoadBalancerLifecycle extends TestLoadBalancerLifecycle { - - @Override - protected String getName() { - return this.getClass().getSimpleName(); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java deleted file mode 100644 index 5b42a8f6..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionIntegrationTests.java +++ /dev/null @@ -1,328 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.net.URI; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -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.server.LocalServerPort; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.context.annotation.Bean; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * Integration tests for {@link RetryableLoadBalancerExchangeFilterFunction}. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -@SpringBootTest(webEnvironment = RANDOM_PORT) -class RetryableLoadBalancerExchangeFilterFunctionIntegrationTests { - - @Autowired - private RetryableLoadBalancerExchangeFilterFunction loadBalancerFunction; - - @Autowired - private SimpleDiscoveryProperties properties; - - @Autowired - private LoadBalancerProperties loadBalancerProperties; - - @Autowired - private ReactiveLoadBalancer.Factory factory; - - @LocalServerPort - private int port; - - @BeforeEach - void setUp() { - DefaultServiceInstance instance = new DefaultServiceInstance(); - instance.setServiceId("testservice"); - instance.setUri(URI.create("http://localhost:" + port)); - DefaultServiceInstance instanceWithNoLifecycleProcessors = new DefaultServiceInstance(); - instanceWithNoLifecycleProcessors.setServiceId("serviceWithNoLifecycleProcessors"); - instanceWithNoLifecycleProcessors.setUri(URI.create("http://localhost:" + port)); - properties.getInstances().put("testservice", Collections.singletonList(instance)); - properties.getInstances().put("serviceWithNoLifecycleProcessors", - Collections.singletonList(instanceWithNoLifecycleProcessors)); - } - - @Test - void loadBalancerLifecycleCallbacksExecuted() { - final String callbackTestHint = "callbackTestHint"; - loadBalancerProperties.getHint().put("testservice", "callbackTestHint"); - - ClientResponse clientResponse = WebClient.builder().baseUrl("http://testservice") - .filter(this.loadBalancerFunction).build().get().uri("/callback").exchange().block(); - - Collection> lifecycleLogRequests = ((TestLoadBalancerLifecycle) factory - .getInstances("testservice", LoadBalancerLifecycle.class).get("loadBalancerLifecycle")).getStartLog() - .values(); - Collection> lifecycleLogStartRequests = ((TestLoadBalancerLifecycle) factory - .getInstances("testservice", LoadBalancerLifecycle.class).get("loadBalancerLifecycle")) - .getStartRequestLog().values(); - Collection> anotherLifecycleLogRequests = ((AnotherLoadBalancerLifecycle) factory - .getInstances("testservice", LoadBalancerLifecycle.class).get("anotherLoadBalancerLifecycle")) - .getCompleteLog().values(); - then(clientResponse.statusCode()).isEqualTo(HttpStatus.OK); - assertThat(lifecycleLogRequests).extracting(request -> ((DefaultRequestContext) request.getContext()).getHint()) - .contains(callbackTestHint); - assertThat(lifecycleLogStartRequests) - .extracting(request -> ((DefaultRequestContext) request.getContext()).getHint()) - .contains(callbackTestHint); - assertThat(anotherLifecycleLogRequests) - .extracting(completionContext -> ((ResponseData) completionContext.getClientResponse()).getRequestData() - .getHttpMethod()) - .contains(HttpMethod.GET); - } - - @Test - void correctResponseReturnedForExistingHostAndInstancePresent() { - ClientResponse clientResponse = WebClient.builder().baseUrl("http://testservice") - .filter(this.loadBalancerFunction).build().get().uri("/hello").exchange().block(); - - then(clientResponse.statusCode()).isEqualTo(HttpStatus.OK); - then(clientResponse.bodyToMono(String.class).block()).isEqualTo("Hello World"); - } - - @Test - void correctResponseReturnedAfterRetryingOnSameServiceInstance() { - loadBalancerProperties.getRetry().setMaxRetriesOnSameServiceInstance(1); - loadBalancerProperties.getRetry().getRetryableStatusCodes().add(500); - - ClientResponse clientResponse = WebClient.builder().baseUrl("http://testservice") - .filter(this.loadBalancerFunction).build().get().uri("/exception").exchange().block(); - - then(clientResponse.statusCode()).isEqualTo(HttpStatus.OK); - then(clientResponse.bodyToMono(String.class).block()).isEqualTo("Hello World!"); - } - - @Test - void correctResponseReturnedAfterRetryingOnNextServiceInstanceWithBackoff() { - loadBalancerProperties.getRetry().getBackoff().setEnabled(true); - loadBalancerProperties.getRetry().setMaxRetriesOnSameServiceInstance(1); - DefaultServiceInstance goodRetryTestInstance = new DefaultServiceInstance(); - goodRetryTestInstance.setServiceId("retrytest"); - goodRetryTestInstance.setUri(URI.create("http://localhost:" + port)); - DefaultServiceInstance badRetryTestInstance = new DefaultServiceInstance(); - badRetryTestInstance.setServiceId("retrytest"); - badRetryTestInstance.setUri(URI.create("http://localhost:" + 8080)); - properties.getInstances().put("retrytest", Arrays.asList(badRetryTestInstance, goodRetryTestInstance)); - loadBalancerProperties.getRetry().getRetryableStatusCodes().add(500); - - ClientResponse clientResponse = WebClient.builder().baseUrl("http://retrytest") - .filter(this.loadBalancerFunction).build().get().uri("/hello").exchange().block(); - - then(clientResponse.statusCode()).isEqualTo(HttpStatus.OK); - then(clientResponse.bodyToMono(String.class).block()).isEqualTo("Hello World"); - - ClientResponse secondClientResponse = WebClient.builder().baseUrl("http://retrytest") - .filter(this.loadBalancerFunction).build().get().uri("/hello").exchange().block(); - - then(secondClientResponse.statusCode()).isEqualTo(HttpStatus.OK); - then(secondClientResponse.bodyToMono(String.class).block()).isEqualTo("Hello World"); - } - - @Test - void serviceUnavailableReturnedWhenNoInstancePresent() { - ClientResponse clientResponse = WebClient.builder().baseUrl("http://xxx").filter(this.loadBalancerFunction) - .build().get().exchange().block(); - - then(clientResponse.statusCode()).isEqualTo(HttpStatus.SERVICE_UNAVAILABLE); - } - - @Test - @Disabled - // FIXME 3.0.0 - void badRequestReturnedForIncorrectHost() { - ClientResponse clientResponse = WebClient.builder().baseUrl("http:///xxx").filter(this.loadBalancerFunction) - .build().get().exchange().block(); - - then(clientResponse.statusCode()).isEqualTo(HttpStatus.BAD_REQUEST); - } - - @Test - void exceptionNotThrownWhenFactoryReturnsNullLifecycleProcessorsMap() { - assertThatCode(() -> WebClient.builder().baseUrl("http://serviceWithNoLifecycleProcessors") - .filter(this.loadBalancerFunction).build().get().uri("/hello").exchange().block()) - .doesNotThrowAnyException(); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @EnableDiscoveryClient - @EnableAutoConfiguration - @SpringBootConfiguration(proxyBeanMethods = false) - @RestController - static class Config { - - AtomicInteger exceptionCallsCount = new AtomicInteger(); - - @GetMapping("/hello") - public String hello() { - return "Hello World"; - } - - @GetMapping("/callback") - String callbackTestResult() { - return "callbackTestResult"; - } - - @GetMapping("/exception") - String exception() { - int callCount = exceptionCallsCount.incrementAndGet(); - if (callCount % 2 != 0) { - throw new IllegalStateException("Test!"); - } - return "Hello World!"; - } - - @Bean - ReactiveLoadBalancer.Factory reactiveLoadBalancerFactory(DiscoveryClient discoveryClient, - LoadBalancerProperties properties) { - return new ReactiveLoadBalancer.Factory<>() { - - private final TestLoadBalancerLifecycle testLoadBalancerLifecycle = new TestLoadBalancerLifecycle(); - - private final TestLoadBalancerLifecycle anotherLoadBalancerLifecycle = new AnotherLoadBalancerLifecycle(); - - @Override - public ReactiveLoadBalancer getInstance(String serviceId) { - return new org.springframework.cloud.client.loadbalancer.reactive.DiscoveryClientBasedReactiveLoadBalancer( - serviceId, discoveryClient); - } - - @Override - public Map getInstances(String name, Class type) { - if (name.equals("serviceWithNoLifecycleProcessors")) { - return null; - } - Map lifecycleProcessors = new HashMap<>(); - lifecycleProcessors.put("loadBalancerLifecycle", testLoadBalancerLifecycle); - lifecycleProcessors.put("anotherLoadBalancerLifecycle", anotherLoadBalancerLifecycle); - return lifecycleProcessors; - } - - @Override - public X getInstance(String name, Class clazz, Class... generics) { - return null; - } - - @Override - public LoadBalancerProperties getProperties(String serviceId) { - return properties; - } - }; - } - - @Bean - RetryableLoadBalancerExchangeFilterFunction exchangeFilterFunction( - ReactiveLoadBalancer.Factory factory) { - return new RetryableLoadBalancerExchangeFilterFunction( - new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy.Factory(factory), factory, - Collections.emptyList()); - } - - } - - protected static class TestLoadBalancerLifecycle implements LoadBalancerLifecycle { - - Map> startLog = new ConcurrentHashMap<>(); - - Map> startRequestLog = new ConcurrentHashMap<>(); - - Map> completeLog = new ConcurrentHashMap<>(); - - @Override - public void onStart(Request request) { - startLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onStartRequest(Request request, Response lbResponse) { - startRequestLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onComplete(CompletionContext completionContext) { - completeLog.clear(); - completeLog.put(getName() + UUID.randomUUID(), completionContext); - } - - Map> getStartLog() { - return startLog; - } - - Map> getCompleteLog() { - return completeLog; - } - - Map> getStartRequestLog() { - return startRequestLog; - } - - protected String getName() { - return this.getClass().getSimpleName(); - } - - } - - protected static class AnotherLoadBalancerLifecycle extends TestLoadBalancerLifecycle { - - @Override - protected String getName() { - return this.getClass().getSimpleName(); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java deleted file mode 100644 index 29bef5bc..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/RetryableLoadBalancerExchangeFilterFunctionTests.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.io.IOException; -import java.net.URI; -import java.util.Collections; -import java.util.HashSet; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.web.reactive.function.client.ClientRequest; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.reactive.function.client.ExchangeFunction; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link RetryableLoadBalancerExchangeFilterFunction}. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -@SuppressWarnings("unchecked") -class RetryableLoadBalancerExchangeFilterFunctionTests { - - private final LoadBalancerProperties properties = new LoadBalancerProperties(); - - private final ReactiveLoadBalancer.Factory factory = mock(ReactiveLoadBalancer.Factory.class); - - private final RetryableLoadBalancerExchangeFilterFunction filterFunction = new RetryableLoadBalancerExchangeFilterFunction( - new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy.Factory(factory), factory, - Collections.emptyList()); - - private final ClientRequest clientRequest = mock(ClientRequest.class); - - private final ExchangeFunction next = mock(ExchangeFunction.class); - - private final ClientResponse clientResponse = mock(ClientResponse.class); - - private final InOrder inOrder = inOrder(next, factory); - - @BeforeEach - void setUp() { - properties.getRetry().setMaxRetriesOnSameServiceInstance(1); - properties.getRetry().getRetryableStatusCodes().add(404); - when(clientRequest.url()).thenReturn(URI.create("http://test")); - when(factory.getInstance("test")).thenReturn(new TestReactiveLoadBalancer()); - when(factory.getProperties(any())).thenReturn(properties); - when(clientRequest.headers()).thenReturn(new HttpHeaders()); - when(clientRequest.cookies()).thenReturn(new HttpHeaders()); - - } - - @Test - void shouldRetryOnSameAndNextServiceInstanceOnException() { - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(next.exchange(any())).thenThrow(new IllegalStateException(new IOException())); - - filterFunction.filter(clientRequest, next).subscribe(); - - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - } - - @Test - void shouldRetryOnSameAndNextServiceInstanceOnRetryableStatusCode() { - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(clientResponse.statusCode()).thenReturn(HttpStatus.NOT_FOUND); - when(next.exchange(any())).thenReturn(Mono.just(clientResponse)); - - filterFunction.filter(clientRequest, next).subscribe(); - - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - } - - @Test - void shouldNotRetryWhenNoRetryableExceptionOrStatusCode() { - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(clientResponse.statusCode()).thenReturn(HttpStatus.OK); - when(next.exchange(any())).thenReturn(Mono.just(clientResponse)); - - filterFunction.filter(clientRequest, next).subscribe(); - - verify(next, times(1)).exchange(any()); - verify(factory, times(1)).getInstance(any()); - } - - @Test - void shouldNotRetryOnMethodOtherThanGet() { - when(clientRequest.method()).thenReturn(HttpMethod.POST); - when(clientResponse.statusCode()).thenReturn(HttpStatus.NOT_FOUND); - when(next.exchange(any())).thenReturn(Mono.just(clientResponse)); - - filterFunction.filter(clientRequest, next).subscribe(); - - verify(next, times(1)).exchange(any()); - verify(factory, times(1)).getInstance(any()); - } - - @Test - void shouldRetryOnMethodOtherThanGetWhenEnabled() { - LoadBalancerProperties properties = new LoadBalancerProperties(); - properties.getRetry().setRetryOnAllOperations(true); - properties.getRetry().setMaxRetriesOnSameServiceInstance(1); - properties.getRetry().getRetryableStatusCodes().add(404); - LoadBalancerRetryPolicy policy = new RetryableExchangeFilterFunctionLoadBalancerRetryPolicy(properties); - RetryableLoadBalancerExchangeFilterFunction filterFunction = new RetryableLoadBalancerExchangeFilterFunction( - s -> policy, factory, Collections.emptyList()); - when(clientRequest.method()).thenReturn(HttpMethod.POST); - when(clientResponse.statusCode()).thenReturn(HttpStatus.NOT_FOUND); - when(next.exchange(any())).thenReturn(Mono.just(clientResponse)); - - filterFunction.filter(clientRequest, next).subscribe(); - - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - } - - @Test - void shouldNotRetryNotConfiguredException() { - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(next.exchange(any())).thenThrow(new TestException()); - - filterFunction.filter(clientRequest, next).subscribe(); - - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(1)).exchange(any()); - } - - @Test - void shouldRetryOnNotConfiguredExceptionWhenRetryOnAllExceptions() { - properties.getRetry().setRetryOnAllExceptions(true); - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(next.exchange(any())).thenThrow(new TestException()); - - filterFunction.filter(clientRequest, next).subscribe(); - - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - } - - @Test - void shouldRetryOnConfiguredException() { - properties.getRetry().setRetryableExceptions(new HashSet<>(Collections.singletonList(TestException.class))); - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(next.exchange(any())).thenThrow(new TestException()); - - filterFunction.filter(clientRequest, next).subscribe(); - - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - } - - @Test - void shouldRetryOnRetryableStatusCodeExceptionEvenWhenCustomExceptionsConfigured() { - properties.getRetry().setRetryableExceptions(new HashSet<>(Collections.singletonList(TestException.class))); - when(clientRequest.method()).thenReturn(HttpMethod.GET); - when(next.exchange(any())).thenThrow(new RetryableStatusCodeException()); - - filterFunction.filter(clientRequest, next).subscribe(); - - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - inOrder.verify(factory, times(1)).getInstance(any()); - inOrder.verify(next, times(2)).exchange(any()); - } - - protected static class TestException extends RuntimeException { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/TestReactiveLoadBalancer.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/TestReactiveLoadBalancer.java deleted file mode 100644 index 45b02661..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/loadbalancer/reactive/TestReactiveLoadBalancer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.loadbalancer.reactive; - -import java.util.Random; - -import org.reactivestreams.Publisher; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; - -/** - * A sample implementation of {@link ReactiveLoadBalancer} used for tests. - * - * @author Olga Maciaszek-Sharma - */ -class TestReactiveLoadBalancer implements ReactiveLoadBalancer { - - private static final String TEST_SERVICE_ID = "testServiceId"; - - private final Random random = new Random(); - - @Override - public Publisher> choose() { - return Mono.just(new DefaultResponse(new DefaultServiceInstance(TEST_SERVICE_ID, TEST_SERVICE_ID, - TEST_SERVICE_ID, random.nextInt(40000), false))); - } - - @Override - public Publisher> choose(Request request) { - return choose(); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationMgmtDisabledTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationMgmtDisabledTests.java deleted file mode 100644 index fef017e1..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationMgmtDisabledTests.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import java.net.URI; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import org.assertj.core.api.BDDAssertions; -import org.junit.jupiter.api.Test; - -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.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - * @author Tim Ysewyn - */ -@SpringBootTest(classes = AbstractAutoServiceRegistrationMgmtDisabledTests.Config.class, - properties = { "management.port=0", - "spring.cloud.service-registry.auto-registration.register-management=false" }, - webEnvironment = RANDOM_PORT) -public class AbstractAutoServiceRegistrationMgmtDisabledTests { - - @Autowired - private TestAutoServiceRegistration autoRegistration; - - @Test - public void portsWork() { - BDDAssertions.then(this.autoRegistration.shouldRegisterManagement()).isFalse(); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - public static class Config { - - @Bean - public TestAutoServiceRegistration testAutoServiceRegistration(AutoServiceRegistrationProperties properties) { - return new TestAutoServiceRegistration(properties); - } - - } - - public static class TestRegistration implements Registration { - - @Override - public String getInstanceId() { - return "testRegistrationInstance3"; - } - - @Override - public String getServiceId() { - return "testRegistration3"; - } - - @Override - public String getHost() { - return null; - } - - @Override - public int getPort() { - return 0; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public URI getUri() { - return null; - } - - @Override - public Map getMetadata() { - return null; - } - - } - - public static class TestMgmtRegistration extends TestRegistration { - - @Override - public String getServiceId() { - return "testMgmtRegistration3"; - } - - } - - public static class TestServiceRegistry implements ServiceRegistry { - - private boolean registered = false; - - private boolean deregistered = false; - - @Override - public void register(TestRegistration registration) { - if (registration == null) { - throw new NullPointerException(); - } - if (!(registration instanceof TestMgmtRegistration)) { - this.registered = true; - } - } - - @Override - public void deregister(TestRegistration registration) { - if (registration == null) { - throw new NullPointerException(); - } - if (!(registration instanceof TestMgmtRegistration)) { - this.deregistered = true; - } - } - - @Override - public void close() { - } - - @Override - public void setStatus(TestRegistration registration, String status) { - // TODO: test setStatus - } - - @Override - public Object getStatus(TestRegistration registration) { - // TODO: test getStatus - return null; - } - - boolean isRegistered() { - return this.registered; - } - - boolean isDeregistered() { - return this.deregistered; - } - - } - - public static class TestAutoServiceRegistration extends AbstractAutoServiceRegistration { - - private int port = 0; - - public TestAutoServiceRegistration(AutoServiceRegistrationProperties properties) { - super(new TestServiceRegistry(), properties); - } - - protected TestAutoServiceRegistration() { - super(new TestServiceRegistry(), new AutoServiceRegistrationProperties()); - } - - @Override - protected AtomicInteger getPort() { - return super.getPort(); - } - - @Override - protected String getAppName() { - return super.getAppName(); - } - - @Override - protected TestRegistration getRegistration() { - return new TestRegistration(); - } - - @Override - protected TestRegistration getManagementRegistration() { - return null; - } - - @Override - protected Object getConfiguration() { - return null; - } - - @Override - protected boolean isEnabled() { - return true; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationRegistrationLifecycleTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationRegistrationLifecycleTests.java deleted file mode 100644 index aea40fb1..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationRegistrationLifecycleTests.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.jupiter.api.Test; - -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.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Zen Huifer - */ -@SpringBootTest(classes = AbstractAutoServiceRegistrationRegistrationLifecycleTests.Config.class) -class AbstractAutoServiceRegistrationRegistrationLifecycleTests { - - @Autowired - @Qualifier("testAutoServiceRegistration") - private TestAutoServiceRegistrationLifecycle autoRegistration; - - @Test - void startTest() { - autoRegistration.start(); - } - - @Test - void stopTest() { - autoRegistration.stop(); - } - - static class RegistrationLifecycleImpl implements RegistrationLifecycle { - - @Override - public void postProcessBeforeStartRegister(TestRegistrationLifecycleRegistration registration) { - registration.getMetadata().putIfAbsent("test_data", "test_data"); - registration.getMetadata().putIfAbsent("is_start", "false"); - } - - @Override - public void postProcessAfterStartRegister(TestRegistrationLifecycleRegistration registration) { - assertThat(registration.getMetadata()).containsKey("test_data"); - assertThat(registration.getMetadata().get("test_data")).isEqualTo("test_data"); - assertThat(registration.getMetadata()).containsKey("is_start"); - registration.getMetadata().putIfAbsent("is_start", "true"); - } - - @Override - public void postProcessBeforeStopRegister(TestRegistrationLifecycleRegistration registration) { - assertThat(registration.getMetadata().get("is_start")).isEqualTo("true"); - Map metadata = registration.getMetadata(); - metadata.putIfAbsent("is_stop", "false"); - metadata.putIfAbsent("is_start", "false"); - } - - @Override - public void postProcessAfterStopRegister(TestRegistrationLifecycleRegistration registration) { - - assertThat(registration.getMetadata().get("test_data")).isEqualTo("test_data"); - assertThat(registration.getMetadata().get("is_stop")).isEqualTo("false"); - assertThat(registration.getMetadata().get("is_start")).isEqualTo("false"); - registration.getMetadata().putIfAbsent("is_stop", "true"); - } - - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - static class Config { - - @Bean - public TestAutoServiceRegistrationLifecycle testAutoServiceRegistration( - AutoServiceRegistrationProperties properties) { - List> registrationLifecycles = new ArrayList<>(); - registrationLifecycles.add(new RegistrationLifecycleImpl()); - return new TestAutoServiceRegistrationLifecycle(properties, registrationLifecycles); - } - - } - - static class TestAutoServiceRegistrationLifecycle - extends AbstractAutoServiceRegistration { - - private final int port = 0; - - TestRegistrationLifecycleRegistration testRegistrationLifecycleRegistration = new TestRegistrationLifecycleRegistration(); - - protected TestAutoServiceRegistrationLifecycle() { - super(new TestRegistrationLifecycleServiceRegistration(), new AutoServiceRegistrationProperties()); - } - - TestAutoServiceRegistrationLifecycle(AutoServiceRegistrationProperties properties) { - super(new TestRegistrationLifecycleServiceRegistration(), properties); - } - - TestAutoServiceRegistrationLifecycle(AutoServiceRegistrationProperties properties, - List> registrationManagementLifecycles, - List> registrationLifecycles) { - super(new TestRegistrationLifecycleServiceRegistration(), properties, registrationManagementLifecycles, - registrationLifecycles); - } - - TestAutoServiceRegistrationLifecycle(AutoServiceRegistrationProperties properties, - List> registrationLifecycles) { - super(new TestRegistrationLifecycleServiceRegistration(), properties, registrationLifecycles); - } - - @Override - protected AtomicInteger getPort() { - return super.getPort(); - } - - @Override - protected String getAppName() { - return super.getAppName(); - } - - @Override - protected TestRegistrationLifecycleRegistration getRegistration() { - return testRegistrationLifecycleRegistration; - } - - @Override - protected TestRegistrationLifecycleRegistration getManagementRegistration() { - return null; - } - - @Override - protected Object getConfiguration() { - return null; - } - - @Override - protected boolean isEnabled() { - return true; - } - - } - - static class TestRegistrationLifecycleServiceRegistration - implements ServiceRegistry { - - private boolean registered = false; - - private boolean deregistered = false; - - @Override - public void register(TestRegistrationLifecycleRegistration registration) { - if (registration == null) { - throw new NullPointerException(); - } - if (!(registration instanceof TestRegistrationLifecycleRegistration)) { - this.registered = true; - } - } - - @Override - public void deregister(TestRegistrationLifecycleRegistration registration) { - if (registration == null) { - throw new NullPointerException(); - } - if (!(registration instanceof TestRegistrationLifecycleRegistration)) { - this.deregistered = true; - } - } - - @Override - public void close() { - - } - - @Override - public void setStatus(TestRegistrationLifecycleRegistration registration, String status) { - - } - - @Override - public T getStatus(TestRegistrationLifecycleRegistration registration) { - return null; - } - - boolean isRegistered() { - return registered; - } - - boolean isDeregistered() { - return deregistered; - } - - } - - static class TestRegistrationLifecycleRegistration implements Registration { - - private final Map metadata = new HashMap<>(8); - - @Override - public String getInstanceId() { - return "TestRegistrationLifecycleRegistration"; - } - - @Override - public String getServiceId() { - return "test"; - } - - @Override - public String getHost() { - return null; - } - - @Override - public int getPort() { - return 0; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public URI getUri() { - return null; - } - - @Override - public Map getMetadata() { - return this.metadata; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationTests.java deleted file mode 100644 index 3ac6d3e2..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AbstractAutoServiceRegistrationTests.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import java.net.URI; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.jupiter.api.Test; - -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.server.LocalManagementPort; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent; -import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Spencer Gibb - * @author Tim Ysewyn - */ -// @checkstyle:off -@SpringBootTest(classes = AbstractAutoServiceRegistrationTests.Config.class, properties = "management.port=0", - webEnvironment = RANDOM_PORT) -// @checkstyle:on -public class AbstractAutoServiceRegistrationTests { - - @Autowired - public PostEventListener postEventListener; - - @Autowired - private TestAutoServiceRegistration autoRegistration; - - @Autowired - private PreEventListener preEventListener; - - @LocalServerPort - private int port; - - @LocalManagementPort - private int managementPort; - - @Test - public void portsWork() { - then(this.autoRegistration.getPort().get()).isNotEqualTo(0).as("Lifecycle port is zero"); - then(this.managementPort).isNotEqualTo(this.autoRegistration.getPort().get()) - .as("Lifecycle port is management port"); - then(this.port).isEqualTo(this.autoRegistration.getPort().get()).as("Lifecycle port is wrong"); - then(this.autoRegistration.isRunning()).isTrue().as("Lifecycle not running"); - then(this.autoRegistration.getServiceRegistry()).isInstanceOf(TestServiceRegistry.class) - .as("ServiceRegistry is wrong type"); - TestServiceRegistry serviceRegistry = (TestServiceRegistry) this.autoRegistration.getServiceRegistry(); - then(serviceRegistry.isRegistered()).isTrue().as("Lifecycle not registered"); - then(this.autoRegistration.getAppName()).as("Lifecycle appName is wrong").isEqualTo("application"); - } - - @Test - public void eventsFireTest() { - then(this.preEventListener.wasFired).isTrue(); - then(this.preEventListener.registration.getServiceId()).isEqualTo("testRegistration2"); - then(this.postEventListener.wasFired).isTrue(); - then(this.postEventListener.config.getServiceId()).isEqualTo("testRegistration2"); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - public static class Config { - - @Bean - public TestAutoServiceRegistration testAutoServiceRegistration() { - return new TestAutoServiceRegistration(); - } - - @Bean - public PreEventListener preRegisterListener() { - return new PreEventListener(); - } - - @Bean - public PostEventListener postEventListener() { - return new PostEventListener(); - } - - } - - public static class PreEventListener implements ApplicationListener { - - public boolean wasFired = false; - - public Registration registration; - - @Override - public void onApplicationEvent(InstancePreRegisteredEvent event) { - this.registration = event.getRegistration(); - this.wasFired = true; - } - - } - - public static class PostEventListener implements ApplicationListener { - - public boolean wasFired = false; - - public Registration config; - - @Override - public void onApplicationEvent(InstanceRegisteredEvent event) { - this.config = (Registration) event.getConfig(); - this.wasFired = true; - } - - } - - public static class TestRegistration implements Registration { - - @Override - public String getInstanceId() { - return "testRegistrationInstance2"; - } - - @Override - public String getServiceId() { - return "testRegistration2"; - } - - @Override - public String getHost() { - return null; - } - - @Override - public int getPort() { - return 0; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public URI getUri() { - return null; - } - - @Override - public Map getMetadata() { - return null; - } - - } - - public static class TestMgmtRegistration extends TestRegistration { - - @Override - public String getServiceId() { - return "testMgmtRegistration2"; - } - - } - - public static class TestServiceRegistry implements ServiceRegistry { - - private boolean registered = false; - - private boolean deregistered = false; - - @Override - public void register(TestRegistration registration) { - if (registration == null) { - throw new NullPointerException(); - } - if (!(registration instanceof TestMgmtRegistration)) { - this.registered = true; - } - } - - @Override - public void deregister(TestRegistration registration) { - if (registration == null) { - throw new NullPointerException(); - } - if (!(registration instanceof TestMgmtRegistration)) { - this.deregistered = true; - } - } - - @Override - public void close() { - } - - @Override - public void setStatus(TestRegistration registration, String status) { - // TODO: test setStatus - } - - @Override - public Object getStatus(TestRegistration registration) { - // TODO: test getStatus - return null; - } - - boolean isRegistered() { - return this.registered; - } - - boolean isDeregistered() { - return this.deregistered; - } - - } - - public static class TestAutoServiceRegistration extends AbstractAutoServiceRegistration { - - private int port = 0; - - public TestAutoServiceRegistration(AutoServiceRegistrationProperties properties) { - super(null, properties); - } - - protected TestAutoServiceRegistration() { - super(new TestServiceRegistry(), new AutoServiceRegistrationProperties()); - } - - @Override - protected AtomicInteger getPort() { - return super.getPort(); - } - - @Override - protected String getAppName() { - return super.getAppName(); - } - - protected int getConfiguredPort() { - return this.port; - } - - protected void setConfiguredPort(int port) { - this.port = port; - } - - @Override - protected TestRegistration getRegistration() { - return new TestRegistration(); - } - - @Override - protected TestRegistration getManagementRegistration() { - return null; - } - - @Override - protected Object getConfiguration() { - return getRegistration(); - } - - @Override - protected boolean isEnabled() { - return true; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfigurationTests.java deleted file mode 100644 index a93a302b..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/AutoServiceRegistrationAutoConfigurationTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.StringUtils; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - */ -public class AutoServiceRegistrationAutoConfigurationTests { - - @Test - public void hasAutoServiceRegistration() { - try (AnnotationConfigApplicationContext context = setup(HasAutoServiceRegistrationConfiguration.class)) { - AutoServiceRegistration autoServiceRegistration = context.getBean(AutoServiceRegistration.class); - then(autoServiceRegistration).isNotNull(); - } - } - - @Test - public void noAutoServiceRegistrationAndFailFast() { - assertThatThrownBy(() -> { - try (AnnotationConfigApplicationContext context = setup( - "spring.cloud.service-registry.auto-registration.failFast=true")) { - assertNoBean(context); - } - }).isInstanceOf(BeanCreationException.class).hasMessageContaining("no AutoServiceRegistration"); - } - - @Test - public void noAutoServiceRegistrationAndFailFastFalse() { - try (AnnotationConfigApplicationContext context = setup()) { - assertNoBean(context); - } - } - - private void assertNoBean(AnnotationConfigApplicationContext context) { - Map beans = context.getBeansOfType(AutoServiceRegistration.class); - then(beans).isEmpty(); - } - - private AnnotationConfigApplicationContext setup(Class... classes) { - return setup(null, classes); - } - - private AnnotationConfigApplicationContext setup(String property, Class... classes) { - ArrayList list = new ArrayList<>(); - list.add(AutoServiceRegistrationConfiguration.class); - list.add(AutoServiceRegistrationAutoConfiguration.class); - list.addAll(Arrays.asList(classes)); - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); - context.register(list.toArray(new Class[0])); - if (StringUtils.hasText(property)) { - TestPropertyValues.of(property).applyTo(context); - } - context.refresh(); - return context; - } - - @Configuration(proxyBeanMethods = false) - static class HasAutoServiceRegistrationConfiguration { - - @Bean - public AutoServiceRegistration autoServiceRegistration() { - return new AutoServiceRegistration() { - }; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfigurationTests.java deleted file mode 100644 index 3e919ecc..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/ServiceRegistryAutoConfigurationTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.fail; - -/** - * @author Spencer Gibb - */ -@ClassPathExclusions({ "spring-boot-actuator-*.jar", "spring-boot-starter-actuator-*.jar" }) -public class ServiceRegistryAutoConfigurationTests { - - @Test - public void runsWithoutActuator() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfig.class) - .web(WebApplicationType.NONE).run(); - try { - context.getBean("serviceRegistryEndpoint"); - fail("found a bean that shouldn't be there"); - } - catch (NoSuchBeanDefinitionException e) { - // success - } - } - - @Configuration(proxyBeanMethods = false) - protected static class TestConfig { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointNoRegistrationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointNoRegistrationTests.java deleted file mode 100644 index 7e91a616..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointNoRegistrationTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry.endpoint; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -import org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpointTests.TestServiceRegistry; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.web.servlet.MockMvc; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** - * @author Spencer Gibb - */ -@SpringBootTest(classes = ServiceRegistryEndpointNoRegistrationTests.TestConfiguration.class) -@AutoConfigureMockMvc -public class ServiceRegistryEndpointNoRegistrationTests { - - @Autowired - private MockMvc mvc; - - @Test - public void testGet() throws Exception { - this.mvc.perform(get("/service-registry/instance-status")).andExpect(status().isNotFound()); - } - - @Test - public void testPost() throws Exception { - this.mvc.perform(post("/service-registry/instance-status").content("newstatus")) - .andExpect(status().isNotFound()); - } - - @Import({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, - EndpointAutoConfiguration.class, WebMvcAutoConfiguration.class - // ManagementServerPropertiesAutoConfiguration.class - }) - @Configuration(proxyBeanMethods = false) - public static class TestConfiguration { - - @Bean - ServiceRegistryEndpoint serviceRegistryEndpoint() { - return new ServiceRegistryEndpoint(serviceRegistry()); - } - - @Bean - ServiceRegistry serviceRegistry() { - return new TestServiceRegistry(); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointTests.java deleted file mode 100644 index 8605f311..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/serviceregistry/endpoint/ServiceRegistryEndpointTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.client.serviceregistry.endpoint; - -import java.net.URI; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -import com.fasterxml.jackson.databind.ObjectMapper; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -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.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.hamcrest.Matchers.containsString; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** - * @author Spencer Gibb - * @author Tim Ysewyn - */ -// @checkstyle:off -@SpringBootTest(classes = ServiceRegistryEndpointTests.TestConfiguration.class, - properties = "management.endpoints.web.exposure.include=*") -// @checkstyle:on -@AutoConfigureMockMvc -public class ServiceRegistryEndpointTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - private static final String UPDATED_STATUS = "updatedstatus"; - - private static final String MYSTATUS = "mystatus"; - - @Autowired - private TestServiceRegistry serviceRegistry; - - @Autowired - private MockMvc mvc; - - @Test - public void testGet() throws Exception { - this.mvc.perform(get(BASE_PATH + "/serviceregistry")).andExpect(status().isOk()) - .andExpect(content().string(containsString(MYSTATUS))); - } - - @Test - public void testPost() throws Exception { - Map status = Collections.singletonMap("status", UPDATED_STATUS); - this.mvc.perform(post(BASE_PATH + "/serviceregistry").content(new ObjectMapper().writeValueAsString(status)) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); - then(this.serviceRegistry.getUpdatedStatus().get()).isEqualTo(UPDATED_STATUS); - } - - @EnableAutoConfiguration - @SpringBootConfiguration - public static class TestConfiguration { - - @Bean - Registration registration() { - return new Registration() { - @Override - public String getInstanceId() { - return "testRegistrationInstance1"; - } - - @Override - public String getServiceId() { - return "testRegistration1"; - } - - @Override - public String getHost() { - return null; - } - - @Override - public int getPort() { - return 0; - } - - @Override - public boolean isSecure() { - return false; - } - - @Override - public URI getUri() { - return null; - } - - @Override - public Map getMetadata() { - return null; - } - }; - } - - @Bean - ServiceRegistry serviceRegistry() { - return new TestServiceRegistry(); - } - - } - - static class TestServiceRegistry implements ServiceRegistry { - - AtomicReference updatedStatus = new AtomicReference<>(); - - @Override - public void register(Registration registration) { - - } - - @Override - public void deregister(Registration registration) { - - } - - @Override - public void close() { - - } - - @Override - public void setStatus(Registration registration, String status) { - this.updatedStatus.compareAndSet(null, status); - } - - @Override - public Object getStatus(Registration registration) { - return MYSTATUS; - } - - public AtomicReference getUpdatedStatus() { - return this.updatedStatus; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessorTests.java deleted file mode 100644 index 26e88bbe..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/ConfigDataMissingEnvironmentPostProcessorTests.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2015-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.Environment; -import org.springframework.mock.env.MockEnvironment; -import org.springframework.mock.env.MockPropertySource; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.mockito.Mockito.mock; - -/** - * @author Ryan Baxter - */ -@ExtendWith(OutputCaptureExtension.class) -public class ConfigDataMissingEnvironmentPostProcessorTests { - - @Test - void noSpringConfigImport() { - MockEnvironment environment = new MockEnvironment(); - SpringApplication app = mock(SpringApplication.class); - TestConfigDataMissingEnvironmentPostProcessor processor = new TestConfigDataMissingEnvironmentPostProcessor(); - assertThatThrownBy(() -> processor.postProcessEnvironment(environment, app)) - .isInstanceOf(ConfigDataMissingEnvironmentPostProcessor.ImportException.class); - } - - @Test - void importSinglePropertySource() { - MockEnvironment environment = new MockEnvironment(); - environment.setProperty("spring.config.import", "configserver:http://localhost:8888"); - SpringApplication app = mock(SpringApplication.class); - TestConfigDataMissingEnvironmentPostProcessor processor = new TestConfigDataMissingEnvironmentPostProcessor(); - assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException(); - } - - @Test - void importMultiplePropertySource() { - MockEnvironment environment = new MockEnvironment(); - environment.setProperty("spring.config.import", "configserver:http://localhost:8888,file:./app.properties"); - SpringApplication app = mock(SpringApplication.class); - TestConfigDataMissingEnvironmentPostProcessor processor = new TestConfigDataMissingEnvironmentPostProcessor(); - assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException(); - } - - @Test - void importMultiplePropertySourceAsList() { - MockEnvironment environment = new MockEnvironment(); - environment.setProperty("spring.config.import[0]", "configserver:http://localhost:8888"); - environment.setProperty("spring.config.import[1]", "file:./app.properties"); - SpringApplication app = mock(SpringApplication.class); - TestConfigDataMissingEnvironmentPostProcessor processor = new TestConfigDataMissingEnvironmentPostProcessor(); - assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException(); - } - - @Test - void importCompositePropertySource() { - MockEnvironment environment = new MockEnvironment(); - CompositePropertySource ps1 = new CompositePropertySource("ps1"); - MockPropertySource ps2 = new MockPropertySource("ps2"); - ps2.setProperty("spring.config.import", "file:./app.properties"); - MockPropertySource ps3 = new MockPropertySource("ps3"); - ps3.setProperty("my.property", "value"); - MockPropertySource ps4 = new MockPropertySource("ps4"); - ps4.setProperty("spring.config.import[0]", "file:./moreproperties.yaml"); - ps4.setProperty("spring.config.import[1]", "configserver:http://localhost:8888"); - CompositePropertySource compositePropertySource = new CompositePropertySource("composite"); - compositePropertySource.addPropertySource(ps3); - compositePropertySource.addPropertySource(ps4); - ps1.addPropertySource(compositePropertySource); - environment.getPropertySources().addFirst(ps2); - environment.getPropertySources().addLast(ps1); - SpringApplication app = mock(SpringApplication.class); - TestConfigDataMissingEnvironmentPostProcessor processor = new TestConfigDataMissingEnvironmentPostProcessor(); - assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException(); - } - - @Test - void importHandlesNullConfigurationPropertySource(CapturedOutput output) { - MockEnvironment environment = new MockEnvironment(); - ConfigurationPropertySources.attach(environment); - environment.setProperty("spring.config.import[0]", "configserver:http://localhost:8888"); - environment.setProperty("spring.config.import[1]", "file:./app.properties"); - SpringApplication app = mock(SpringApplication.class); - TestConfigDataMissingEnvironmentPostProcessor processor = new TestConfigDataMissingEnvironmentPostProcessor(); - assertThatCode(() -> processor.postProcessEnvironment(environment, app)).doesNotThrowAnyException(); - assertThat(output).doesNotContain("Error binding spring.config.import"); - } - - static public class TestConfigDataMissingEnvironmentPostProcessor - extends ConfigDataMissingEnvironmentPostProcessor { - - @Override - protected boolean shouldProcessEnvironment(Environment environment) { - return true; - } - - @Override - protected String getPrefix() { - return "configserver:"; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmittingTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmittingTests.java deleted file mode 100644 index 0d7ac759..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/publisher/FluxFirstNonEmptyEmittingTests.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.publisher; - -import java.time.Duration; -import java.util.Arrays; - -import org.junit.jupiter.api.Test; -import org.reactivestreams.Publisher; -import org.reactivestreams.Subscription; -import reactor.core.CoreSubscriber; -import reactor.core.Scannable; -import reactor.core.publisher.BaseSubscriber; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Operators; -import reactor.test.StepVerifier; - -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatNullPointerException; - -/** - * @author Tim Ysewyn - */ -public class FluxFirstNonEmptyEmittingTests { - - @Test - public void arrayNull() { - assertThatNullPointerException().isThrownBy(() -> CloudFlux.firstNonEmpty((Publisher[]) null)); - } - - @Test - public void iterableNull() { - assertThatNullPointerException().isThrownBy(() -> CloudFlux.firstNonEmpty((Iterable>) null)); - } - - @Test - public void firstWinner() { - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.range(1, 10), Flux.range(11, 10))) - .expectNext(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).verifyComplete(); - } - - @Test - public void firstWinnerSecondEmpty() { - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.range(1, 10), Flux.empty())) - .expectNext(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).verifyComplete(); - } - - @Test - public void firstWinnerBackpressured() { - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.range(1, 10), Flux.range(11, 10))).thenRequest(5) - .expectNext(1, 2, 3, 4, 5).thenCancel().verifyThenAssertThat().hasNotDiscardedElements() - .hasNotDroppedElements().hasNotDroppedErrors(); - } - - @Test - public void secondWinner() { - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.never(), Flux.range(11, 10).log())) - .expectNext(11, 12, 13, 14, 15, 16, 17, 18, 19, 20).verifyComplete(); - } - - @Test - public void secondWinnerFirstEmpty() { - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.empty(), Flux.range(11, 10).log())) - .expectNext(11, 12, 13, 14, 15, 16, 17, 18, 19, 20).verifyComplete(); - } - - @Test - public void bothEmpty() { - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.empty(), Flux.empty())).expectComplete().verifyThenAssertThat() - .hasNotDiscardedElements().hasNotDroppedElements().hasNotDroppedErrors(); - } - - @Test - public void neverAndEmpty() { - StepVerifier.withVirtualTime(() -> CloudFlux.firstNonEmpty(Flux.never(), Flux.empty())).expectSubscription() - .expectNoEvent(Duration.ofDays(1)).thenCancel().verifyThenAssertThat().hasNotDiscardedElements() - .hasNotDroppedElements().hasNotDroppedErrors(); - } - - @Test - public void firstEmitsError() { - RuntimeException ex = new RuntimeException("forced failure"); - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.error(ex), Flux.empty())) - .expectErrorMessage("forced failure").verifyThenAssertThat().hasNotDiscardedElements() - .hasNotDroppedElements().hasNotDroppedErrors(); - } - - @Test - public void secondEmitsError() { - RuntimeException ex = new RuntimeException("forced failure"); - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.empty(), Flux.error(ex))) - .expectErrorMessage("forced failure").verifyThenAssertThat().hasNotDiscardedElements() - .hasNotDroppedElements().hasNotDroppedErrors(); - } - - @Test - public void neverAndSecondEmitsError() { - RuntimeException ex = new RuntimeException("forced failure"); - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.never(), Flux.error(ex))) - .expectErrorMessage("forced failure").verifyThenAssertThat().hasNotDiscardedElements() - .hasNotDroppedElements().hasNotDroppedErrors(); - } - - @Test - public void singleArrayNullSource() { - StepVerifier.create(CloudFlux.firstNonEmpty((Publisher) null)).expectError(NullPointerException.class) - .verify(); - } - - @Test - public void arrayOneIsNullSource() { - StepVerifier.create(CloudFlux.firstNonEmpty(Flux.never(), null, Flux.never())) - .expectError(NullPointerException.class).verify(); - } - - @Test - public void singleIterableNullSource() { - StepVerifier.create(CloudFlux.firstNonEmpty(singletonList((Publisher) null))) - .expectError(NullPointerException.class).verify(); - } - - @Test - public void iterableOneIsNullSource() { - StepVerifier - .create(CloudFlux.firstNonEmpty(Arrays.asList(Flux.never(), (Publisher) null, Flux.never()))) - .expectError(NullPointerException.class).verify(); - } - - @Test - public void scanSubscriber() { - CoreSubscriber actual = new TestSubscriber<>(); - FluxFirstNonEmptyEmitting.RaceCoordinator parent = new FluxFirstNonEmptyEmitting.RaceCoordinator<>(1); - FluxFirstNonEmptyEmitting.FirstNonEmptyEmittingSubscriber test = new FluxFirstNonEmptyEmitting.FirstNonEmptyEmittingSubscriber<>( - actual, parent, 1); - Subscription sub = Operators.emptySubscription(); - test.onSubscribe(sub); - - assertThat(test.scan(Scannable.Attr.PARENT)).isSameAs(sub); - assertThat(test.scan(Scannable.Attr.ACTUAL)).isSameAs(actual); - assertThat(test.scan(Scannable.Attr.CANCELLED)).isFalse(); - parent.cancelled = true; - assertThat(test.scan(Scannable.Attr.CANCELLED)).isTrue(); - } - - @Test - public void scanRaceCoordinator() { - CoreSubscriber actual = new TestSubscriber<>(); - FluxFirstNonEmptyEmitting.RaceCoordinator parent = new FluxFirstNonEmptyEmitting.RaceCoordinator<>(1); - FluxFirstNonEmptyEmitting.FirstNonEmptyEmittingSubscriber test = new FluxFirstNonEmptyEmitting.FirstNonEmptyEmittingSubscriber<>( - actual, parent, 1); - Subscription sub = Operators.emptySubscription(); - test.onSubscribe(sub); - - assertThat(test.scan(Scannable.Attr.PARENT)).isSameAs(sub); - assertThat(test.scan(Scannable.Attr.ACTUAL)).isSameAs(actual); - assertThat(parent.scan(Scannable.Attr.CANCELLED)).isFalse(); - parent.cancelled = true; - assertThat(parent.scan(Scannable.Attr.CANCELLED)).isTrue(); - } - - static class TestSubscriber extends BaseSubscriber implements Scannable { - - @Override - public Object scanUnsafe(Attr key) { - return null; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfigurationTests.java deleted file mode 100644 index 47fd1103..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/ResourceServerTokenRelayAutoConfigurationTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2015-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.commons.security; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -@Disabled -public class ResourceServerTokenRelayAutoConfigurationTests { - - private ConfigurableApplicationContext context; - - @AfterEach - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void clientNotConfigured() { - this.context = new SpringApplicationBuilder(NoClientConfiguration.class) - .properties("spring.config.name=test", "server.port=0", "spring.cloud.mvc.token-relay.enabled=true", - "security.oauth2.resource.userInfoUri:https://example.com") - .run(); - assertThat(this.context.containsBean("loadBalancedOauth2RestTemplate")).isFalse(); - } - - @Test - public void clientConfigured() throws Exception { - /* - * this.context = new - * SpringApplicationBuilder(ClientConfiguration.class).properties( - * "spring.config.name=test", "server.port=0", - * "security.oauth2.resource.userInfoUri:https://example.com", - * "security.oauth2.client.clientId=foo").run(); - * RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(new - * MockHttpServletRequest())); OAuth2ClientContext client = - * this.context.getBean(OAuth2ClientContext.class); - * assertThat(client.getAccessToken()).isNull(); UserInfoTokenServices services = - * context.getBean(UserInfoTokenServices.class); OAuth2RestTemplate template = - * (OAuth2RestTemplate) ReflectionTestUtils.getField(services, "restTemplate"); - * MockRestServiceServer server = MockRestServiceServer.createServer(template); - * server.expect(requestTo("https://example.com")) - * .andRespond(withSuccess("{\"id\":\"user\"}", MediaType.APPLICATION_JSON)); - * services.loadAuthentication("FOO"); - * assertThat(client.getAccessToken().getValue()).isEqualTo("FOO"); - * server.verify(); - */ - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - // @EnableResourceServer - protected static class NoClientConfiguration { - - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - // @EnableResourceServer - // @EnableOAuth2Sso - protected static class ClientConfiguration { - - /* - * @Bean public OAuth2RestTemplate - * oauth2RestTemplate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext - * oauth2Context) { return new OAuth2RestTemplate(resource, oauth2Context); } - */ - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/tokenrelay/ResourceServerTokenRelayTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/tokenrelay/ResourceServerTokenRelayTests.java deleted file mode 100644 index 77f68dc2..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/security/tokenrelay/ResourceServerTokenRelayTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2015-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.commons.security.tokenrelay; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.context.TestComponent; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.boot.test.mock.mockito.SpyBean; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.cloud.commons.security.AccessTokenContextRelay; -import org.springframework.context.annotation.ComponentScan; -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.web.client.MockRestServiceServer; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.header; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; - -/** - * @author Peter Szanto (spring@szantocsalad.hu) - * - */ -@Disabled -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, - properties = { "security.oauth2.resource.jwt.keyValue=secret", "spring.cloud.mvc.token-relay.enabled=true", - "spring.autoconfigure.exclude=" }) -public class ResourceServerTokenRelayTests { - - protected static final String TOKEN_VALID_UNTIL_2085 = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." - + "eyJleHAiOjM2NDA2ODU4ODIsInVzZXJfbmFtZSI6InJlYWRlciIsImF1dGhvcml0aWVzIjpbIlJPTEVfUkVBREVSIl0s" - + "Imp0aSI6ImRkOTAzZGM2LTI0NDctNDViMi04MDZjLTIzZjU3ODVhNGQ4MCIsImNsaWVudF9pZCI6IndlYi1hcHAiLCJzY29wZSI6WyJyZWFkIl19." - + "6hoNtxmN1_o5Ki0D0ae4amSOTRmit3pmaqv-z1-Qk4Y"; - - protected static final String AUTH_HEADER_TO_BE_RELAYED = "Bearer " + TOKEN_VALID_UNTIL_2085; - - protected static final String TEST_RESPONSE = "[\"test response\"]"; - - @Autowired - private TestRestTemplate testRestTemplate; - - @Autowired - private MockRestServiceServer mockServerToReceiveRelay; - - @SpyBean - AccessTokenContextRelay accessTokenContextRelay; - - @Test - public void tokenRelayJWT() { - - mockServerToReceiveRelay.expect(requestTo("https://example.com/test")) - .andExpect(header("authorization", AUTH_HEADER_TO_BE_RELAYED)) - .andRespond(withSuccess(TEST_RESPONSE, MediaType.APPLICATION_JSON)); - - HttpEntity authorizationHeader = createAuthorizationHeader(); - ResponseEntity exchange = testRestTemplate.exchange("/token-relay", HttpMethod.GET, authorizationHeader, - String.class); - - assertThat(exchange.getStatusCode().value()).isEqualTo(HttpStatus.OK.value()); - assertThat(exchange.getBody()).isEqualTo(TEST_RESPONSE); - - mockServerToReceiveRelay.verify(); - // verify(accessTokenContextRelay).copyToken(); - } - - private HttpEntity createAuthorizationHeader() { - HttpHeaders headers = new HttpHeaders(); - headers.add("Authorization", AUTH_HEADER_TO_BE_RELAYED); - return new HttpEntity<>("parameters", headers); - - } - - @SpringBootApplication - @TestConfiguration - // @EnableResourceServer - @ComponentScan(basePackageClasses = TokenRelayTestController.class) - // @EnableOAuth2Client - protected static class ClientConfiguration { - - /* - * @Bean public OAuth2RestTemplate - * oauth2RestTemplate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext - * oauth2Context) { return new OAuth2RestTemplate(resource, oauth2Context); - * - * } - * - * @Bean public MockRestServiceServer mockRestServiceServer(OAuth2RestTemplate - * template) { return MockRestServiceServer.createServer(template); } - */ - - } - - @RestController - @TestComponent - protected static class TokenRelayTestController { - - /* - * @Autowired OAuth2RestTemplate oAuth2RestTemplate; - * - * @GetMapping("/token-relay") public String callAnotherService() { - * - * return oAuth2RestTemplate.getForEntity("https://example.com/test", - * String.class).getBody(); - * - * } - */ - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/IdUtilsTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/IdUtilsTests.java deleted file mode 100644 index a14367b5..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/IdUtilsTests.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.mock.env.MockEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * Tests for {@link IdUtils}. - * - * @author Spencer Gibb - */ -public class IdUtilsTests { - - public static final String DEFAULT_ID = "id1"; - - private MockEnvironment env; - - @BeforeEach - public void setup() { - this.env = new MockEnvironment(); - } - - @AfterEach - public void destroy() { - this.env = null; - } - - @Test - public void emptyEnvironmentWorks() { - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(instanceId).as("instanceId was not null").isNull(); - } - - @Test - public void vcapInstanceIdWorks() { - this.env.setProperty("vcap.application.instance_id", DEFAULT_ID); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(DEFAULT_ID).isEqualTo(instanceId).as("instanceId was wrong"); - } - - @Test - public void hostnameWorks() { - this.env.setProperty("spring.cloud.client.hostname", DEFAULT_ID); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(DEFAULT_ID).isEqualTo(instanceId).as("instanceId was wrong"); - } - - @Test - public void appNameWorks() { - this.env.setProperty("spring.application.name", DEFAULT_ID); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(DEFAULT_ID).isEqualTo(instanceId).as("instanceId was wrong"); - } - - @Test - public void hostnameAndAppNameWorks() { - this.env.setProperty("spring.application.name", DEFAULT_ID); - this.env.setProperty("spring.cloud.client.hostname", DEFAULT_ID + "2"); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(instanceId).as("instanceId was wrong").isEqualTo(DEFAULT_ID + "2" + ":" + DEFAULT_ID); - } - - @Test - public void instanceIdWorks() { - this.env.setProperty("spring.cloud.client.hostname", DEFAULT_ID); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(DEFAULT_ID).isEqualTo(instanceId).as("instanceId was wrong"); - } - - @Test - public void portWorks() { - this.env.setProperty("spring.application.name", DEFAULT_ID); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(DEFAULT_ID).isEqualTo(instanceId).as("instanceId was wrong"); - } - - @Test - public void appNameAndPortWorks() { - this.env.setProperty("spring.application.name", DEFAULT_ID); - this.env.setProperty("server.port", "80"); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then(DEFAULT_ID + ":80").isEqualTo(instanceId).as("instanceId was wrong"); - } - - @Test - public void fullWorks() { - this.env.setProperty("spring.cloud.client.hostname", "myhost"); - this.env.setProperty("spring.application.name", DEFAULT_ID); - this.env.setProperty("server.port", "80"); - String instanceId = IdUtils.getDefaultInstanceId(this.env); - then("myhost:" + DEFAULT_ID + ":80").isEqualTo(instanceId).as("instanceId was wrong"); - } - - @Test - public void testUnresolvedServiceId() { - then(IdUtils.DEFAULT_SERVICE_ID_STRING).isEqualTo(IdUtils.getUnresolvedServiceId()); - } - - @Test - public void testUnresolvedServiceIdWithActiveProfiles() { - then(IdUtils.DEFAULT_SERVICE_ID_WITH_ACTIVE_PROFILES_STRING) - .isEqualTo(IdUtils.getUnresolvedServiceIdWithActiveProfiles()); - } - - @Test - public void testServiceIdDefaults() { - this.env.setProperty("cachedrandom.application.value", "123abc"); - then("application:8080:123abc").isEqualTo(IdUtils.getResolvedServiceId(this.env)); - } - - @Test - public void testVCAPServiceId() { - env.setProperty("vcap.application.name", "vcapname"); - env.setProperty("vcap.application.instance_index", "vcapindex"); - env.setProperty("vcap.application.instance_id", "vcapid"); - then("vcapname:vcapindex:vcapid").isEqualTo(IdUtils.getResolvedServiceId(env)); - } - - @Test - public void testSpringServiceId() { - env.setProperty("spring.application.name", "springname"); - env.setProperty("spring.application.index", "springindex"); - env.setProperty("cachedrandom.springname.value", "123abc"); - then("springname:springindex:123abc").isEqualTo(IdUtils.getResolvedServiceId(env)); - } - - @Test - public void testServerPortServiceId() { - env.setProperty("spring.application.name", "springname"); - env.setProperty("server.port", "1234"); - env.setProperty("cachedrandom.springname.value", "123abc"); - then("springname:1234:123abc").isEqualTo(IdUtils.getResolvedServiceId(env)); - - // ensure that for spring.profiles.active, empty string value is equivalent to not - // being set at all - env.setProperty("spring.profiles.active", ""); - then("springname:1234:123abc").isEqualTo(IdUtils.getResolvedServiceId(env)); - } - - @Test - public void testVCAPServiceIdWithActiveProfile() { - env.setProperty("vcap.application.name", "vcapname"); - env.setProperty("vcap.application.instance_index", "vcapindex"); - env.setProperty("vcap.application.instance_id", "vcapid"); - env.setProperty("spring.profiles.active", "123profile"); - then("vcapname:vcapindex:vcapid").isEqualTo(IdUtils.getResolvedServiceId(env)); - } - - @Test - public void testSpringServiceIdWithActiveProfile() { - env.setProperty("spring.application.name", "springname"); - env.setProperty("spring.application.index", "springindex"); - env.setProperty("cachedrandom.springname.value", "123abc"); - env.setProperty("spring.profiles.active", "123profile"); - then("springname:123profile:springindex:123abc").isEqualTo(IdUtils.getResolvedServiceId(env)); - } - - @Test - public void testServerPortServiceIdWithActiveProfile() { - env.setProperty("spring.application.name", "springname"); - env.setProperty("server.port", "1234"); - env.setProperty("cachedrandom.springname.value", "123abc"); - env.setProperty("spring.profiles.active", "123profile"); - then("springname:123profile:1234:123abc").isEqualTo(IdUtils.getResolvedServiceId(env)); - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java deleted file mode 100644 index 36eb3aee..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import java.net.InetAddress; -import java.util.Arrays; -import java.util.Collections; - -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.commons.util.InetUtils.HostInfo; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - * - */ -public class InetUtilsTests { - - @Test - public void testGetFirstNonLoopbackHostInfo() { - try (InetUtils utils = new InetUtils(new InetUtilsProperties())) { - then(utils.findFirstNonLoopbackHostInfo()).isNotNull(); - } - } - - @Test - public void testGetFirstNonLoopbackAddress() { - try (InetUtils utils = new InetUtils(new InetUtilsProperties())) { - then(utils.findFirstNonLoopbackAddress()).isNotNull(); - } - } - - @Test - public void testConvert() throws Exception { - try (InetUtils utils = new InetUtils(new InetUtilsProperties())) { - then(utils.convertAddress(InetAddress.getByName("localhost"))).isNotNull(); - } - } - - @Test - public void testHostInfo() { - try (InetUtils utils = new InetUtils(new InetUtilsProperties())) { - HostInfo info = utils.findFirstNonLoopbackHostInfo(); - then(info.getIpAddressAsInt()).isNotNull(); - } - } - - @Test - public void testIgnoreInterface() { - InetUtilsProperties properties = new InetUtilsProperties(); - // These interfaces are not usable for "outside" communication, so they're - // probably not a good fit for the simple strategy of getting the first "usable" - // interface. - // https://docs.docker.com/v1.7/articles/networking/ - properties.setIgnoredInterfaces(Arrays.asList("docker0", "veth.*")); - try (InetUtils inetUtils = new InetUtils(properties)) { - - then(inetUtils.ignoreInterface("docker0")).isTrue().as("docker0 not ignored"); - then(inetUtils.ignoreInterface("vethAQI2QT")).as("vethAQI2QT0 not ignored").isTrue(); - then(inetUtils.ignoreInterface("docker1")).as("docker1 ignored").isFalse(); - } - } - - @Test - public void testDefaultIgnoreInterface() { - try (InetUtils inetUtils = new InetUtils(new InetUtilsProperties())) { - then(inetUtils.ignoreInterface("docker0")).as("docker0 ignored").isFalse(); - } - } - - @Test - public void testSiteLocalAddresses() throws Exception { - InetUtilsProperties properties = new InetUtilsProperties(); - properties.setUseOnlySiteLocalInterfaces(true); - - try (InetUtils utils = new InetUtils(properties)) { - then(utils.isPreferredAddress(InetAddress.getByName("192.168.0.1"))).isTrue(); - then(utils.isPreferredAddress(InetAddress.getByName("5.5.8.1"))).isFalse(); - } - } - - @Test - public void testPreferredNetworksRegex() throws Exception { - InetUtilsProperties properties = new InetUtilsProperties(); - properties.setPreferredNetworks(Arrays.asList("192.168.*", "10.0.*")); - - try (InetUtils utils = new InetUtils(properties)) { - then(utils.isPreferredAddress(InetAddress.getByName("192.168.0.1"))).isTrue(); - then(utils.isPreferredAddress(InetAddress.getByName("5.5.8.1"))).isFalse(); - then(utils.isPreferredAddress(InetAddress.getByName("10.0.10.1"))).isTrue(); - then(utils.isPreferredAddress(InetAddress.getByName("10.255.10.1"))).isFalse(); - } - } - - @Test - public void testPreferredNetworksSimple() throws Exception { - InetUtilsProperties properties = new InetUtilsProperties(); - properties.setPreferredNetworks(Arrays.asList("192", "10.0")); - - try (InetUtils utils = new InetUtils(properties)) { - then(utils.isPreferredAddress(InetAddress.getByName("192.168.0.1"))).isTrue(); - then(utils.isPreferredAddress(InetAddress.getByName("5.5.8.1"))).isFalse(); - then(utils.isPreferredAddress(InetAddress.getByName("10.255.10.1"))).isFalse(); - then(utils.isPreferredAddress(InetAddress.getByName("10.0.10.1"))).isTrue(); - } - } - - @Test - public void testPreferredNetworksListIsEmpty() throws Exception { - InetUtilsProperties properties = new InetUtilsProperties(); - properties.setPreferredNetworks(Collections.emptyList()); - try (InetUtils utils = new InetUtils(properties)) { - then(utils.isPreferredAddress(InetAddress.getByName("192.168.0.1"))).isTrue(); - then(utils.isPreferredAddress(InetAddress.getByName("5.5.8.1"))).isTrue(); - then(utils.isPreferredAddress(InetAddress.getByName("10.255.10.1"))).isTrue(); - then(utils.isPreferredAddress(InetAddress.getByName("10.0.10.1"))).isTrue(); - } - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/SpringFactoryImportSelectorTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/SpringFactoryImportSelectorTests.java deleted file mode 100644 index 2f2a156e..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/SpringFactoryImportSelectorTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.commons.util; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - */ -public class SpringFactoryImportSelectorTests { - - @Test - public void testFindAnnotation() { - MyAnnotationImportSelector selector = new MyAnnotationImportSelector(); - then(selector.getAnnotationClass()).as("annotationClass was wrong").isEqualTo(MyAnnotation.class); - } - - public @interface MyAnnotation { - - } - - public static class MyAnnotationImportSelector extends SpringFactoryImportSelector { - - @Override - protected boolean isEnabled() { - return true; - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java deleted file mode 100644 index 70350322..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierAutoConfigurationTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringBootVersion; -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 static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.cloud.configuration.SpringBootVersionVerifier.stripWildCardFromVersion; - -/** - * @author Marcin Grzejszczak - */ -@SpringBootTest -public class CompatibilityVerifierAutoConfigurationTests { - - @Autowired - MyCompatibilityVerifier myMismatchVerifier; - - @Autowired - CompatibilityVerifierProperties verifierProperties; - - @Test - public void contextLoads() { - then(this.myMismatchVerifier.called).isTrue(); - } - - @Test - public void verifierPropertiesContainsCurrentBootVersion() { - String version = SpringBootVersion.getVersion(); - assertThat(version).isNotBlank(); - - for (String compatibleVersion : verifierProperties.getCompatibleBootVersions()) { - if (version.startsWith(stripWildCardFromVersion(compatibleVersion))) { - // success we found the current boot version in our list of compatible - // versions. - return; - } - } - fail(version + " not found in " + verifierProperties.getCompatibleBootVersions()); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class TestConfiguration { - - @Bean - MyCompatibilityVerifier myMismatchVerifier() { - return new MyCompatibilityVerifier(); - } - - } - - private static class MyCompatibilityVerifier implements CompatibilityVerifier { - - boolean called; - - @Override - public VerificationResult verify() { - this.called = true; - return VerificationResult.compatible(); - } - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java deleted file mode 100644 index 4b8c346c..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierDisabledAutoConfigurationTests.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import org.junit.jupiter.api.Test; - -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 static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -@SpringBootTest(properties = "spring.cloud.compatibility-verifier.enabled=false") -public class CompatibilityVerifierDisabledAutoConfigurationTests { - - @Autowired(required = false) - CompositeCompatibilityVerifier compositeCompatibilityVerifier; - - @Test - public void contextLoads() { - then(this.compositeCompatibilityVerifier).isNull(); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class TestConfiguration { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java deleted file mode 100644 index 95c220c4..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierFailureAutoConfigurationTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import org.assertj.core.api.BDDAssertions; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.NestedExceptionUtils; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -public class CompatibilityVerifierFailureAutoConfigurationTests { - - @Test - public void contextFailsToLoad() { - try { - SpringApplication.run(TestConfiguration.class, - "--spring.cloud.compatibility-verifier.compatible-boot-versions=1.2.x,1.3.x"); - BDDAssertions.fail("should throw exception"); - } - catch (BeanCreationException ex) { - Throwable cause = NestedExceptionUtils.getRootCause(ex); - then(((CompatibilityNotMetException) cause).results).hasSize(1); - } - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class TestConfiguration { - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java deleted file mode 100644 index 865fa7e0..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/CompatibilityVerifierTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.ArrayList; -import java.util.List; - -import org.assertj.core.api.BDDAssertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -@ExtendWith(OutputCaptureExtension.class) -public class CompatibilityVerifierTests { - - @Test - public void should_not_print_the_report_when_no_errors_were_found(CapturedOutput output) { - CompositeCompatibilityVerifier verifier = new CompositeCompatibilityVerifier(new ArrayList<>()); - - verifier.verifyDependencies(); - - then(output).doesNotContain("SPRING CLOUD VERIFICATION FAILED"); - } - - @Test - public void should_print_the_report_when_errors_were_found() { - List list = new ArrayList<>(); - list.add(() -> VerificationResult.notCompatible("Wrong Boot version", "Use Boot version 1.2")); - list.add(() -> VerificationResult.notCompatible("Wrong JDK version", "Use JDK 25")); - CompositeCompatibilityVerifier verifier = new CompositeCompatibilityVerifier(list); - - try { - verifier.verifyDependencies(); - BDDAssertions.fail("should fail"); - } - catch (CompatibilityNotMetException ex) { - then(ex.results).hasSize(2); - } - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SSHContextFactoryTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SSHContextFactoryTests.java deleted file mode 100644 index 6fbcc4c2..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SSHContextFactoryTests.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.Key; -import java.security.KeyStore; -import java.security.cert.Certificate; - -import javax.net.ssl.SSLContext; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; - -import static org.assertj.core.api.Assertions.assertThat; - -public class SSHContextFactoryTests { - - private static final String KEY_STORE_PASSWORD = "test-key-store-password"; - - private static final String KEY_PASSWORD = "test-key-password"; - - private TlsProperties properties; - - @BeforeEach - public void createProperties() { - properties = new TlsProperties(); - - properties.setEnabled(true); - properties.setKeyStore(resourceOf("MyCert.p12")); - properties.setKeyStorePassword(KEY_STORE_PASSWORD); - properties.setKeyPassword(KEY_PASSWORD); - properties.setTrustStore(resourceOf("MyCA.p12")); - properties.setTrustStorePassword(KEY_STORE_PASSWORD); - } - - private Resource resourceOf(String path) { - return new ClassPathResource(path); - } - - @Test - public void createKeyStoreFromProperties() throws GeneralSecurityException, IOException { - SSLContextFactory factory = new SSLContextFactory(properties); - KeyStore store = factory.createKeyStore(); - - Certificate c = store.getCertificate("MyCert"); - assertThat(c).isNotNull(); - - Key key = store.getKey("MyCert", KEY_PASSWORD.toCharArray()); - assertThat(key).isNotNull(); - } - - @Test - public void createTrustStoreFromProperties() throws GeneralSecurityException, IOException { - SSLContextFactory factory = new SSLContextFactory(properties); - KeyStore store = factory.createTrustStore(); - - Certificate c = store.getCertificate("MyCA"); - assertThat(c).isNotNull(); - } - - @Test - public void createSSLContextFromProperties() throws GeneralSecurityException, IOException { - SSLContextFactory factory = new SSLContextFactory(properties); - SSLContext context = factory.createSSLContext(); - assertThat(context).isNotNull(); - } - - interface KeyStoreSupplier { - - KeyStore createKeyStore() throws Exception; - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SleuthPresentVerifierTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SleuthPresentVerifierTests.java deleted file mode 100644 index 675734a7..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SleuthPresentVerifierTests.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import org.assertj.core.api.BDDAssertions; -import org.junit.jupiter.api.Test; - -class SleuthPresentVerifierTests { - - @Test - void should_be_compatible_when_sleuth_is_not_on_the_classpath() { - VerificationResult verify = new SleuthPresentVerifier() { - @Override - boolean sleuthPresent() { - return false; - } - }.verify(); - - BDDAssertions.then(verify.isNotCompatible()).isFalse(); - } - - @Test - void should_not_be_compatible_when_sleuth_is_on_the_classpath() { - VerificationResult verify = new SleuthPresentVerifier() { - @Override - boolean sleuthPresent() { - return true; - } - }.verify(); - - BDDAssertions.then(verify.isNotCompatible()).isTrue(); - - } - -} diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java deleted file mode 100644 index 238152a6..00000000 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/configuration/SpringBootDependencyTests.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.configuration; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -public class SpringBootDependencyTests { - - @Test - public void should_read_concrete_version_from_manifest() { - List acceptedVersions = Collections.singletonList("2.1.3.RELEASE"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.1.3.RELEASE"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isEmpty(); - then(verificationResult.action).isEmpty(); - } - - @Test - public void should_read_concrete_version_from_manifest_and_return_false_when_version_is_not_matched() { - List acceptedVersions = Collections.singletonList("2.1.9.RELEASE"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.1.3.RELEASE"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isNotEmpty(); - then(verificationResult.action).isNotEmpty(); - } - - @Test - public void should_read_concrete_version_from_manifest_and_return_false_when_minor_version_is_not_matched() { - List acceptedVersions = Collections.singletonList("2.1"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.99.3.RELEASE"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isNotEmpty(); - then(verificationResult.action).isNotEmpty(); - } - - @Test - public void should_read_concrete_version_from_manifest_and_match_it_against_minor_version() { - List acceptedVersions = Collections.singletonList("2.1"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.1.3.RELEASE"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isEmpty(); - then(verificationResult.action).isEmpty(); - } - - @Test - public void should_match_against_predicate() { - List acceptedVersions = Collections.singletonList("2.5"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return ""; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - versionVerifier.ACCEPTED_VERSIONS.put("2.5", () -> true); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isEmpty(); - then(verificationResult.action).isEmpty(); - } - - @Test - public void should_fail_to_match_against_predicate_when_none_is_matching() { - List acceptedVersions = Collections.singletonList("2.5"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.1"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isNotEmpty(); - then(verificationResult.action).isNotEmpty(); - } - - @Test - public void should_not_match_when_manifest_has_version_and_not_compatible() { - List acceptedVersions = Collections.singletonList("2.5"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.1"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - AtomicBoolean verifierRun = new AtomicBoolean(false); - versionVerifier.ACCEPTED_VERSIONS.put("2.5", () -> verifierRun.compareAndSet(false, true)); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verifierRun).isFalse(); - then(verificationResult.description).isNotEmpty(); - then(verificationResult.action).isNotEmpty(); - } - - @Test - public void should_match_when_manifest_has_version_and_compatible_list() { - List acceptedVersions = Arrays.asList("2.0", "2.1"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.1"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - AtomicBoolean verifierRun = new AtomicBoolean(false); - versionVerifier.ACCEPTED_VERSIONS.put("2.5", () -> verifierRun.compareAndSet(false, true)); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verifierRun).isFalse(); - then(verificationResult.description).isEmpty(); - then(verificationResult.action).isEmpty(); - } - - @Test - public void should_match_against_current_manifest() { - try { - verifyCurrentVersionFromManifest("3.2"); - verifyCurrentVersionFromManifest("3.2.x"); - } - catch (AssertionError e) { - // if (e.getMessage() != null && e.getMessage().contains("3.3.")) { - // we're likely running a boot 3.3 compatibility test, try 3.3 - // verifyCurrentVersionFromManifest("3.3"); - // verifyCurrentVersionFromManifest("3.3.x"); - // } - // else { - throw e; - // } - } - } - - private void verifyCurrentVersionFromManifest(String version) { - List acceptedVersions = Collections.singletonList(version); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions); - versionVerifier.ACCEPTED_VERSIONS.clear(); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isEmpty(); - then(verificationResult.action).isEmpty(); - } - - @Test - public void should_match_against_current_predicate() { - List acceptedVersions = Collections.singletonList("3.0"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return ""; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - versionVerifier.ACCEPTED_VERSIONS.put("3.0", versionVerifier.is3_2()); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isEmpty(); - then(verificationResult.action).isEmpty(); - } - - @Test - public void should_match_against_current_predicate_with_version_ending_with_x() { - List acceptedVersions = Collections.singletonList("3.0.x"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return ""; - } - }; - versionVerifier.ACCEPTED_VERSIONS.clear(); - versionVerifier.ACCEPTED_VERSIONS.put("3.0", versionVerifier.is3_2()); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isEmpty(); - then(verificationResult.action).isEmpty(); - } - - @Test - public void should_fail_to_match_against_predicate_for_non_current_versions() { - List acceptedVersions = Collections.singletonList("2.1"); - SpringBootVersionVerifier versionVerifier = new SpringBootVersionVerifier(acceptedVersions) { - @Override - String getVersionFromManifest() { - return "2.0"; - } - }; - versionVerifier.ACCEPTED_VERSIONS.remove("2.1"); - - VerificationResult verificationResult = versionVerifier.verify(); - - then(verificationResult.description).isNotEmpty(); - then(verificationResult.action).isNotEmpty(); - } - -} diff --git a/spring-cloud-commons/src/test/resources/MyCA.p12 b/spring-cloud-commons/src/test/resources/MyCA.p12 deleted file mode 100644 index ba068e07f1355b176b39e16629e751bb1a0c8228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 822 zcmXqLVm4x8WHxAGy2Hk))#lOmotKfFaX}N)S(YZIlR)94KztA(#Rinx1Qc4w#K-`o zmLp^s4btEoR$hZh0}BL~$3UA!L@}VPME4x?=}C=$UZ$Pj*nT6B>lG7|x&RZSf&mX3 z2gGtFPF4m3SvJmuHV?*BW)?;*7J-k;ZZf>PtE8AMS7gofcAZ{B6O#d>hn$hq%VYU@ z6%UU55qh+`?OJPOh#jNbwAhCVY_i2~iiElDGFNL2Qx{wQ=;-g~69KY?zkL z4w85%!;~{yaBYp3miBk&yy=;L-fg$uv0ZaTLElsVNwa_J$T@HXdzvk=U%aOM_`@hc zi#r|9Dw_iyzl=?Ex-xzb|;h&F(pNJO1gY#+xtMU;b77 zz0a?Q`OAO5yZ$k|uD`PE)ce!ZTnkiAyc5awI4C^JHmNG$aNSBpmp?5wk9roU{&m{U zIq$^$|Npvs6ZftcJmwr4G^JgQZ)eHXJ-?VUbn?Ub#CVjYlV4OU0?BupcTbdUs*!(I;?`t&oAZyHvDy>u zv*$l}F=pRl{}yFty>M0GV<(0QN)uk6SiQaA@I3yzQ~vr*UNb}S1=H2}FOS`eba=h~ z)~PxtPeEUHgGbF0udljhp77Z6!)xY=mX7wxrMH&vdb8Pb-ZQ19aPjUwPR^*SsbM&5oAe lD>9TbWY@8X6vVlg|EyWCe)igfcY`FI_w1Q8>oq9J0s#1YaCQIy diff --git a/spring-cloud-commons/src/test/resources/MyCert.p12 b/spring-cloud-commons/src/test/resources/MyCert.p12 deleted file mode 100644 index ed30bb999ffb63fb2340d5ebf31a3191c622275e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1736 zcma)6dpOez7~XF;*C9<;2`Rd;--cPJDON61xn-h>+)}C~jV=zqmXzxf(U^^ALRNE` zQp-syr<+`7a!nSpCn@*GIgaz3^XNH$o%6@{e9!m3-~0Xbz8?sopThwJ2%%4+RkkEJ zCQM@hC4dK^{gDvbcMBf-As~B?Srt z`hcXLqdK@1iJjWo`h+%M&vx2(!RU~ug(ex%a1{Y?|l~w9QSM_fe)<6fk?p{I0X66x~)^f#vZ8ak70DTrB>sdB-FoZa*f9v3Z2^ zIp~LRV^NjzP(QL;V=l0KGo#k#1-0u;TcM=D`**3w8bQ}k3vDCUNuKW4a$K_0eK4qR zZj*uOfEjH1?0TcAFSfeTyR?};JE)stlYo({(gPbmu1@dVh_Q_8J~O-dv=?e-fp`kNRDpVS8dLsKYr;~~*n>kF`7BWP{8l3c7ZAB6o+k7B zz1&<7e7(Kzi(|%#iC0eK7_!0evz`T9LT3IW3f)}gPTi%emCiD!oqC+OP;Nl7wbA@6 zFQ+&MCz^mw$?4=bm+CD}zX-SYUHkf}N*>PU>OPZ%1TW6Zv~xr!lXv6z51qK!?Z%~W z$=izUW2quzvG%>aKio76zJ87u)fZ7SYq;5Fy=vc2Nlpto=){%S^bRQLVll66Wsz0o zilNcZbJ$c8p^5K`WKhozBcyohwOzG=2wK6r;o-oi07PrG80gPO7l3*T@eDqqNDl&x+E_*zaaoDljP%$if0#oK{vm+Y;A#cSxP z!y;fYu%obG*csSa(BLPjgU2GZJM>*I+etL;Q0NCK@u!eU~^mzI>!iy<0VgnHos zY_WCxWPtyQRdr2cUqKi?B`W$tV%;uJ+UMwk>)ndx} z8`L?jEQL$G{>?r<7J#l)H74F83W{xXGq=SxW-%oJHp{{TwOT*2xmH!m z1}VC~)qV_ZOoItO=v%~pn6ANfRQVqX^(LQ~H{5!qs3n9b8Ml_73~McyIu#F|=oKNU z2j9KQzmU9>xx4wCM)0_wgDwXavsXUa?B<>8LV4b$I$39G$eL|DSVars$+_KXO^g*s zN5X=*x2Zm9V)=}nw}{6RM?8A({ILtI+uRygr_2IE2&4sanaO_9n({oQh-@ZU@-nMh zg}&2c?1jIzEnoCnYSs}@?+L7j6s@DWg+?h{;SQsgjY zmV^@Tu;a|$9{j2Od#Dkcn?+yo0Fr+>^h1Oo#uE`f1 zbq+O7DN!l{Mz-;8CHJ$kQOQB~cYQ-*nQAVa+`yH4ocnX)Ypa{#{&1e}InVbTtsSia007W&0e=_lZYUlX zg!jRP9(ODO>AD#J00fLCLI7xPC|m&w1Ow$kyg(oX049Q0e@x9;9QG?AIP}u(CND%g zNL5^8ki_Z1zB6X`UVR^kr^@)Za%CW-5U~S{(x=E5SHze8uy8g$xVXbqb9SqI-=~O@ zDZ-raMhb2A?eA;^2tpvt&n0=Tv~MNkS+5cI%2ij=N0R1?xp!A9C1<%SwZ8R?wlAsRHE9}}VzAy?cNnNwj3mGJ ztO-#a(awjYi`pB4QZ3Sa>N48Czr(&Q=D8EzCsp2oRlI1!@Jy_}uMmM35Rjvce76Rn{sAPO-#KSC6*SKdCs(y+|98led18K-}~uxm*ZA&V^CZTUPC=1H?jjd$lM3^4l7AqAr-bX7jb``=cD5 zIMw4W+r|afp*>WF;-%HTL*$lgBv>W;L8@p+@?Kk>K6P2+eo?#rDto48>|$m{!Mv~| zZTB|eUT&A*oNw=a){D@F+($ge__?FdLyRjz*lRDez{=JYg4t z?T~Nt7#sXK7fcsAcfuQGw6HUwEVz3Mz5@Lwa*Hl=t%Lmw?4Z9v8jwg8nK}#Sqj)?@ z+BHxVUHV)dfenu1h-K@``b@EO8Sw3V_&_T`&^p}|BI4Vx{pNX5ssPQYGTg0~$E>ZZ zxZ>hl6L&y&)hn3)$)D@C!aF_SboqQait#%U_4yu{^2MAuH>-}q#;M{-yd1sEc}}h! z!#R{Sd)}9cwF7759L{M(#|V;PRF~2@PreCz|3njzoAGE%6!otuPeTYZZ^g%Z#3eRn zfshtdY)|?AhZHX!nd2(_w=WHNxPONdAds*OoAny-|6E(ZSi8K@(5{zd?hjA#*fa0A5i#N z%rmW5VdEX0hc-bhk02~eAijXoC+$e9-XlfzUF})OwsJnHR0sF zfatDpl0ix+$9?M5TCe{>$N+shXTFzo#jerT+q%)Oc~h}D?gBV^5n;FCWxdgBw&;N7 zN{wjk`x>K^_Es|RoSRFxBcx{L(Kp#025&_laa2I;_fiG}I zpoS4qhz7VB4~TLti;qdy^LItOQ4{U3yu8ra=~pg66Esfh%l#1~{PL5Y`|o&!I4G*4 zwEzIN05p;9E}96kEo1`$K_Kvn{YyP)E+|Ys-YkBX3kc*q4onYaPBaY4W($TQLAKV) z+-Srv;6OsG@mM@gnG4PNi`kK2Loa-&vH%+S3*krvCeQ=x>lKE@d-?hPPsND@+xmLp zm62%PUn({v+#csDZjB2J#s#8J3vwx|qgBybDk^9VRb{8&sDVEJU;O_KLIk4zX~OZB zU?T!g0MJAr97F^H0j<}O_wE`aZ!*0iCzaqH1hqf0+fr9?67F{Ebpew?$mhB&83hK4 zbBl&033s?#ah`4>B<<81CH3DC00DJZ)gi+s=F+}Lxi@H@0y83l;?Cqd`eXQ#9@lj+ z*#y&cb7JoMR$hRii5{jpak1L`W0@XCEZzJ8f+a?)$YvmD!kR3%;Q7;6H~C=qL9xcN zE25LR2KygI@^3lUo~-IaK@~>Y$IDilLxP+&>l4NrZp_yWTXyE$WaCT@$hiIBImvxD zhhd8Uq1WXUQzT+lYPkC>XO}>?TQ5vITGGgjB1B6T{_EE0gL2hVwBV}8_iuk9*`Z*d znazx?DX@+`hz$q;mPnw*(5H^Kc#0c*63j1Km`l&8nC&gig1yvy+y)X=VB!C1;_)RN zn+OCro@z?g7#s%qHRrwC^N|V3zjS?-I9tyi;S%$8bY$=6&e`}fp~OZ z|EKLrH4p2BRMUw)`_g&D+e3dF>4S>M{md%)*Au18*)bhS+QV7_<))PO@Rl^c)wbtG z4`Se;rC}V&=!-~igc?GjgpvaLkU=Y6o=rx%ZUo5@86BYt%_zS7>8*CS==nH7KCXF7 z&o@r*mXjiJChyy>&-+zlxc9rzJuA5g3ev~OryKWVMcd_O(`6AD4W$M$SEiOftl^v?Ht^0YZuAWk}0Qx X87oqp`%q!o8#z_2ZOluhie~)>Rnq1* diff --git a/spring-cloud-context-integration-tests/pom.xml b/spring-cloud-context-integration-tests/pom.xml deleted file mode 100644 index 2dc7d983..00000000 --- a/spring-cloud-context-integration-tests/pom.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - spring-cloud-context-integration-tests - jar - spring-cloud-context-integration-tests - Spring Cloud Context Integration Tests - - - org.springframework.cloud - spring-cloud-context - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-aop - - - org.springframework.integration - spring-integration-jmx - - - javax.annotation - javax.annotation-api - - - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-data-jpa - test - - - com.sun.activation - jakarta.activation - - - - - org.hsqldb - hsqldb - test - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.junit.platform - junit-platform-launcher - test - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - - diff --git a/spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/JdbcConfigurationTests.java b/spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/JdbcConfigurationTests.java deleted file mode 100644 index f33294f1..00000000 --- a/spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/JdbcConfigurationTests.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.integration; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.context.annotation.Import; - -/** - * @author Dave Syer - * - */ -public class JdbcConfigurationTests { - - @Test - public void schemaApplied() { - new SpringApplicationBuilder(BrokenApplication.class).web(WebApplicationType.NONE) - .run("--spring.datasource.initialization-mode=always").close(); - } - - @SpringBootConfiguration - @EnableConfigurationProperties(DataSourceProperties.class) - @Import({ DataSourceAutoConfiguration.class, RefreshAutoConfiguration.class }) - protected static class BrokenApplication { - - public static void main(String[] args) { - new SpringApplicationBuilder(BrokenApplication.class).web(WebApplicationType.NONE).run(args); - } - - } - -} diff --git a/spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/RefreshScopeIntegrationTests.java b/spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/RefreshScopeIntegrationTests.java deleted file mode 100644 index 57cc81f3..00000000 --- a/spring-cloud-context-integration-tests/src/test/java/org/springframework/cloud/context/integration/RefreshScopeIntegrationTests.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.integration; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.Advised; -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.integration.RefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -@SuppressWarnings("Duplicates") -public class RefreshScopeIntegrationTests { - - @Autowired - private Service service; - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @BeforeEach - public void init() { - then(ExampleService.getInitCount()).isEqualTo(1); - ExampleService.reset(); - } - - @AfterEach - public void close() { - ExampleService.reset(); - } - - @Test - @DirtiesContext - public void testSimpleProperties() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(this.service instanceof Advised).isTrue(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...but don't refresh, so the bean stays the same: - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(ExampleService.getInitCount()).isEqualTo(0); - then(ExampleService.getDestroyCount()).isEqualTo(0); - } - - @Test - @DirtiesContext - public void testRefresh() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - String id1 = this.service.toString(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.scope.refreshAll(); - String id2 = this.service.toString(); - then(this.service.getMessage()).isEqualTo("Foo"); - then(ExampleService.getInitCount()).isEqualTo(1); - then(ExampleService.getDestroyCount()).isEqualTo(1); - then(id2).isNotSameAs(id1); - then(ExampleService.event).isNotNull(); - then(ExampleService.event.getName()).isEqualTo(RefreshScopeRefreshedEvent.DEFAULT_NAME); - } - - @Test - @DirtiesContext - public void testRefreshBean() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - String id1 = this.service.toString(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.scope.refresh("service"); - String id2 = this.service.toString(); - then(this.service.getMessage()).isEqualTo("Foo"); - then(this.service.getMessage()).isEqualTo("Foo"); - then(ExampleService.getInitCount()).isEqualTo(1); - then(ExampleService.getDestroyCount()).isEqualTo(1); - then(id2).isNotSameAs(id1); - then(ExampleService.event).isNotNull(); - then(ExampleService.event.getName()).isEqualTo(ScopedProxyUtils.getTargetBeanName("service")); - } - - // see gh-349 - @Test - @DirtiesContext - public void testCheckedException() { - Assertions.assertThrows(ServiceException.class, () -> this.service.throwsException()); - } - - public interface Service { - - String getMessage(); - - String throwsException() throws ServiceException; - - } - - public static class ExampleService - implements Service, InitializingBean, DisposableBean, ApplicationListener { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private volatile static int initCount = 0; - - private volatile static int destroyCount = 0; - - private volatile static RefreshScopeRefreshedEvent event; - - private String message = null; - - private volatile long delay = 0; - - public static void reset() { - initCount = 0; - destroyCount = 0; - event = null; - } - - public static int getInitCount() { - return initCount; - } - - public static int getDestroyCount() { - return destroyCount; - } - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() { - logger.debug("Initializing message: " + this.message); - initCount++; - } - - @Override - public void destroy() { - logger.debug("Destroying message: " + this.message); - destroyCount++; - this.message = null; - } - - @Override - public String getMessage() { - logger.debug("Getting message: " + this.message); - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + message); - this.message = message; - } - - @Override - public String throwsException() throws ServiceException { - throw new ServiceException(); - } - - @Override - public void onApplicationEvent(RefreshScopeRefreshedEvent e) { - event = e; - } - - } - - @SuppressWarnings("serial") - public static class ServiceException extends Exception { - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TestProperties.class) - @EnableAutoConfiguration - protected static class TestConfiguration { - - @Autowired - private TestProperties properties; - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage(this.properties.getMessage()); - service.setDelay(this.properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - @ManagedAttribute - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context-integration-tests/src/test/resources/application.properties b/spring-cloud-context-integration-tests/src/test/resources/application.properties deleted file mode 100644 index 9246b588..00000000 --- a/spring-cloud-context-integration-tests/src/test/resources/application.properties +++ /dev/null @@ -1,8 +0,0 @@ -message:Hello scope! -delay:0 -debug:true -#logging.level.org.springframework.web: DEBUG -#logging.level.org.springframework.context.annotation: DEBUG -logging.level.org.hibernate=ERROR -logging.level.com.zaxxer.hikari=ERROR -spring.datasource.initialization-mode=always diff --git a/spring-cloud-context-integration-tests/src/test/resources/bootstrap.properties b/spring-cloud-context-integration-tests/src/test/resources/bootstrap.properties deleted file mode 100644 index 90319f84..00000000 --- a/spring-cloud-context-integration-tests/src/test/resources/bootstrap.properties +++ /dev/null @@ -1 +0,0 @@ -info.name:child diff --git a/spring-cloud-context-integration-tests/src/test/resources/data.sql b/spring-cloud-context-integration-tests/src/test/resources/data.sql deleted file mode 100644 index 29d1d4e8..00000000 --- a/spring-cloud-context-integration-tests/src/test/resources/data.sql +++ /dev/null @@ -1,7 +0,0 @@ -DELETE FROM foos; -INSERT INTO foos (value) -VALUES - ('ITEM1') -,('ITEM2') -,('ITEM3') -; diff --git a/spring-cloud-context-integration-tests/src/test/resources/schema.sql b/spring-cloud-context-integration-tests/src/test/resources/schema.sql deleted file mode 100644 index 337285d3..00000000 --- a/spring-cloud-context-integration-tests/src/test/resources/schema.sql +++ /dev/null @@ -1,4 +0,0 @@ -create table if not exists foos ( - id INTEGER IDENTITY PRIMARY KEY, - value VARCHAR(30) -); diff --git a/spring-cloud-context-webflux-integration-tests/pom.xml b/spring-cloud-context-webflux-integration-tests/pom.xml deleted file mode 100644 index 000768e3..00000000 --- a/spring-cloud-context-webflux-integration-tests/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - spring-cloud-context-webflux-integration-tests - jar - spring-cloud-context-webflux-integration-tests - Spring Cloud Context Webflux Integration Tests - - - org.springframework.cloud - spring-cloud-context - - - org.springframework.boot - spring-boot-starter-actuator - - - org.springframework.boot - spring-boot-starter-webflux - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.junit.platform - junit-platform-launcher - test - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - - org.apache.maven.plugins - maven-deploy-plugin - - true - - - - - diff --git a/spring-cloud-context-webflux-integration-tests/src/test/java/org/springframework/cloud/context/integration/webflux/WebfluxRefreshEndpointIntegrationTests.java b/spring-cloud-context-webflux-integration-tests/src/test/java/org/springframework/cloud/context/integration/webflux/WebfluxRefreshEndpointIntegrationTests.java deleted file mode 100644 index 7d890d90..00000000 --- a/spring-cloud-context-webflux-integration-tests/src/test/java/org/springframework/cloud/context/integration/webflux/WebfluxRefreshEndpointIntegrationTests.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.integration.webflux; - -import org.junit.jupiter.api.Test; - -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.test.web.server.LocalServerPort; -import org.springframework.context.annotation.Configuration; -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 static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Dave Syer - * - */ -@SpringBootTest(classes = WebfluxRefreshEndpointIntegrationTests.ClientApp.class, - properties = { "management.endpoints.web.exposure.include=*" }, webEnvironment = RANDOM_PORT) -public class WebfluxRefreshEndpointIntegrationTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - @LocalServerPort - private int port; - - @Test - public void webAccess() throws Exception { - TestRestTemplate template = new TestRestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity request = new HttpEntity(headers); - ResponseEntity entity = template.postForEntity("http://localhost:" + this.port + BASE_PATH + "/refresh", - request, String.class); - assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK); - } - - @Configuration - @EnableAutoConfiguration - protected static class ClientApp { - - } - -} diff --git a/spring-cloud-context-webflux-integration-tests/src/test/resources/application.properties b/spring-cloud-context-webflux-integration-tests/src/test/resources/application.properties deleted file mode 100644 index 10813755..00000000 --- a/spring-cloud-context-webflux-integration-tests/src/test/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -spring.main.web-application-type=REACTIVE diff --git a/spring-cloud-context-webflux-integration-tests/src/test/resources/bootstrap.properties b/spring-cloud-context-webflux-integration-tests/src/test/resources/bootstrap.properties deleted file mode 100644 index 90319f84..00000000 --- a/spring-cloud-context-webflux-integration-tests/src/test/resources/bootstrap.properties +++ /dev/null @@ -1 +0,0 @@ -info.name:child diff --git a/spring-cloud-context/README.md b/spring-cloud-context/README.md deleted file mode 100644 index 9177f3ee..00000000 --- a/spring-cloud-context/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Spring Cloud Context - -Utilities and special services for the `ApplicationContext` of a Spring Cloud application (bootstrap context, encryption, refresh scope and environment endpoints). \ No newline at end of file diff --git a/spring-cloud-context/eclipse/eclipse-code-formatter.xml b/spring-cloud-context/eclipse/eclipse-code-formatter.xml deleted file mode 100644 index 5cbf769b..00000000 --- a/spring-cloud-context/eclipse/eclipse-code-formatter.xml +++ /dev/null @@ -1,754 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-cloud-context/eclipse/org.eclipse.jdt.core.prefs b/spring-cloud-context/eclipse/org.eclipse.jdt.core.prefs deleted file mode 100644 index 63d59166..00000000 --- a/spring-cloud-context/eclipse/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,389 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=8 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/spring-cloud-context/eclipse/org.eclipse.jdt.ui.prefs b/spring-cloud-context/eclipse/org.eclipse.jdt.ui.prefs deleted file mode 100644 index badcb453..00000000 --- a/spring-cloud-context/eclipse/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,125 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=false -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=false -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=false -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=true -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=false -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=true -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Spring Cloud Cleanup Conventions -cleanup_settings_version=2 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_Spring Cloud Java Conventions -formatter_settings_version=12 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=false -org.eclipse.jdt.ui.ignorelowercasenames=true -org.eclipse.jdt.ui.importorder=java;javax;org;com;\#; -org.eclipse.jdt.ui.javadoc=true -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=9999 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=true -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml deleted file mode 100644 index fd9b5636..00000000 --- a/spring-cloud-context/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - spring-cloud-context - jar - Spring Cloud Context - Spring Cloud Context - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-actuator - true - - - - org.apache.logging.log4j - log4j-to-slf4j - - - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.boot - spring-boot-starter-aop - true - - - org.springframework.security - spring-security-crypto - - - org.springframework.security - spring-security-rsa - true - - - org.springframework.integration - spring-integration-jmx - true - - - javax.annotation - javax.annotation-api - - - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.cloud - spring-cloud-test-support - test - - - org.junit.platform - junit-platform-launcher - test - - - diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebinderAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebinderAutoConfiguration.java deleted file mode 100644 index 94dc8b4e..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebinderAutoConfiguration.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import org.springframework.beans.factory.SmartInitializingSingleton; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.SearchStrategy; -import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; -import org.springframework.cloud.context.properties.ConfigurationPropertiesBeans; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Auto-configuration for {@link ConfigurationPropertiesRebinder}. - * - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnBean(ConfigurationPropertiesBindingPostProcessor.class) -public class ConfigurationPropertiesRebinderAutoConfiguration - implements ApplicationContextAware, SmartInitializingSingleton { - - private ApplicationContext context; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) { - this.context = applicationContext; - } - - @Bean - @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) - public static ConfigurationPropertiesBeans configurationPropertiesBeans() { - return new ConfigurationPropertiesBeans(); - } - - @Bean - @ConditionalOnMissingBean(search = SearchStrategy.CURRENT) - public ConfigurationPropertiesRebinder configurationPropertiesRebinder(ConfigurationPropertiesBeans beans) { - ConfigurationPropertiesRebinder rebinder = new ConfigurationPropertiesRebinder(beans); - return rebinder; - } - - @Override - public void afterSingletonsInstantiated() { - // After all beans are initialized explicitly rebind beans from the parent - // so that changes during the initialization of the current context are - // reflected. In particular this can be important when low level services like - // decryption are bootstrapped in the parent, but need to change their - // configuration before the child context is processed. - if (this.context.getParent() != null) { - // TODO: make this optional? (E.g. when creating child contexts that prefer to - // be isolated.) - ConfigurationPropertiesRebinder rebinder = this.context.getBean(ConfigurationPropertiesRebinder.class); - for (String name : this.context.getParent().getBeanDefinitionNames()) { - rebinder.rebind(name); - } - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java deleted file mode 100644 index c7e64d27..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; - -/** - * Auto-configuration for some MVC endpoints governing the application context lifecycle. - * Provides restart, pause, resume, refresh (environment), and environment update - * endpoints. - * - * @author Dave Syer - * - */ -@Configuration(proxyBeanMethods = false) -@AutoConfigureAfter(WebMvcAutoConfiguration.class) -public class LifecycleMvcEndpointAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public EnvironmentManager environmentManager(ConfigurableEnvironment environment) { - return new EnvironmentManager(environment); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java deleted file mode 100644 index ecc7eb1f..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanDefinitionHolder; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -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.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.cloud.context.refresh.ConfigDataContextRefresher; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.cloud.context.refresh.LegacyContextRefresher; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.cloud.endpoint.event.RefreshEventListener; -import org.springframework.cloud.logging.LoggingRebinder; -import org.springframework.cloud.util.ConditionalOnBootstrapDisabled; -import org.springframework.cloud.util.ConditionalOnBootstrapEnabled; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.EnvironmentAware; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.weaving.LoadTimeWeaverAware; -import org.springframework.core.env.Environment; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.core.style.ToStringCreator; -import org.springframework.instrument.classloading.LoadTimeWeaver; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -/** - * Autoconfiguration for the refresh scope and associated features to do with changes in - * the Environment (e.g. rebinding logger levels). - * - * @author Dave Syer - * @author Venil Noronha - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(RefreshScope.class) -@ConditionalOnProperty(name = RefreshAutoConfiguration.REFRESH_SCOPE_ENABLED, matchIfMissing = true) -@AutoConfigureBefore(HibernateJpaAutoConfiguration.class) -@EnableConfigurationProperties(RefreshAutoConfiguration.RefreshProperties.class) -public class RefreshAutoConfiguration { - - /** - * Name of the refresh scope name. - */ - public static final String REFRESH_SCOPE_NAME = "refresh"; - - /** - * Name of the prefix for refresh scope. - */ - public static final String REFRESH_SCOPE_PREFIX = "spring.cloud.refresh"; - - /** - * Name of the enabled prefix for refresh scope. - */ - public static final String REFRESH_SCOPE_ENABLED = REFRESH_SCOPE_PREFIX + ".enabled"; - - @Bean - @ConditionalOnMissingBean(RefreshScope.class) - public static RefreshScope refreshScope() { - return new RefreshScope(); - } - - @Bean - @ConditionalOnMissingBean - public static LoggingRebinder loggingRebinder() { - return new LoggingRebinder(); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBootstrapEnabled - public LegacyContextRefresher legacyContextRefresher(ConfigurableApplicationContext context, RefreshScope scope, - RefreshProperties properties) { - return new LegacyContextRefresher(context, scope, properties); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnBootstrapDisabled - public ConfigDataContextRefresher configDataContextRefresher(ConfigurableApplicationContext context, - RefreshScope scope, RefreshProperties properties) { - return new ConfigDataContextRefresher(context, scope, properties); - } - - @Bean - public RefreshEventListener refreshEventListener(ContextRefresher contextRefresher) { - return new RefreshEventListener(contextRefresher); - } - - @ConfigurationProperties("spring.cloud.refresh") - public static class RefreshProperties { - - /** - * Additional property sources to retain during a refresh. Typically only system - * property sources are retained. This property allows property sources, such as - * property sources created by EnvironmentPostProcessors to be retained as well. - */ - private List additionalPropertySourcesToRetain; - - public List getAdditionalPropertySourcesToRetain() { - return this.additionalPropertySourcesToRetain; - } - - public void setAdditionalPropertySourcesToRetain(List additionalPropertySourcesToRetain) { - this.additionalPropertySourcesToRetain = additionalPropertySourcesToRetain; - } - - @Override - public String toString() { - return new ToStringCreator(this) - .append("additionalPropertySourcesToRetain", additionalPropertySourcesToRetain).toString(); - - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(name = "javax.persistence.EntityManagerFactory") - protected static class JpaInvokerConfiguration implements LoadTimeWeaverAware, InitializingBean { - - @Autowired - private ListableBeanFactory beanFactory; - - @Override - public void afterPropertiesSet() { - String cls = "org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker"; - if (this.beanFactory.containsBean(cls)) { - this.beanFactory.getBean(cls); - } - } - - @Override - public void setLoadTimeWeaver(LoadTimeWeaver ltw) { - } - - } - - @Component - protected static class RefreshScopeBeanDefinitionEnhancer - implements BeanDefinitionRegistryPostProcessor, EnvironmentAware { - - private Environment environment; - - private boolean bound = false; - - /** - * Class names for beans to post process into refresh scope. Useful when you don't - * control the bean definition (e.g. it came from auto-configuration). - */ - private Set refreshables = new HashSet<>(); - - public Set getRefreshable() { - return this.refreshables; - } - - public void setRefreshable(Set refreshables) { - if (this.refreshables != refreshables) { - this.refreshables.clear(); - this.refreshables.addAll(refreshables); - } - } - - public void setExtraRefreshable(Set refreshables) { - this.refreshables.addAll(refreshables); - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - bindEnvironmentIfNeeded(registry); - for (String name : registry.getBeanDefinitionNames()) { - BeanDefinition definition = registry.getBeanDefinition(name); - if (isApplicable(registry, name, definition)) { - BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, name); - BeanDefinitionHolder proxy = ScopedProxyUtils.createScopedProxy(holder, registry, true); - definition.setScope("refresh"); - if (registry.containsBeanDefinition(proxy.getBeanName())) { - registry.removeBeanDefinition(proxy.getBeanName()); - } - registry.registerBeanDefinition(proxy.getBeanName(), proxy.getBeanDefinition()); - } - } - } - - private boolean isApplicable(BeanDefinitionRegistry registry, String name, BeanDefinition definition) { - String scope = definition.getScope(); - if (REFRESH_SCOPE_NAME.equals(scope)) { - // Already refresh scoped - return false; - } - String type = definition.getBeanClassName(); - if (!StringUtils.hasText(type) && registry instanceof BeanFactory) { - Class cls = ((BeanFactory) registry).getType(name); - if (cls != null) { - type = cls.getName(); - } - } - if (type != null) { - return this.refreshables.contains(type); - } - return false; - } - - private void bindEnvironmentIfNeeded(BeanDefinitionRegistry registry) { - if (!this.bound) { // only bind once - if (this.environment == null) { - this.environment = new StandardEnvironment(); - } - Binder.get(this.environment).bind("spring.cloud.refresh", Bindable.ofInstance(this)); - this.bound = true; - } - } - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java deleted file mode 100644 index 893879e0..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.health.Health; -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.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.cloud.context.restart.PauseHandler; -import org.springframework.cloud.context.restart.RestartEndpoint; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.cloud.endpoint.RefreshEndpoint; -import org.springframework.cloud.health.RefreshScopeHealthIndicator; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.integration.core.Pausable; -import org.springframework.integration.monitor.IntegrationMBeanExporter; - -/** - * @author Dave Syer - * @author Spencer Gibb - * @author Venil Noronha - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ EndpointAutoConfiguration.class, Health.class }) -@AutoConfigureAfter({ LifecycleMvcEndpointAutoConfiguration.class, RefreshAutoConfiguration.class }) -@Import({ RestartEndpointWithIntegrationConfiguration.class, RestartEndpointWithoutIntegrationConfiguration.class, - PauseResumeEndpointsConfiguration.class }) -public class RefreshEndpointAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - @ConditionalOnEnabledHealthIndicator("refresh") - RefreshScopeHealthIndicator refreshScopeHealthIndicator(ObjectProvider scope, - ConfigurationPropertiesRebinder rebinder) { - return new RefreshScopeHealthIndicator(scope, rebinder); - } - - @Configuration(proxyBeanMethods = false) - protected static class RefreshEndpointConfiguration { - - @Bean - @ConditionalOnBean(ContextRefresher.class) - @ConditionalOnAvailableEndpoint - @ConditionalOnMissingBean - public RefreshEndpoint refreshEndpoint(ContextRefresher contextRefresher) { - return new RefreshEndpoint(contextRefresher); - } - - } - -} - -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(IntegrationMBeanExporter.class) -class RestartEndpointWithIntegrationConfiguration { - - private IntegrationMBeanExporter exporter; - - RestartEndpointWithIntegrationConfiguration(@Autowired(required = false) IntegrationMBeanExporter exporter) { - this.exporter = exporter; - } - - @Bean - public PauseHandler integrationPauseHandler(ObjectProvider pausables) { - return new IntegrationPauseHandler(pausables.orderedStream().collect(Collectors.toList())); - } - - @Bean - @ConditionalOnAvailableEndpoint - @ConditionalOnMissingBean - public RestartEndpoint restartEndpoint() { - RestartEndpoint endpoint = new RestartEndpoint(); - if (this.exporter != null) { - endpoint.setIntegrationMBeanExporter(this.exporter); - } - return endpoint; - } - - private class IntegrationPauseHandler implements PauseHandler { - - private List pausables = new ArrayList<>(); - - IntegrationPauseHandler(List pausables) { - this.pausables.addAll(pausables); - } - - @Override - public void pause() { - for (Pausable pausable : this.pausables) { - pausable.pause(); - } - } - - @Override - public void resume() { - for (int i = this.pausables.size(); i-- > 0;) { - this.pausables.get(i).resume(); - } - } - - } - -} - -@Configuration(proxyBeanMethods = false) -@ConditionalOnMissingClass("org.springframework.integration.monitor.IntegrationMBeanExporter") -class RestartEndpointWithoutIntegrationConfiguration { - - @Bean - @ConditionalOnAvailableEndpoint - @ConditionalOnMissingBean - public RestartEndpoint restartEndpointWithoutIntegration() { - return new RestartEndpoint(); - } - -} - -@Configuration(proxyBeanMethods = false) -class PauseResumeEndpointsConfiguration { - - @Bean - @ConditionalOnBean(RestartEndpoint.class) - @ConditionalOnMissingBean - @ConditionalOnAvailableEndpoint - public RestartEndpoint.PauseEndpoint pauseEndpoint(RestartEndpoint restartEndpoint) { - return restartEndpoint.getPauseEndpoint(); - } - - @Bean - @ConditionalOnBean(RestartEndpoint.class) - @ConditionalOnMissingBean - @ConditionalOnAvailableEndpoint - public RestartEndpoint.ResumeEndpoint resumeEndpoint(RestartEndpoint restartEndpoint) { - return restartEndpoint.getResumeEndpoint(); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/WritableEnvironmentEndpointAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/WritableEnvironmentEndpointAutoConfiguration.java deleted file mode 100644 index 3efcfa28..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/WritableEnvironmentEndpointAutoConfiguration.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint; -import org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.env.EnvironmentEndpointProperties; -import org.springframework.boot.actuate.endpoint.SanitizingFunction; -import org.springframework.boot.actuate.env.EnvironmentEndpoint; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -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.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.cloud.context.environment.WritableEnvironmentEndpoint; -import org.springframework.cloud.context.environment.WritableEnvironmentEndpointWebExtension; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for the - * {@link WritableEnvironmentEndpoint}. - * - * @author Stephane Nicoll - * @since 2.0.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ EnvironmentEndpoint.class, EnvironmentEndpointProperties.class }) -@ConditionalOnBean(EnvironmentManager.class) -@AutoConfigureBefore(EnvironmentEndpointAutoConfiguration.class) -@AutoConfigureAfter(LifecycleMvcEndpointAutoConfiguration.class) -@EnableConfigurationProperties({ EnvironmentEndpointProperties.class }) -@ConditionalOnProperty("management.endpoint.env.post.enabled") -public class WritableEnvironmentEndpointAutoConfiguration { - - private final EnvironmentEndpointProperties properties; - - public WritableEnvironmentEndpointAutoConfiguration(EnvironmentEndpointProperties properties) { - this.properties = properties; - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnAvailableEndpoint - public WritableEnvironmentEndpoint writableEnvironmentEndpoint(Environment environment, - ObjectProvider sanitizingFunctions) { - return new WritableEnvironmentEndpoint(environment, sanitizingFunctions, this.properties.getShowValues()); - } - - @Bean - @ConditionalOnAvailableEndpoint - public WritableEnvironmentEndpointWebExtension writableEnvironmentEndpointWebExtension( - WritableEnvironmentEndpoint endpoint, EnvironmentManager environment) { - return new WritableEnvironmentEndpointWebExtension(endpoint, environment, this.properties.getShowValues(), - this.properties.getRoles()); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java deleted file mode 100644 index 3a614181..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.boot.Banner.Mode; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.ParentContextApplicationContextInitializer; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; -import org.springframework.boot.context.event.ApplicationFailedEvent; -import org.springframework.boot.context.logging.LoggingApplicationListener; -import org.springframework.boot.env.OriginTrackedMapPropertySource; -import org.springframework.boot.origin.Origin; -import org.springframework.boot.origin.OriginLookup; -import org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer; -import org.springframework.cloud.bootstrap.support.OriginTrackedCompositePropertySource; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.event.SmartApplicationListener; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.annotation.Order; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.PropertySource.StubPropertySource; -import org.springframework.core.env.SystemEnvironmentPropertySource; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.util.PropertyUtils.bootstrapEnabled; -import static org.springframework.cloud.util.PropertyUtils.useLegacyProcessing; - -/** - * A listener that prepares a SpringApplication (e.g. populating its Environment) by - * delegating to {@link ApplicationContextInitializer} beans in a separate bootstrap - * context. The bootstrap context is a SpringApplication created from sources defined in - * spring.factories as {@link BootstrapConfiguration}, and initialized with external - * config taken from "bootstrap.properties" (or yml), instead of the normal - * "application.properties". - * - * @author Dave Syer - * - */ -public class BootstrapApplicationListener implements ApplicationListener, Ordered { - - /** - * Property source name for bootstrap. - */ - public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap"; - - /** - * The default order for this listener. - */ - public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 5; - - /** - * The name of the default properties. - */ - public static final String DEFAULT_PROPERTIES = "springCloudDefaultProperties"; - - private int order = DEFAULT_ORDER; - - @Override - public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { - ConfigurableEnvironment environment = event.getEnvironment(); - if (!bootstrapEnabled(environment) && !useLegacyProcessing(environment)) { - return; - } - // don't listen to events in a bootstrap context - if (environment.getPropertySources().contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - return; - } - ConfigurableApplicationContext context = null; - String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}"); - for (ApplicationContextInitializer initializer : event.getSpringApplication().getInitializers()) { - if (initializer instanceof ParentContextApplicationContextInitializer) { - context = findBootstrapContext((ParentContextApplicationContextInitializer) initializer, configName); - } - } - if (context == null) { - context = bootstrapServiceContext(environment, event.getSpringApplication(), configName); - event.getSpringApplication().addListeners(new CloseContextOnFailureApplicationListener(context)); - } - - apply(context, event.getSpringApplication(), environment); - } - - private ConfigurableApplicationContext findBootstrapContext(ParentContextApplicationContextInitializer initializer, - String configName) { - Field field = ReflectionUtils.findField(ParentContextApplicationContextInitializer.class, "parent"); - ReflectionUtils.makeAccessible(field); - ConfigurableApplicationContext parent = safeCast(ConfigurableApplicationContext.class, - ReflectionUtils.getField(field, initializer)); - if (parent != null && !configName.equals(parent.getId())) { - parent = safeCast(ConfigurableApplicationContext.class, parent.getParent()); - } - return parent; - } - - private T safeCast(Class type, Object object) { - try { - return type.cast(object); - } - catch (ClassCastException e) { - return null; - } - } - - private ConfigurableApplicationContext bootstrapServiceContext(ConfigurableEnvironment environment, - final SpringApplication application, String configName) { - ConfigurableEnvironment bootstrapEnvironment = new AbstractEnvironment() { - }; - MutablePropertySources bootstrapProperties = bootstrapEnvironment.getPropertySources(); - String configLocation = environment.resolvePlaceholders("${spring.cloud.bootstrap.location:}"); - String configAdditionalLocation = environment - .resolvePlaceholders("${spring.cloud.bootstrap.additional-location:}"); - Map bootstrapMap = new HashMap<>(); - bootstrapMap.put("spring.config.name", configName); - // if an app (or test) uses spring.main.web-application-type=reactive, bootstrap - // will fail - // force the environment to use none, because if though it is set below in the - // builder - // the environment overrides it - bootstrapMap.put("spring.main.web-application-type", "none"); - if (StringUtils.hasText(configLocation)) { - bootstrapMap.put("spring.config.location", configLocation); - } - if (StringUtils.hasText(configAdditionalLocation)) { - bootstrapMap.put("spring.config.additional-location", configAdditionalLocation); - } - bootstrapProperties.addFirst(new MapPropertySource(BOOTSTRAP_PROPERTY_SOURCE_NAME, bootstrapMap)); - for (PropertySource source : environment.getPropertySources()) { - if (source instanceof StubPropertySource) { - continue; - } - bootstrapProperties.addLast(source); - } - // TODO: is it possible or sensible to share a ResourceLoader? - SpringApplicationBuilder builder = new SpringApplicationBuilder().profiles(environment.getActiveProfiles()) - .bannerMode(Mode.OFF).environment(bootstrapEnvironment) - // Don't use the default properties in this builder - .registerShutdownHook(false).logStartupInfo(false).web(WebApplicationType.NONE); - final SpringApplication builderApplication = builder.application(); - if (builderApplication.getMainApplicationClass() == null) { - // gh_425: - // SpringApplication cannot deduce the MainApplicationClass here - // if it is booted from SpringBootServletInitializer due to the - // absense of the "main" method in stackTraces. - // But luckily this method's second parameter "application" here - // carries the real MainApplicationClass which has been explicitly - // set by SpringBootServletInitializer itself already. - builder.main(application.getMainApplicationClass()); - } - if (environment.getPropertySources().contains("refreshArgs")) { - // If we are doing a context refresh, really we only want to refresh the - // Environment, and there are some toxic listeners (like the - // LoggingApplicationListener) that affect global static state, so we need a - // way to switch those off. - builderApplication.setListeners(filterListeners(builderApplication.getListeners())); - } - builder.sources(BootstrapImportSelectorConfiguration.class); - final ConfigurableApplicationContext context = builder.run(); - // gh-214 using spring.application.name=bootstrap to set the context id via - // `ContextIdApplicationContextInitializer` prevents apps from getting the actual - // spring.application.name - // during the bootstrap phase. - context.setId("bootstrap"); - // Make the bootstrap context a parent of the app context - addAncestorInitializer(application, context); - // It only has properties in it now that we don't want in the parent so remove - // it (and it will be added back later) - bootstrapProperties.remove(BOOTSTRAP_PROPERTY_SOURCE_NAME); - mergeDefaultProperties(environment.getPropertySources(), bootstrapProperties); - return context; - } - - private Collection> filterListeners(Set> listeners) { - Set> result = new LinkedHashSet<>(); - for (ApplicationListener listener : listeners) { - if (!(listener instanceof LoggingApplicationListener) - && !(listener instanceof LoggingSystemShutdownListener)) { - result.add(listener); - } - } - return result; - } - - private void mergeDefaultProperties(MutablePropertySources environment, MutablePropertySources bootstrap) { - String name = DEFAULT_PROPERTIES; - if (bootstrap.contains(name)) { - PropertySource source = bootstrap.get(name); - if (!environment.contains(name)) { - environment.addLast(source); - } - else { - PropertySource target = environment.get(name); - if (target instanceof MapPropertySource && target != source && source instanceof MapPropertySource) { - Map targetMap = ((MapPropertySource) target).getSource(); - Map map = ((MapPropertySource) source).getSource(); - for (String key : map.keySet()) { - if (!target.containsProperty(key)) { - targetMap.put(key, map.get(key)); - } - } - } - } - } - mergeAdditionalPropertySources(environment, bootstrap); - } - - private void mergeAdditionalPropertySources(MutablePropertySources environment, MutablePropertySources bootstrap) { - PropertySource defaultProperties = environment.get(DEFAULT_PROPERTIES); - ExtendedDefaultPropertySource result = defaultProperties instanceof ExtendedDefaultPropertySource - ? (ExtendedDefaultPropertySource) defaultProperties - : new ExtendedDefaultPropertySource(DEFAULT_PROPERTIES, defaultProperties); - for (PropertySource source : bootstrap) { - if (!environment.contains(source.getName())) { - result.add(source); - } - } - for (String name : result.getPropertySourceNames()) { - bootstrap.remove(name); - } - addOrReplace(environment, result); - addOrReplace(bootstrap, result); - } - - private void addOrReplace(MutablePropertySources environment, PropertySource result) { - if (environment.contains(result.getName())) { - environment.replace(result.getName(), result); - } - else { - environment.addLast(result); - } - } - - private void addAncestorInitializer(SpringApplication application, ConfigurableApplicationContext context) { - boolean installed = false; - for (ApplicationContextInitializer initializer : application.getInitializers()) { - if (initializer instanceof AncestorInitializer) { - installed = true; - // New parent - ((AncestorInitializer) initializer).setParent(context); - } - } - if (!installed) { - application.addInitializers(new AncestorInitializer(context)); - } - - } - - @SuppressWarnings("unchecked") - private void apply(ConfigurableApplicationContext context, SpringApplication application, - ConfigurableEnvironment environment) { - if (application.getAllSources().contains(BootstrapMarkerConfiguration.class)) { - return; - } - application.addPrimarySources(List.of(BootstrapMarkerConfiguration.class)); - @SuppressWarnings("rawtypes") - Set target = new LinkedHashSet<>(application.getInitializers()); - target.addAll(getOrderedBeansOfType(context, ApplicationContextInitializer.class)); - application.setInitializers(target); - addBootstrapDecryptInitializer(application); - - // Get the active profiles from the bootstrap context and set them in main - // application - // environment. This allows any profiles activated during bootstrap to be - // activated when - // config data runs in the main application context. - environment.setActiveProfiles(context.getEnvironment().getActiveProfiles()); - } - - @SuppressWarnings("unchecked") - private void addBootstrapDecryptInitializer(SpringApplication application) { - DelegatingEnvironmentDecryptApplicationInitializer decrypter = null; - Set> initializers = new LinkedHashSet<>(); - for (ApplicationContextInitializer ini : application.getInitializers()) { - if (ini instanceof EnvironmentDecryptApplicationInitializer) { - @SuppressWarnings("rawtypes") - ApplicationContextInitializer del = ini; - decrypter = new DelegatingEnvironmentDecryptApplicationInitializer(del); - initializers.add(ini); - initializers.add(decrypter); - } - else if (ini instanceof DelegatingEnvironmentDecryptApplicationInitializer) { - // do nothing - } - else { - initializers.add(ini); - } - } - ArrayList> target = new ArrayList<>(initializers); - application.setInitializers(target); - } - - private List getOrderedBeansOfType(ListableBeanFactory context, Class type) { - List result = new ArrayList<>(); - for (String name : context.getBeanNamesForType(type)) { - result.add(context.getBean(name, type)); - } - AnnotationAwareOrderComparator.sort(result); - return result; - } - - @Override - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - - private static class BootstrapMarkerConfiguration { - - } - - private static class AncestorInitializer - implements ApplicationContextInitializer, Ordered { - - private ConfigurableApplicationContext parent; - - AncestorInitializer(ConfigurableApplicationContext parent) { - this.parent = parent; - } - - public void setParent(ConfigurableApplicationContext parent) { - this.parent = parent; - } - - @Override - public int getOrder() { - // Need to run not too late (so not unordered), so that, for instance, the - // ContextIdApplicationContextInitializer runs later and picks up the merged - // Environment. Also needs to be quite early so that other initializers can - // pick up the parent (especially the Environment). - return Ordered.HIGHEST_PRECEDENCE + 5; - } - - @Override - public void initialize(ConfigurableApplicationContext context) { - while (context.getParent() != null && context.getParent() != context) { - context = (ConfigurableApplicationContext) context.getParent(); - } - reorderSources(context.getEnvironment()); - new ParentContextApplicationContextInitializer(this.parent).initialize(context); - } - - private void reorderSources(ConfigurableEnvironment environment) { - PropertySource removed = environment.getPropertySources().remove(DEFAULT_PROPERTIES); - if (removed instanceof ExtendedDefaultPropertySource defaultProperties) { - environment.getPropertySources() - .addLast(new MapPropertySource(DEFAULT_PROPERTIES, defaultProperties.getSource())); - for (PropertySource source : defaultProperties.getPropertySources().getPropertySources()) { - if (!environment.getPropertySources().contains(source.getName())) { - environment.getPropertySources().addBefore(DEFAULT_PROPERTIES, source); - } - } - } - } - - } - - /** - * A special initializer designed to run before the property source bootstrap and - * decrypt any properties needed there (e.g. URL of config server). - */ - @Order(Ordered.HIGHEST_PRECEDENCE + 9) - private static class DelegatingEnvironmentDecryptApplicationInitializer - implements ApplicationContextInitializer { - - private ApplicationContextInitializer delegate; - - DelegatingEnvironmentDecryptApplicationInitializer( - ApplicationContextInitializer delegate) { - this.delegate = delegate; - } - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - this.delegate.initialize(applicationContext); - } - - } - - private static class ExtendedDefaultPropertySource extends SystemEnvironmentPropertySource - implements OriginLookup { - - private final OriginTrackedCompositePropertySource sources; - - private final List names = new ArrayList<>(); - - ExtendedDefaultPropertySource(String name, PropertySource propertySource) { - super(name, findMap(propertySource)); - this.sources = new OriginTrackedCompositePropertySource(name); - } - - @SuppressWarnings("unchecked") - private static Map findMap(PropertySource propertySource) { - if (propertySource instanceof MapPropertySource) { - return (Map) propertySource.getSource(); - } - return new LinkedHashMap<>(); - } - - public CompositePropertySource getPropertySources() { - return this.sources; - } - - public List getPropertySourceNames() { - return this.names; - } - - public void add(PropertySource source) { - // Only add map property sources added by boot, see gh-476 - if (source instanceof OriginTrackedMapPropertySource && !this.names.contains(source.getName())) { - this.sources.addPropertySource(source); - this.names.add(source.getName()); - } - } - - @Override - public Object getProperty(String name) { - if (this.sources.containsProperty(name)) { - return this.sources.getProperty(name); - } - return super.getProperty(name); - } - - @Override - public boolean containsProperty(String name) { - if (this.sources.containsProperty(name)) { - return true; - } - return super.containsProperty(name); - } - - @Override - public String[] getPropertyNames() { - List names = new ArrayList<>(); - names.addAll(Arrays.asList(this.sources.getPropertyNames())); - names.addAll(Arrays.asList(super.getPropertyNames())); - return names.toArray(new String[0]); - } - - @Override - public Origin getOrigin(String name) { - return this.sources.getOrigin(name); - } - - } - - private static class CloseContextOnFailureApplicationListener implements SmartApplicationListener { - - private final ConfigurableApplicationContext context; - - CloseContextOnFailureApplicationListener(ConfigurableApplicationContext context) { - this.context = context; - } - - @Override - public boolean supportsEventType(Class eventType) { - return ApplicationFailedEvent.class.isAssignableFrom(eventType); - } - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof ApplicationFailedEvent) { - this.context.close(); - } - - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfigFileApplicationListener.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfigFileApplicationListener.java deleted file mode 100644 index 323643ac..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfigFileApplicationListener.java +++ /dev/null @@ -1,1011 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.commons.logging.Log; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.DefaultPropertiesPropertySource; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor; -import org.springframework.boot.context.config.ConfigDataLocation; -import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; -import org.springframework.boot.context.event.ApplicationPreparedEvent; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.bind.PropertySourcesPlaceholdersResolver; -import org.springframework.boot.context.properties.source.ConfigurationPropertySources; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.boot.env.PropertySourceLoader; -import org.springframework.boot.env.RandomValuePropertySource; -import org.springframework.boot.logging.DeferredLog; -import org.springframework.cloud.util.PropertyUtils; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.ConfigurationClassPostProcessor; -import org.springframework.context.event.SmartApplicationListener; -import org.springframework.core.Ordered; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.Profiles; -import org.springframework.core.env.PropertySource; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.io.FileSystemResource; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; -import org.springframework.core.io.support.ResourcePatternResolver; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.util.Assert; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; -import org.springframework.util.ResourceUtils; -import org.springframework.util.StringUtils; - -/** - * {@link EnvironmentPostProcessor} that configures the context environment by loading - * properties from well known file locations. By default properties will be loaded from - * 'application.properties' and/or 'application.yml' files in the following locations: - *
    - *
  • file:./config/
  • - *
  • file:./config/{@literal *}/
  • - *
  • file:./
  • - *
  • classpath:config/
  • - *
  • classpath:
  • - *
- * The list is ordered by precedence (properties defined in locations higher in the list - * override those defined in lower locations). - *

- * Alternative search locations and names can be specified using - * {@link #setSearchLocations(String)} and {@link #setSearchNames(String)}. - *

- * Additional files will also be loaded based on active profiles. For example if a 'web' - * profile is active 'application-web.properties' and 'application-web.yml' will be - * considered. - *

- * The 'spring.config.name' property can be used to specify an alternative name to load - * and the 'spring.config.location' property can be used to specify alternative search - * locations or specific files. - *

- * - * @author Dave Syer - * @author Phillip Webb - * @author Stephane Nicoll - * @author Andy Wilkinson - * @author Eddú Meléndez - * @author Madhura Bhave - * @author Scott Frederick - * @since 1.0.0 {@link ConfigDataEnvironmentPostProcessor} - */ -public class BootstrapConfigFileApplicationListener - implements EnvironmentPostProcessor, SmartApplicationListener, Ordered { - - // Note the order is from least to most specific (last one wins) - private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/"; - - private static final String DEFAULT_NAMES = "application"; - - private static final Set NO_SEARCH_NAMES = Collections.singleton(null); - - private static final Bindable STRING_ARRAY = Bindable.of(String[].class); - - private static final Bindable> STRING_LIST = Bindable.listOf(String.class); - - private static final Set LOAD_FILTERED_PROPERTY; - - static { - LOAD_FILTERED_PROPERTY = Set.of("spring.profiles.active", "spring.profiles.include"); - } - - /** - * The "active profiles" property name. - */ - public static final String ACTIVE_PROFILES_PROPERTY = "spring.profiles.active"; - - /** - * The "includes profiles" property name. - */ - public static final String INCLUDE_PROFILES_PROPERTY = "spring.profiles.include"; - - /** - * The "config name" property name. - */ - public static final String CONFIG_NAME_PROPERTY = "spring.config.name"; - - /** - * The "config location" property name. - */ - public static final String CONFIG_LOCATION_PROPERTY = "spring.config.location"; - - /** - * The "config additional location" property name. - */ - public static final String CONFIG_ADDITIONAL_LOCATION_PROPERTY = "spring.config.additional-location"; - - /** - * The default order for the processor. - */ - public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10; - - private final Log logger; - - private static final Resource[] EMPTY_RESOURCES = {}; - - private static final Comparator FILE_COMPARATOR = Comparator.comparing(File::getAbsolutePath); - - private String searchLocations; - - private String names; - - private int order = DEFAULT_ORDER; - - public BootstrapConfigFileApplicationListener() { - this(new DeferredLog()); - } - - BootstrapConfigFileApplicationListener(Log logger) { - this.logger = logger; - } - - @Override - public boolean supportsEventType(Class eventType) { - return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType) - || ApplicationPreparedEvent.class.isAssignableFrom(eventType); - } - - @Override - public void onApplicationEvent(ApplicationEvent event) { - // do nothing - } - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - if (PropertyUtils.bootstrapEnabled(environment)) { - addPropertySources(environment, application.getResourceLoader()); - } - } - - /** - * Add config file property sources to the specified environment. - * @param environment the environment to add source to - * @param resourceLoader the resource loader - * @see #addPostProcessors(ConfigurableApplicationContext) - */ - protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) { - RandomValuePropertySource.addToEnvironment(environment); - new Loader(environment, resourceLoader).load(); - } - - /** - * Add appropriate post-processors to post-configure the property-sources. - * @param context the context to configure - */ - protected void addPostProcessors(ConfigurableApplicationContext context) { - context.addBeanFactoryPostProcessor(new PropertySourceOrderingPostProcessor(context)); - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public int getOrder() { - return this.order; - } - - /** - * Set the search locations that will be considered as a comma-separated list. Each - * search location should be a directory path (ending in "/") and it will be prefixed - * by the file names constructed from {@link #setSearchNames(String) search names} and - * profiles (if any) plus file extensions supported by the properties loaders. - * Locations are considered in the order specified, with later items taking precedence - * (like a map merge). - * @param locations the search locations - */ - public void setSearchLocations(String locations) { - Assert.hasLength(locations, "Locations must not be empty"); - this.searchLocations = locations; - } - - /** - * Sets the names of the files that should be loaded (excluding file extension) as a - * comma-separated list. - * @param names the names to load - */ - public void setSearchNames(String names) { - Assert.hasLength(names, "Names must not be empty"); - this.names = names; - } - - /** - * {@link BeanFactoryPostProcessor} to re-order our property sources below any - * {@code @PropertySource} items added by the {@link ConfigurationClassPostProcessor}. - */ - private static class PropertySourceOrderingPostProcessor implements BeanFactoryPostProcessor, Ordered { - - private final ConfigurableApplicationContext context; - - PropertySourceOrderingPostProcessor(ConfigurableApplicationContext context) { - this.context = context; - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - reorderSources(this.context.getEnvironment()); - } - - private void reorderSources(ConfigurableEnvironment environment) { - DefaultPropertiesPropertySource.moveToEnd(environment); - } - - } - - /** - * Loads candidate property sources and configures the active profiles. - */ - private class Loader { - - private final Log logger = BootstrapConfigFileApplicationListener.this.logger; - - private final ConfigurableEnvironment environment; - - private final PropertySourcesPlaceholdersResolver placeholdersResolver; - - private final ResourceLoader resourceLoader; - - private final List propertySourceLoaders; - - private Deque profiles; - - private List processedProfiles; - - private boolean activatedProfiles; - - private Map loaded; - - private Map> loadDocumentsCache = new HashMap<>(); - - Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) { - this.environment = environment; - this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment); - this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader(null); - this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, - this.resourceLoader.getClassLoader()); - } - - void load() { - FilteredPropertySource.apply(this.environment, DefaultPropertiesPropertySource.NAME, LOAD_FILTERED_PROPERTY, - this::loadWithFilteredProperties); - } - - private void loadWithFilteredProperties(PropertySource defaultProperties) { - this.profiles = new LinkedList<>(); - this.processedProfiles = new LinkedList<>(); - this.activatedProfiles = false; - this.loaded = new LinkedHashMap<>(); - initializeProfiles(); - while (!this.profiles.isEmpty()) { - Profile profile = this.profiles.poll(); - if (isDefaultProfile(profile)) { - addProfileToEnvironment(profile.getName()); - } - load(profile, this::getPositiveProfileFilter, addToLoaded(MutablePropertySources::addLast, false)); - this.processedProfiles.add(profile); - } - load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true)); - addLoadedPropertySources(); - applyActiveProfiles(defaultProperties); - } - - /** - * Initialize profile information from both the {@link Environment} active - * profiles and any {@code spring.profiles.active}/{@code spring.profiles.include} - * properties that are already set. - */ - private void initializeProfiles() { - // The default profile for these purposes is represented as null. We add it - // first so that it is processed first and has lowest priority. - this.profiles.add(null); - Binder binder = Binder.get(this.environment); - Set activatedViaProperty = getProfiles(binder, ACTIVE_PROFILES_PROPERTY); - Set includedViaProperty = getProfiles(binder, INCLUDE_PROFILES_PROPERTY); - List otherActiveProfiles = getOtherActiveProfiles(activatedViaProperty, includedViaProperty); - this.profiles.addAll(otherActiveProfiles); - // Any pre-existing active profiles set via property sources (e.g. - // System properties) take precedence over those added in config files. - this.profiles.addAll(includedViaProperty); - addActiveProfiles(activatedViaProperty); - if (this.profiles.size() == 1) { // only has null profile - for (String defaultProfileName : getDefaultProfiles(binder)) { - Profile defaultProfile = new Profile(defaultProfileName, true); - this.profiles.add(defaultProfile); - } - } - } - - private String[] getDefaultProfiles(Binder binder) { - return binder.bind(AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, STRING_ARRAY) - .orElseGet(this.environment::getDefaultProfiles); - } - - private List getOtherActiveProfiles(Set activatedViaProperty, - Set includedViaProperty) { - return Arrays.stream(this.environment.getActiveProfiles()).map(Profile::new).filter( - (profile) -> !activatedViaProperty.contains(profile) && !includedViaProperty.contains(profile)) - .collect(Collectors.toList()); - } - - void addActiveProfiles(Set profiles) { - if (profiles.isEmpty()) { - return; - } - if (this.activatedProfiles) { - if (this.logger.isDebugEnabled()) { - this.logger.debug("Profiles already activated, '" + profiles + "' will not be applied"); - } - return; - } - this.profiles.addAll(profiles); - if (this.logger.isDebugEnabled()) { - this.logger.debug("Activated activeProfiles " + StringUtils.collectionToCommaDelimitedString(profiles)); - } - this.activatedProfiles = true; - removeUnprocessedDefaultProfiles(); - } - - private void removeUnprocessedDefaultProfiles() { - this.profiles.removeIf((profile) -> (profile != null && profile.isDefaultProfile())); - } - - private DocumentFilter getPositiveProfileFilter(Profile profile) { - return (Document document) -> { - if (profile == null) { - return ObjectUtils.isEmpty(document.getProfiles()); - } - return ObjectUtils.containsElement(document.getProfiles(), profile.getName()) - && this.environment.acceptsProfiles(Profiles.of(document.getProfiles())); - }; - } - - private DocumentFilter getNegativeProfileFilter(Profile profile) { - return (Document document) -> (profile == null && !ObjectUtils.isEmpty(document.getProfiles()) - && this.environment.acceptsProfiles(Profiles.of(document.getProfiles()))); - } - - private DocumentConsumer addToLoaded(BiConsumer> addMethod, - boolean checkForExisting) { - return (profile, document) -> { - if (checkForExisting) { - for (MutablePropertySources merged : this.loaded.values()) { - if (merged.contains(document.getPropertySource().getName())) { - return; - } - } - } - MutablePropertySources merged = this.loaded.computeIfAbsent(profile, - (k) -> new MutablePropertySources()); - addMethod.accept(merged, document.getPropertySource()); - }; - } - - private void load(Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) { - getSearchLocations().forEach((location) -> { - String nonOptionalLocation = ConfigDataLocation.of(location).getValue(); - boolean isDirectory = location.endsWith("/"); - Set names = isDirectory ? getSearchNames() : NO_SEARCH_NAMES; - names.forEach((name) -> load(nonOptionalLocation, name, profile, filterFactory, consumer)); - }); - } - - private void load(String location, String name, Profile profile, DocumentFilterFactory filterFactory, - DocumentConsumer consumer) { - if (!StringUtils.hasText(name)) { - for (PropertySourceLoader loader : this.propertySourceLoaders) { - if (canLoadFileExtension(loader, location)) { - load(loader, location, profile, filterFactory.getDocumentFilter(profile), consumer); - return; - } - } - throw new IllegalStateException("File extension of config file location '" + location - + "' is not known to any PropertySourceLoader. If the location is meant to reference " - + "a directory, it must end in '/'"); - } - Set processed = new HashSet<>(); - for (PropertySourceLoader loader : this.propertySourceLoaders) { - for (String fileExtension : loader.getFileExtensions()) { - if (processed.add(fileExtension)) { - loadForFileExtension(loader, location + name, "." + fileExtension, profile, filterFactory, - consumer); - } - } - } - } - - private boolean canLoadFileExtension(PropertySourceLoader loader, String name) { - return Arrays.stream(loader.getFileExtensions()) - .anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name, fileExtension)); - } - - private void loadForFileExtension(PropertySourceLoader loader, String prefix, String fileExtension, - Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) { - DocumentFilter defaultFilter = filterFactory.getDocumentFilter(null); - DocumentFilter profileFilter = filterFactory.getDocumentFilter(profile); - if (profile != null) { - // Try profile-specific file & profile section in profile file (gh-340) - String profileSpecificFile = prefix + "-" + profile + fileExtension; - load(loader, profileSpecificFile, profile, defaultFilter, consumer); - load(loader, profileSpecificFile, profile, profileFilter, consumer); - // Try profile specific sections in files we've already processed - for (Profile processedProfile : this.processedProfiles) { - if (processedProfile != null) { - String previouslyLoaded = prefix + "-" + processedProfile + fileExtension; - load(loader, previouslyLoaded, profile, profileFilter, consumer); - } - } - } - // Also try the profile-specific section (if any) of the normal file - load(loader, prefix + fileExtension, profile, profileFilter, consumer); - } - - private void load(PropertySourceLoader loader, String location, Profile profile, DocumentFilter filter, - DocumentConsumer consumer) { - Resource[] resources = getResources(location); - for (Resource resource : resources) { - try { - if (resource == null || !resource.exists()) { - if (this.logger.isTraceEnabled()) { - StringBuilder description = getDescription("Skipped missing config ", location, resource, - profile); - this.logger.trace(description); - } - continue; - } - if (!StringUtils.hasText(StringUtils.getFilenameExtension(resource.getFilename()))) { - if (this.logger.isTraceEnabled()) { - StringBuilder description = getDescription("Skipped empty config extension ", location, - resource, profile); - this.logger.trace(description); - } - continue; - } - if (resource.isFile() && isPatternLocation(location) && hasHiddenPathElement(resource)) { - if (this.logger.isTraceEnabled()) { - StringBuilder description = getDescription("Skipped location with hidden path element ", - location, resource, profile); - this.logger.trace(description); - } - continue; - } - String name = "applicationConfig: [" + getLocationName(location, resource) + "]"; - List documents = loadDocuments(loader, name, resource); - if (CollectionUtils.isEmpty(documents)) { - if (this.logger.isTraceEnabled()) { - StringBuilder description = getDescription("Skipped unloaded config ", location, resource, - profile); - this.logger.trace(description); - } - continue; - } - List loaded = new ArrayList<>(); - for (Document document : documents) { - if (filter.match(document)) { - addActiveProfiles(document.getActiveProfiles()); - addIncludedProfiles(document.getIncludeProfiles()); - loaded.add(document); - } - } - Collections.reverse(loaded); - if (!loaded.isEmpty()) { - loaded.forEach((document) -> consumer.accept(profile, document)); - if (this.logger.isDebugEnabled()) { - StringBuilder description = getDescription("Loaded config file ", location, resource, - profile); - this.logger.debug(description); - } - } - } - catch (Exception ex) { - StringBuilder description = getDescription("Failed to load property source from ", location, - resource, profile); - throw new IllegalStateException(description.toString(), ex); - } - } - } - - private boolean hasHiddenPathElement(Resource resource) throws IOException { - String cleanPath = StringUtils.cleanPath(resource.getFile().getAbsolutePath()); - for (Path value : Paths.get(cleanPath)) { - if (value.toString().startsWith("..")) { - return true; - } - } - return false; - } - - private String getLocationName(String locationReference, Resource resource) { - if (!locationReference.contains("*")) { - return locationReference; - } - if (resource instanceof FileSystemResource) { - return ((FileSystemResource) resource).getPath(); - } - return resource.getDescription(); - } - - private Resource[] getResources(String locationReference) { - try { - if (isPatternLocation(locationReference)) { - return getResourcesFromPatternLocationReference(locationReference); - } - return new Resource[] { this.resourceLoader.getResource(locationReference) }; - } - catch (Exception ex) { - return EMPTY_RESOURCES; - } - } - - private boolean isPatternLocation(String location) { - return location.contains("*"); - } - - private Resource[] getResourcesFromPatternLocationReference(String locationReference) throws IOException { - String directoryPath = locationReference.substring(0, locationReference.indexOf("*/")); - Resource resource = this.resourceLoader.getResource(directoryPath); - File[] files = resource.getFile().listFiles(File::isDirectory); - if (files != null) { - String fileName = locationReference.substring(locationReference.lastIndexOf("/") + 1); - Arrays.sort(files, FILE_COMPARATOR); - return Arrays.stream(files).map((file) -> file.listFiles((dir, name) -> name.equals(fileName))) - .filter(Objects::nonNull).flatMap((Function>) Arrays::stream) - .map(FileSystemResource::new).toArray(Resource[]::new); - } - return EMPTY_RESOURCES; - } - - private void addIncludedProfiles(Set includeProfiles) { - LinkedList existingProfiles = new LinkedList<>(this.profiles); - this.profiles.clear(); - this.profiles.addAll(includeProfiles); - this.profiles.removeAll(this.processedProfiles); - this.profiles.addAll(existingProfiles); - } - - private List loadDocuments(PropertySourceLoader loader, String name, Resource resource) - throws IOException { - DocumentsCacheKey cacheKey = new DocumentsCacheKey(loader, resource); - List documents = this.loadDocumentsCache.get(cacheKey); - if (documents == null) { - List> loaded = loader.load(name, resource); - documents = asDocuments(loaded); - this.loadDocumentsCache.put(cacheKey, documents); - } - return documents; - } - - private List asDocuments(List> loaded) { - if (loaded == null) { - return Collections.emptyList(); - } - return loaded.stream().map((propertySource) -> { - Binder binder = new Binder(ConfigurationPropertySources.from(propertySource), - this.placeholdersResolver); - String[] profiles = binder.bind("spring.config.activate.on-profile", STRING_ARRAY).orElse(null); - Set activeProfiles = getProfiles(binder, ACTIVE_PROFILES_PROPERTY); - Set includeProfiles = getProfiles(binder, INCLUDE_PROFILES_PROPERTY); - return new Document(propertySource, profiles, activeProfiles, includeProfiles); - }).collect(Collectors.toList()); - } - - private StringBuilder getDescription(String prefix, String locationReference, Resource resource, - Profile profile) { - StringBuilder result = new StringBuilder(prefix); - try { - if (resource != null) { - String uri = resource.getURI().toASCIIString(); - result.append("'"); - result.append(uri); - result.append("' ("); - result.append(locationReference); - result.append(")"); - } - } - catch (IOException ex) { - result.append(locationReference); - } - if (profile != null) { - result.append(" for profile "); - result.append(profile); - } - return result; - } - - private Set getProfiles(Binder binder, String name) { - return binder.bind(name, STRING_ARRAY).map(this::asProfileSet).orElse(Collections.emptySet()); - } - - private Set asProfileSet(String[] profileNames) { - List profiles = new ArrayList<>(); - for (String profileName : profileNames) { - profiles.add(new Profile(profileName)); - } - return new LinkedHashSet<>(profiles); - } - - private void addProfileToEnvironment(String profile) { - for (String activeProfile : this.environment.getActiveProfiles()) { - if (activeProfile.equals(profile)) { - return; - } - } - this.environment.addActiveProfile(profile); - } - - private Set getSearchLocations() { - Set locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY); - if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) { - locations.addAll(getSearchLocations(CONFIG_LOCATION_PROPERTY)); - } - else { - locations.addAll(asResolvedSet(BootstrapConfigFileApplicationListener.this.searchLocations, - DEFAULT_SEARCH_LOCATIONS)); - } - return locations; - } - - private Set getSearchLocations(String propertyName) { - Set locations = new LinkedHashSet<>(); - if (this.environment.containsProperty(propertyName)) { - for (String path : asResolvedSet(this.environment.getProperty(propertyName), null)) { - if (!path.contains("$")) { - path = StringUtils.cleanPath(path); - Assert.state(!path.startsWith(ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX), - "Classpath wildcard patterns cannot be used as a search location"); - validateWildcardLocation(path); - if (!ResourceUtils.isUrl(path)) { - path = ResourceUtils.FILE_URL_PREFIX + path; - } - } - locations.add(path); - } - } - return locations; - } - - private void validateWildcardLocation(String path) { - if (path.contains("*")) { - Assert.state(StringUtils.countOccurrencesOf(path, "*") == 1, - () -> "Search location '" + path + "' cannot contain multiple wildcards"); - String directoryPath = path.substring(0, path.lastIndexOf("/") + 1); - Assert.state(directoryPath.endsWith("*/"), () -> "Search location '" + path + "' must end with '*/'"); - } - } - - private Set getSearchNames() { - if (this.environment.containsProperty(CONFIG_NAME_PROPERTY)) { - String property = this.environment.getProperty(CONFIG_NAME_PROPERTY); - Set names = asResolvedSet(property, null); - names.forEach(this::assertValidConfigName); - return names; - } - return asResolvedSet(BootstrapConfigFileApplicationListener.this.names, DEFAULT_NAMES); - } - - private Set asResolvedSet(String value, String fallback) { - List list = Arrays.asList(StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray( - (value != null) ? this.environment.resolvePlaceholders(value) : fallback))); - Collections.reverse(list); - return new LinkedHashSet<>(list); - } - - private void assertValidConfigName(String name) { - Assert.state(!name.contains("*"), () -> "Config name '" + name + "' cannot contain wildcards"); - } - - private void addLoadedPropertySources() { - MutablePropertySources destination = this.environment.getPropertySources(); - List loaded = new ArrayList<>(this.loaded.values()); - Collections.reverse(loaded); - String lastAdded = null; - Set added = new HashSet<>(); - for (MutablePropertySources sources : loaded) { - for (PropertySource source : sources) { - if (added.add(source.getName())) { - addLoadedPropertySource(destination, lastAdded, source); - lastAdded = source.getName(); - } - } - } - } - - private void addLoadedPropertySource(MutablePropertySources destination, String lastAdded, - PropertySource source) { - if (lastAdded == null) { - if (destination.contains(DefaultPropertiesPropertySource.NAME)) { - destination.addBefore(DefaultPropertiesPropertySource.NAME, source); - } - else { - destination.addLast(source); - } - } - else { - destination.addAfter(lastAdded, source); - } - } - - private void applyActiveProfiles(PropertySource defaultProperties) { - List activeProfiles = new ArrayList<>(); - if (defaultProperties != null) { - Binder binder = new Binder(ConfigurationPropertySources.from(defaultProperties), - new PropertySourcesPlaceholdersResolver(this.environment)); - activeProfiles.addAll(bindStringList(binder, "spring.profiles.include")); - if (!this.activatedProfiles) { - activeProfiles.addAll(bindStringList(binder, "spring.profiles.active")); - } - } - this.processedProfiles.stream().filter(this::isDefaultProfile).map(Profile::getName) - .forEach(activeProfiles::add); - this.environment.setActiveProfiles(activeProfiles.toArray(new String[0])); - } - - private boolean isDefaultProfile(Profile profile) { - return profile != null && !profile.isDefaultProfile(); - } - - private List bindStringList(Binder binder, String property) { - return binder.bind(property, STRING_LIST).orElse(Collections.emptyList()); - } - - } - - /** - * A Spring Profile that can be loaded. - */ - private static class Profile { - - private final String name; - - private final boolean defaultProfile; - - Profile(String name) { - this(name, false); - } - - Profile(String name, boolean defaultProfile) { - Assert.notNull(name, "Name must not be null"); - this.name = name; - this.defaultProfile = defaultProfile; - } - - String getName() { - return this.name; - } - - boolean isDefaultProfile() { - return this.defaultProfile; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || obj.getClass() != getClass()) { - return false; - } - return ((Profile) obj).name.equals(this.name); - } - - @Override - public int hashCode() { - return this.name.hashCode(); - } - - @Override - public String toString() { - return this.name; - } - - } - - /** - * Cache key used to save loading the same document multiple times. - */ - private static class DocumentsCacheKey { - - private final PropertySourceLoader loader; - - private final Resource resource; - - DocumentsCacheKey(PropertySourceLoader loader, Resource resource) { - this.loader = loader; - this.resource = resource; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - DocumentsCacheKey other = (DocumentsCacheKey) obj; - return this.loader.equals(other.loader) && this.resource.equals(other.resource); - } - - @Override - public int hashCode() { - return this.loader.hashCode() * 31 + this.resource.hashCode(); - } - - } - - /** - * A single document loaded by a {@link PropertySourceLoader}. - */ - private static class Document { - - private final PropertySource propertySource; - - private String[] profiles; - - private final Set activeProfiles; - - private final Set includeProfiles; - - Document(PropertySource propertySource, String[] profiles, Set activeProfiles, - Set includeProfiles) { - this.propertySource = propertySource; - this.profiles = profiles; - this.activeProfiles = activeProfiles; - this.includeProfiles = includeProfiles; - } - - PropertySource getPropertySource() { - return this.propertySource; - } - - String[] getProfiles() { - return this.profiles; - } - - Set getActiveProfiles() { - return this.activeProfiles; - } - - Set getIncludeProfiles() { - return this.includeProfiles; - } - - @Override - public String toString() { - return this.propertySource.toString(); - } - - } - - /** - * Factory used to create a {@link DocumentFilter}. - */ - @FunctionalInterface - private interface DocumentFilterFactory { - - /** - * Create a filter for the given profile. - * @param profile the profile or {@code null} - * @return the filter - */ - DocumentFilter getDocumentFilter(Profile profile); - - } - - /** - * Filter used to restrict when a {@link Document} is loaded. - */ - @FunctionalInterface - private interface DocumentFilter { - - boolean match(Document document); - - } - - /** - * Consumer used to handle a loaded {@link Document}. - */ - @FunctionalInterface - private interface DocumentConsumer { - - void accept(Profile profile, Document document); - - } - - /** - * Internal {@link PropertySource} implementation used by - * {@link BootstrapConfigFileApplicationListener} to filter out properties for - * specific operations. - * - * @author Phillip Webb - */ - static class FilteredPropertySource extends PropertySource> { - - private final Set filteredProperties; - - FilteredPropertySource(PropertySource original, Set filteredProperties) { - super(original.getName(), original); - this.filteredProperties = filteredProperties; - } - - @Override - public Object getProperty(String name) { - if (this.filteredProperties.contains(name)) { - return null; - } - return getSource().getProperty(name); - } - - static void apply(ConfigurableEnvironment environment, String propertySourceName, - Set filteredProperties, Consumer> operation) { - MutablePropertySources propertySources = environment.getPropertySources(); - PropertySource original = propertySources.get(propertySourceName); - if (original == null) { - operation.accept(null); - return; - } - propertySources.replace(propertySourceName, new FilteredPropertySource(original, filteredProperties)); - try { - operation.accept(original); - } - finally { - propertySources.replace(propertySourceName, original); - } - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java deleted file mode 100644 index dfd28a17..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -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; - -/** - * A marker interface used as a key in META-INF/spring.factories. Entries in - * the factories file are used to create the bootstrap application context. - * - * @author Dave Syer - * - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface BootstrapConfiguration { - - /** - * Excludes specific auto-configuration classes such that they will never be applied. - * @return classes to exclude - */ - Class[] exclude() default {}; - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java deleted file mode 100644 index 62994c62..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelector.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.springframework.context.EnvironmentAware; -import org.springframework.context.annotation.DeferredImportSelector; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.annotation.Order; -import org.springframework.core.env.Environment; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.core.style.ToStringCreator; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.classreading.CachingMetadataReaderFactory; -import org.springframework.core.type.classreading.MetadataReader; -import org.springframework.core.type.classreading.MetadataReaderFactory; -import org.springframework.util.StringUtils; - -/** - * This class uses {@link SpringFactoriesLoader} to load {@link BootstrapConfiguration} - * entries from {@code spring.factories}. The classes are then loaded so they can be - * sorted using {@link AnnotationAwareOrderComparator#sort(List)}. This class is a - * {@link DeferredImportSelector} so {@code @Conditional} annotations on imported classes - * are supported. - * - * @author Spencer Gibb - */ -public class BootstrapImportSelector implements EnvironmentAware, DeferredImportSelector { - - private Environment environment; - - private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(); - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - @Override - public String[] selectImports(AnnotationMetadata annotationMetadata) { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - // Use names and ensure unique to protect against duplicates - List names = new ArrayList<>( - SpringFactoriesLoader.loadFactoryNames(BootstrapConfiguration.class, classLoader)); - names.addAll(Arrays.asList(StringUtils - .commaDelimitedListToStringArray(this.environment.getProperty("spring.cloud.bootstrap.sources", "")))); - - List elements = new ArrayList<>(); - for (String name : names) { - try { - elements.add(new OrderedAnnotatedElement(this.metadataReaderFactory, name)); - } - catch (IOException e) { - continue; - } - } - AnnotationAwareOrderComparator.sort(elements); - - String[] classNames = elements.stream().map(e -> e.name).toArray(String[]::new); - - return classNames; - } - - class OrderedAnnotatedElement implements AnnotatedElement { - - private final String name; - - private Order order = null; - - private Integer value; - - OrderedAnnotatedElement(MetadataReaderFactory metadataReaderFactory, String name) throws IOException { - MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(name); - AnnotationMetadata metadata = metadataReader.getAnnotationMetadata(); - Map attributes = metadata.getAnnotationAttributes(Order.class.getName()); - this.name = name; - if (attributes != null && attributes.containsKey("value")) { - this.value = (Integer) attributes.get("value"); - this.order = new Order() { - @Override - public Class annotationType() { - return Order.class; - } - - @Override - public int value() { - return OrderedAnnotatedElement.this.value; - } - }; - } - } - - @Override - @SuppressWarnings("unchecked") - public T getAnnotation(Class annotationClass) { - if (annotationClass == Order.class) { - return (T) this.order; - } - return null; - } - - @Override - public Annotation[] getAnnotations() { - return this.order == null ? new Annotation[0] : new Annotation[] { this.order }; - } - - @Override - public Annotation[] getDeclaredAnnotations() { - return getAnnotations(); - } - - @Override - public String toString() { - return new ToStringCreator(this).append("name", this.name).append("value", this.value).toString(); - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelectorConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelectorConfiguration.java deleted file mode 100644 index 374e7999..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/BootstrapImportSelectorConfiguration.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Configuration to import the {@link BootstrapImportSelector} configuration. - * - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -@Import(BootstrapImportSelector.class) -public class BootstrapImportSelectorConfiguration { - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/LoggingSystemShutdownListener.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/LoggingSystemShutdownListener.java deleted file mode 100644 index 7240594e..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/LoggingSystemShutdownListener.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.context.ApplicationListener; -import org.springframework.core.Ordered; -import org.springframework.util.ClassUtils; - -/** - * Cleans up the logging system immediately after the bootstrap context is created on - * startup. Logging will go dark until the ConfigFileApplicationListener fires, but this - * is the price we pay for that listener being able to adjust the log levels according to - * what it finds in its own configuration. - * - * @author Dave Syer - */ -public class LoggingSystemShutdownListener - implements ApplicationListener, Ordered { - - /** - * Default order for the listener. - */ - public static final int DEFAULT_ORDER = BootstrapApplicationListener.DEFAULT_ORDER + 1; - - private int order = DEFAULT_ORDER; - - @Override - public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { - shutdownLogging(); - } - - private void shutdownLogging() { - // TODO: only enable if bootstrap and legacy - LoggingSystem loggingSystem = LoggingSystem.get(ClassUtils.getDefaultClassLoader()); - loggingSystem.cleanUp(); - loggingSystem.beforeInitialize(); - } - - @Override - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/RefreshBootstrapRegistryInitializer.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/RefreshBootstrapRegistryInitializer.java deleted file mode 100644 index cb7a2207..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/RefreshBootstrapRegistryInitializer.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.springframework.boot.BootstrapContext; -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.BootstrapRegistryInitializer; -import org.springframework.cloud.context.refresh.ConfigDataContextRefresher; - -/** - * BootstrapRegistryInitializer that adds the BootstrapContext to the ApplicationContext - * for use later in {@link ConfigDataContextRefresher}. - * - * @author Spencer Gibb - * @since 3.0.3 - */ -public class RefreshBootstrapRegistryInitializer implements BootstrapRegistryInitializer { - - @Override - public void initialize(BootstrapRegistry registry) { - // promote BootstrapContext to context - registry.addCloseListener(event -> { - BootstrapContext bootstrapContext = event.getBootstrapContext(); - event.getApplicationContext().getBeanFactory().registerSingleton("bootstrapContext", bootstrapContext); - }); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorBindHandler.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorBindHandler.java deleted file mode 100644 index a73dcaaf..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorBindHandler.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.context.properties.bind.AbstractBindHandler; -import org.springframework.boot.context.properties.bind.BindContext; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.source.ConfigurationPropertyName; -import org.springframework.cloud.bootstrap.encrypt.KeyProperties; -import org.springframework.security.crypto.encrypt.TextEncryptor; - -/** - * BindHandler that uses a TextEncryptor to decrypt text if properly prefixed with - * {cipher}. - * - * @author Marcin Grzejszczak - * @since 3.0.0 - */ -public class TextEncryptorBindHandler extends AbstractBindHandler { - - private static final Log logger = LogFactory.getLog(TextEncryptorBindHandler.class); - - /** - * Prefix indicating an encrypted value. - */ - protected static final String ENCRYPTED_PROPERTY_PREFIX = "{cipher}"; - - private final TextEncryptor textEncryptor; - - private final KeyProperties keyProperties; - - public TextEncryptorBindHandler(TextEncryptor textEncryptor, KeyProperties keyProperties) { - this.textEncryptor = textEncryptor; - this.keyProperties = keyProperties; - } - - @Override - public Object onSuccess(ConfigurationPropertyName name, Bindable target, BindContext context, Object result) { - if (result instanceof String && ((String) result).startsWith(ENCRYPTED_PROPERTY_PREFIX)) { - return decrypt(name.toString(), (String) result); - } - return result; - } - - private String decrypt(String key, String original) { - String value = original.substring(ENCRYPTED_PROPERTY_PREFIX.length()); - try { - value = this.textEncryptor.decrypt(value); - if (logger.isDebugEnabled()) { - logger.debug("Decrypted: key=" + key); - } - return value; - } - catch (Exception e) { - String message = "Cannot decrypt: key=" + key; - if (logger.isDebugEnabled()) { - logger.warn(message, e); - } - else { - logger.warn(message); - } - if (this.keyProperties.isFailOnError()) { - throw new IllegalStateException(message, e); - } - return ""; - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorConfigBootstrapper.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorConfigBootstrapper.java deleted file mode 100644 index 0161eb1e..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/TextEncryptorConfigBootstrapper.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.BootstrapContext; -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.BootstrapRegistryInitializer; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.cloud.bootstrap.encrypt.KeyProperties; -import org.springframework.cloud.bootstrap.encrypt.RsaProperties; -import org.springframework.cloud.bootstrap.encrypt.TextEncryptorUtils; -import org.springframework.util.ClassUtils; - -/** - * Bootstrapper. - * - * @author Marcin Grzejszczak - * @since 3.0.0 - */ -public class TextEncryptorConfigBootstrapper implements BootstrapRegistryInitializer { - - /** - * RsaSecretEncryptor present. - */ - public static final boolean RSA_IS_PRESENT = ClassUtils - .isPresent("org.springframework.security.rsa.crypto.RsaSecretEncryptor", null); - - @Override - public void initialize(BootstrapRegistry registry) { - if (!ClassUtils.isPresent("org.springframework.security.crypto.encrypt.TextEncryptor", null)) { - return; - } - - registry.registerIfAbsent(KeyProperties.class, context -> context.get(Binder.class) - .bind(KeyProperties.PREFIX, KeyProperties.class).orElseGet(KeyProperties::new)); - if (RSA_IS_PRESENT) { - registry.registerIfAbsent(RsaProperties.class, context -> context.get(Binder.class) - .bind(RsaProperties.PREFIX, RsaProperties.class).orElseGet(RsaProperties::new)); - } - TextEncryptorUtils.register(registry); - - // promote beans to context - registry.addCloseListener(event -> { - if (TextEncryptorUtils.isLegacyBootstrap(event.getApplicationContext().getEnvironment())) { - return; - } - BootstrapContext bootstrapContext = event.getBootstrapContext(); - KeyProperties keyProperties = bootstrapContext.get(KeyProperties.class); - ConfigurableListableBeanFactory beanFactory = event.getApplicationContext().getBeanFactory(); - if (keyProperties != null) { - beanFactory.registerSingleton("keyProperties", keyProperties); - } - if (RSA_IS_PRESENT) { - RsaProperties rsaProperties = bootstrapContext.get(RsaProperties.class); - if (rsaProperties != null) { - beanFactory.registerSingleton("rsaProperties", rsaProperties); - } - } - TextEncryptorUtils.promote(bootstrapContext, beanFactory); - }); - } - - @Deprecated - public static boolean keysConfigured(KeyProperties properties) { - return TextEncryptorUtils.keysConfigured(properties); - } - - @Deprecated - public static class FailsafeTextEncryptor extends TextEncryptorUtils.FailsafeTextEncryptor { - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java deleted file mode 100644 index e92c6a77..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.config; - -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.Set; - -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME; - -/** - * Enumerable wrapper for a property source. - * - * @author Ryan Baxter - */ -public class BootstrapPropertySource extends EnumerablePropertySource { - - private EnumerablePropertySource delegate; - - public BootstrapPropertySource(EnumerablePropertySource delegate) { - super(BOOTSTRAP_PROPERTY_SOURCE_NAME + "-" + delegate.getName(), delegate.getSource()); - this.delegate = delegate; - } - - @Override - public Object getProperty(String name) { - return this.delegate.getProperty(name); - } - - @Override - public String[] getPropertyNames() { - Set names = new LinkedHashSet<>(Arrays.asList(this.delegate.getPropertyNames())); - - return StringUtils.toStringArray(names); - } - - public PropertySource getDelegate() { - return delegate; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java deleted file mode 100644 index 07caa76a..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.config; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.stream.Collectors; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.config.Profiles; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.logging.LogFile; -import org.springframework.boot.logging.LoggingInitializationContext; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.cloud.bootstrap.BootstrapApplicationListener; -import org.springframework.cloud.bootstrap.BootstrapConfigFileApplicationListener; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.logging.LoggingRebinder; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.bootstrap.encrypt.AbstractEnvironmentDecrypt.DECRYPTED_PROPERTY_SOURCE_NAME; -import static org.springframework.core.env.StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME; - -/** - * @author Dave Syer - * - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(PropertySourceBootstrapProperties.class) -public class PropertySourceBootstrapConfiguration implements ApplicationListener, - ApplicationContextInitializer, Ordered { - - /** - * Bootstrap property source name. - */ - public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME - + "Properties"; - - private static Log logger = LogFactory.getLog(PropertySourceBootstrapConfiguration.class); - - private int order = Ordered.HIGHEST_PRECEDENCE + 10; - - @Autowired(required = false) - private List propertySourceLocators = new ArrayList<>(); - - @Autowired - private PropertySourceBootstrapProperties bootstrapProperties; - - @Override - public int getOrder() { - return this.order; - } - - public void setPropertySourceLocators(Collection propertySourceLocators) { - this.propertySourceLocators = new ArrayList<>(propertySourceLocators); - } - - /* - * The ApplicationListener is called when the main application context is initialized. - * This will be called after the ApplicationListener ContextRefreshedEvent is fired - * during the bootstrap phase. This method is also what added PropertySources prior to - * Spring Cloud 2021.0.7, this is why it will be called when - * spring.cloud.config.initialize-on-context-refresh is false. When - * spring.cloud.config.initialize-on-context-refresh is true this method provides a - * "second fetch" of configuration data to fetch any additional configuration data - * from profiles that have been activated. - */ - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - if (!bootstrapProperties.isInitializeOnContextRefresh() || !applicationContext.getEnvironment() - .getPropertySources().contains(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - doInitialize(applicationContext); - } - } - - private void doInitialize(ConfigurableApplicationContext applicationContext) { - List> composite = new ArrayList<>(); - AnnotationAwareOrderComparator.sort(this.propertySourceLocators); - boolean empty = true; - ConfigurableEnvironment environment = applicationContext.getEnvironment(); - for (PropertySourceLocator locator : this.propertySourceLocators) { - Collection> source = locator.locateCollection(environment); - if (source == null || source.size() == 0) { - continue; - } - List> sourceList = new ArrayList<>(); - for (PropertySource p : source) { - if (p instanceof EnumerablePropertySource enumerable) { - sourceList.add(new BootstrapPropertySource<>(enumerable)); - } - else { - sourceList.add(new SimpleBootstrapPropertySource(p)); - } - } - logger.info("Located property source: " + sourceList); - composite.addAll(sourceList); - empty = false; - } - if (!empty) { - MutablePropertySources propertySources = environment.getPropertySources(); - String logConfig = environment.resolvePlaceholders("${logging.config:}"); - LogFile logFile = LogFile.get(environment); - for (PropertySource p : environment.getPropertySources()) { - if (p.getName().startsWith(BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - propertySources.remove(p.getName()); - } - } - insertPropertySources(propertySources, composite); - reinitializeLoggingSystem(environment); - setLogLevels(applicationContext, environment); - handleProfiles(environment); - } - } - - private void reinitializeLoggingSystem(ConfigurableEnvironment environment) { - Map props = Binder.get(environment).bind("logging", Bindable.mapOf(String.class, Object.class)) - .orElseGet(Collections::emptyMap); - if (!props.isEmpty()) { - String logConfig = environment.resolvePlaceholders("${logging.config:}"); - LogFile logFile = LogFile.get(environment); - LoggingSystem system = LoggingSystem.get(LoggingSystem.class.getClassLoader()); - try { - // Three step initialization that accounts for the clean up of the logging - // context before initialization. Spring Boot doesn't initialize a logging - // system that hasn't had this sequence applied (since 1.4.1). - system.cleanUp(); - system.beforeInitialize(); - system.initialize(new LoggingInitializationContext(environment), logConfig, logFile); - } - catch (Exception ex) { - PropertySourceBootstrapConfiguration.logger.warn("Error opening logging config file " + logConfig, ex); - } - } - } - - private void setLogLevels(ConfigurableApplicationContext applicationContext, ConfigurableEnvironment environment) { - LoggingRebinder rebinder = new LoggingRebinder(); - rebinder.setEnvironment(environment); - // We can't fire the event in the ApplicationContext here (too early), but we can - // create our own listener and poke it (it doesn't need the key changes) - rebinder.onApplicationEvent(new EnvironmentChangeEvent(applicationContext, Collections.emptySet())); - } - - private void insertPropertySources(MutablePropertySources propertySources, List> composite) { - MutablePropertySources incoming = new MutablePropertySources(); - List> reversedComposite = new ArrayList<>(composite); - // Reverse the list so that when we call addFirst below we are maintaining the - // same order of PropertySources - // Wherever we call addLast we can use the order in the List since the first item - // will end up before the rest - Collections.reverse(reversedComposite); - for (PropertySource p : reversedComposite) { - incoming.addFirst(p); - } - PropertySourceBootstrapProperties remoteProperties = new PropertySourceBootstrapProperties(); - Binder.get(environment(incoming)).bind("spring.cloud.config", Bindable.ofInstance(remoteProperties)); - if (!remoteProperties.isAllowOverride() - || (!remoteProperties.isOverrideNone() && remoteProperties.isOverrideSystemProperties())) { - for (PropertySource p : reversedComposite) { - if (propertySources.contains(DECRYPTED_PROPERTY_SOURCE_NAME)) { - propertySources.addAfter(DECRYPTED_PROPERTY_SOURCE_NAME, p); - } - else { - propertySources.addFirst(p); - } - } - return; - } - if (remoteProperties.isOverrideNone()) { - for (PropertySource p : composite) { - propertySources.addLast(p); - } - return; - } - if (propertySources.contains(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)) { - if (!remoteProperties.isOverrideSystemProperties()) { - for (PropertySource p : reversedComposite) { - propertySources.addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, p); - } - } - else { - for (PropertySource p : composite) { - propertySources.addBefore(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, p); - } - } - } - else { - for (PropertySource p : composite) { - propertySources.addLast(p); - } - } - } - - private Environment environment(MutablePropertySources incoming) { - ConfigurableEnvironment environment = new AbstractEnvironment() { - }; - for (PropertySource source : incoming) { - environment.getPropertySources().addLast(source); - } - return environment; - } - - private void handleProfiles(ConfigurableEnvironment environment) { - if (bootstrapProperties.isInitializeOnContextRefresh() && !environment.getPropertySources() - .contains(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - // In the case that spring.cloud.config.initialize-on-context-refresh is true - // this method will - // be called during the bootstrap phase and the main application startup. We - // only manipulate the environment profiles in the bootstrap phase as we are - // fetching - // any additional profile specific configuration when this method would be - // called during the - // main application startup, and it is not valid to activate profiles in - // profile specific - // configuration properties, so we should not run this method then. - return; - } - Set includeProfiles = new TreeSet<>(); - List activeProfiles = new ArrayList<>(); - - for (PropertySource propertySource : environment.getPropertySources()) { - addIncludedProfilesTo(includeProfiles, propertySource, environment); - addActiveProfilesTo(activeProfiles, propertySource, environment); - } - - // If it's already accepted we assume the order was set intentionally - includeProfiles.removeAll(activeProfiles); - // Prepend each added profile (last wins in a property key clash) - for (String profile : includeProfiles) { - activeProfiles.add(0, profile); - } - List activeProfilesFromEnvironment = Arrays.stream(environment.getActiveProfiles()) - .collect(Collectors.toList()); - if (!activeProfiles.containsAll(activeProfilesFromEnvironment)) { - activeProfiles.addAll(activeProfilesFromEnvironment); - - } - environment.setActiveProfiles(activeProfiles.toArray(new String[activeProfiles.size()])); - } - - private Set addIncludedProfilesTo(Set profiles, PropertySource propertySource, - ConfigurableEnvironment environment) { - return addProfilesTo(profiles, propertySource, Profiles.INCLUDE_PROFILES_PROPERTY_NAME, environment); - } - - private List addActiveProfilesTo(List profiles, PropertySource propertySource, - ConfigurableEnvironment environment) { - return addProfilesTo(profiles, propertySource, AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, environment); - } - - private > T addProfilesTo(T profiles, PropertySource propertySource, - String property, ConfigurableEnvironment environment) { - if (propertySource instanceof CompositePropertySource) { - for (PropertySource nestedPropertySource : ((CompositePropertySource) propertySource) - .getPropertySources()) { - addProfilesTo(profiles, nestedPropertySource, property, environment); - } - } - else { - Collections.addAll(profiles, getProfilesForValue( - propertySource.getProperty(BootstrapConfigFileApplicationListener.INCLUDE_PROFILES_PROPERTY), - environment)); - } - return profiles; - } - - private String[] getProfilesForValue(Object property, ConfigurableEnvironment environment) { - final String value = (property == null ? null : property.toString()); - return property == null ? new String[0] : resolvePlaceholdersInProfiles(value, environment); - } - - private String[] resolvePlaceholdersInProfiles(String profiles, ConfigurableEnvironment environment) { - return Arrays.stream(StringUtils.tokenizeToStringArray(profiles, ",")).map(s -> { - if (s.startsWith("${") && s.endsWith("}")) { - return environment.resolvePlaceholders(s); - } - else { - return s; - } - }).toArray(String[]::new); - } - - /* - * The ConextRefreshedEvent gets called at the end of the boostrap phase after config - * data is loaded during bootstrap. This will run and do an "initial fetch" of - * configuration data during bootstrap but before the main applicaiton context starts. - */ - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - if (bootstrapProperties.isInitializeOnContextRefresh() - && event.getApplicationContext() instanceof ConfigurableApplicationContext) { - if (((ConfigurableApplicationContext) event.getApplicationContext()).getEnvironment().getPropertySources() - .contains(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - doInitialize((ConfigurableApplicationContext) event.getApplicationContext()); - } - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapProperties.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapProperties.java deleted file mode 100644 index 01164988..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapProperties.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.config; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Properties for Spring Cloud Config bootstrap. - * - * @author Dave Syer - */ -@ConfigurationProperties("spring.cloud.config") -public class PropertySourceBootstrapProperties { - - /** - * Flag to indicate that the external properties should override system properties. - * Default true. - */ - private boolean overrideSystemProperties = true; - - /** - * Flag to indicate that {@link #isOverrideSystemProperties() - * systemPropertiesOverride} can be used. Set to false to prevent users from changing - * the default accidentally. Default true. - */ - private boolean allowOverride = true; - - /** - * Flag to indicate that when {@link #setAllowOverride(boolean) allowOverride} is - * true, external properties should take lowest priority and should not override any - * existing property sources (including local config files). Default false. - */ - private boolean overrideNone = false; - - /** - * Flag to initialize bootstrap configuration on context refresh event. Default false. - */ - private boolean initializeOnContextRefresh = false; - - public boolean isInitializeOnContextRefresh() { - return initializeOnContextRefresh; - } - - public void setInitializeOnContextRefresh(boolean initializeOnContextRefresh) { - this.initializeOnContextRefresh = initializeOnContextRefresh; - } - - public boolean isOverrideNone() { - return this.overrideNone; - } - - public void setOverrideNone(boolean overrideNone) { - this.overrideNone = overrideNone; - } - - public boolean isOverrideSystemProperties() { - return this.overrideSystemProperties; - } - - public void setOverrideSystemProperties(boolean overrideSystemProperties) { - this.overrideSystemProperties = overrideSystemProperties; - } - - public boolean isAllowOverride() { - return this.allowOverride; - } - - public void setAllowOverride(boolean allowOverride) { - this.allowOverride = allowOverride; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceLocator.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceLocator.java deleted file mode 100644 index 2e68699e..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceLocator.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.config; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.Environment; -import org.springframework.core.env.PropertySource; - -/** - * Strategy for locating (possibly remote) property sources for the Environment. - * Implementations should not fail unless they intend to prevent the application from - * starting. - * - * @author Dave Syer - * - */ -public interface PropertySourceLocator { - - /** - * @param environment The current Environment. - * @return A PropertySource, or null if there is none. - * @throws IllegalStateException if there is a fail-fast condition. - */ - PropertySource locate(Environment environment); - - default Collection> locateCollection(Environment environment) { - return locateCollection(this, environment); - } - - static Collection> locateCollection(PropertySourceLocator locator, Environment environment) { - PropertySource propertySource = locator.locate(environment); - if (propertySource == null) { - return Collections.emptyList(); - } - if (propertySource instanceof CompositePropertySource) { - Collection> sources = ((CompositePropertySource) propertySource).getPropertySources(); - List> filteredSources = new ArrayList<>(); - for (PropertySource p : sources) { - if (p != null) { - filteredSources.add(p); - } - } - return filteredSources; - } - else { - return List.of(propertySource); - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/SimpleBootstrapPropertySource.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/SimpleBootstrapPropertySource.java deleted file mode 100644 index f0132c7a..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/SimpleBootstrapPropertySource.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.config; - -import org.springframework.core.env.PropertySource; - -import static org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME; - -/** - * Simple, non-enumerable PropertySource wrapper. - * - * @author Ryan Baxter - */ -public class SimpleBootstrapPropertySource extends PropertySource { - - private PropertySource delegate; - - public SimpleBootstrapPropertySource(PropertySource delegate) { - super(BOOTSTRAP_PROPERTY_SOURCE_NAME + "-" + delegate.getName(), delegate.getSource()); - this.delegate = delegate; - } - - @Override - public Object getProperty(String name) { - return this.delegate.getProperty(name); - } - - public PropertySource getDelegate() { - return delegate; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java deleted file mode 100644 index 76cbceba..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/AbstractEnvironmentDecrypt.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.PropertySources; -import org.springframework.security.crypto.encrypt.TextEncryptor; - -/** - * Abstract class that handles decrypting and merging of PropertySources. - */ -public abstract class AbstractEnvironmentDecrypt { - - private static final Pattern COLLECTION_PROPERTY = Pattern.compile("(\\S+)?\\[(\\d+)\\](\\.\\S+)?"); - - /** - * Name of the decrypted property source. - */ - public static final String DECRYPTED_PROPERTY_SOURCE_NAME = "decrypted"; - - /** - * Prefix indicating an encrypted value. - */ - public static final String ENCRYPTED_PROPERTY_PREFIX = "{cipher}"; - - protected Log logger = LogFactory.getLog(getClass()); - - private boolean failOnError = true; - - /** - * Strategy to determine how to handle exceptions during decryption. - * @param failOnError the flag value (default true) - */ - public void setFailOnError(boolean failOnError) { - this.failOnError = failOnError; - } - - public boolean isFailOnError() { - return this.failOnError; - } - - protected Map decrypt(TextEncryptor encryptor, PropertySources propertySources) { - Map properties = merge(propertySources); - decrypt(encryptor, properties); - return properties; - } - - protected Map merge(PropertySources propertySources) { - Map properties = new LinkedHashMap<>(); - List> sources = new ArrayList<>(); - for (PropertySource source : propertySources) { - sources.add(0, source); - } - for (PropertySource source : sources) { - merge(source, properties); - } - return properties; - } - - protected void merge(PropertySource source, Map properties) { - if (source instanceof CompositePropertySource) { - - List> sources = new ArrayList<>(((CompositePropertySource) source).getPropertySources()); - Collections.reverse(sources); - - for (PropertySource nested : sources) { - merge(nested, properties); - } - - } - else if (source instanceof EnumerablePropertySource enumerable) { - Map otherCollectionProperties = new LinkedHashMap<>(); - boolean sourceHasDecryptedCollection = false; - - for (String key : enumerable.getPropertyNames()) { - Object property = source.getProperty(key); - if (property != null) { - String value = property.toString(); - if (value.startsWith(ENCRYPTED_PROPERTY_PREFIX)) { - properties.put(key, value); - if (COLLECTION_PROPERTY.matcher(key).matches()) { - sourceHasDecryptedCollection = true; - } - } - else if (COLLECTION_PROPERTY.matcher(key).matches()) { - // put non-encrypted properties so merging of index properties - // happens correctly - otherCollectionProperties.put(key, value); - } - else { - // override previously encrypted with non-encrypted property - properties.remove(key); - } - } - } - // copy all indexed properties even if not encrypted - if (sourceHasDecryptedCollection && !otherCollectionProperties.isEmpty()) { - properties.putAll(otherCollectionProperties); - } - - } - } - - protected void decrypt(TextEncryptor encryptor, Map properties) { - properties.replaceAll((key, value) -> { - String valueString = value.toString(); - if (!valueString.startsWith(ENCRYPTED_PROPERTY_PREFIX)) { - return value; - } - return decrypt(encryptor, key, valueString); - }); - } - - protected String decrypt(TextEncryptor encryptor, String key, String original) { - String value = original.substring(ENCRYPTED_PROPERTY_PREFIX.length()); - try { - value = encryptor.decrypt(value); - if (logger.isDebugEnabled()) { - logger.debug("Decrypted: key=" + key); - } - return value; - } - catch (Exception e) { - String message = "Cannot decrypt: key=" + key; - if (logger.isDebugEnabled()) { - logger.warn(message, e); - } - else { - logger.warn(message); - } - if (this.failOnError) { - throw new IllegalStateException(message, e); - } - return ""; - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/DecryptEnvironmentPostProcessor.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/DecryptEnvironmentPostProcessor.java deleted file mode 100644 index 18d82a52..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/DecryptEnvironmentPostProcessor.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import java.util.Map; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.core.Ordered; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.SystemEnvironmentPropertySource; -import org.springframework.util.ClassUtils; - -import static org.springframework.cloud.util.PropertyUtils.bootstrapEnabled; -import static org.springframework.cloud.util.PropertyUtils.useLegacyProcessing; - -/** - * Decrypt properties from the environment and insert them with high priority so they - * override the encrypted values. - * - * @author Dave Syer - * @author Tim Ysewyn - */ -public class DecryptEnvironmentPostProcessor extends AbstractEnvironmentDecrypt - implements EnvironmentPostProcessor, Ordered { - - private int order = Ordered.LOWEST_PRECEDENCE; - - @Override - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - if (bootstrapEnabled(environment) || useLegacyProcessing(environment) || !isEnabled(environment)) { - return; - } - if (!ClassUtils.isPresent("org.springframework.security.crypto.encrypt.TextEncryptor", null)) { - return; - } - - MutablePropertySources propertySources = environment.getPropertySources(); - - environment.getPropertySources().remove(DECRYPTED_PROPERTY_SOURCE_NAME); - - Map map = TextEncryptorUtils.decrypt(this, environment, propertySources); - if (!map.isEmpty()) { - // We have some decrypted properties - propertySources.addFirst(new SystemEnvironmentPropertySource(DECRYPTED_PROPERTY_SOURCE_NAME, map)); - } - - } - - protected Boolean isEnabled(ConfigurableEnvironment environment) { - return environment.getProperty("spring.cloud.decrypt-environment-post-processor.enabled", Boolean.class, true); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java deleted file mode 100644 index ee25d77e..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionOutcome; -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.SpringBootCondition; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.context.encrypt.EncryptorFactory; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.type.AnnotatedTypeMetadata; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.security.rsa.crypto.RsaSecretEncryptor; -import org.springframework.util.StringUtils; - -/** - * @author Dave Syer - * - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ TextEncryptor.class }) -@EnableConfigurationProperties -public class EncryptionBootstrapConfiguration { - - @Bean - @ConditionalOnMissingBean - public KeyProperties keyProperties() { - return new KeyProperties(); - } - - @Bean - public EnvironmentDecryptApplicationInitializer environmentDecryptApplicationListener( - ConfigurableApplicationContext context, KeyProperties keyProperties) { - TextEncryptor encryptor; - try { - encryptor = context.getBean(TextEncryptor.class); - } - catch (NoSuchBeanDefinitionException e) { - encryptor = new TextEncryptorUtils.FailsafeTextEncryptor(); - } - EnvironmentDecryptApplicationInitializer listener = new EnvironmentDecryptApplicationInitializer(encryptor); - listener.setFailOnError(keyProperties.isFailOnError()); - return listener; - } - - @Deprecated - public static TextEncryptor createTextEncryptor(KeyProperties keyProperties, RsaProperties rsaProperties) { - return TextEncryptorUtils.createTextEncryptor(keyProperties, rsaProperties); - } - - @Configuration(proxyBeanMethods = false) - @Conditional(KeyCondition.class) - @ConditionalOnClass(RsaSecretEncryptor.class) - @EnableConfigurationProperties - protected static class RsaEncryptionConfiguration { - - @Bean - @ConditionalOnMissingBean - public RsaProperties rsaProperties() { - return new RsaProperties(); - } - - @Bean - @ConditionalOnMissingBean(TextEncryptor.class) - public TextEncryptor textEncryptor(KeyProperties keyProperties, RsaProperties rsaProperties) { - return TextEncryptorUtils.createTextEncryptor(keyProperties, rsaProperties); - } - - } - - @Configuration(proxyBeanMethods = false) - @Conditional(KeyCondition.class) - @ConditionalOnMissingClass("org.springframework.security.rsa.crypto.RsaSecretEncryptor") - protected static class VanillaEncryptionConfiguration { - - @Autowired - private KeyProperties key; - - @Bean - @ConditionalOnMissingBean(TextEncryptor.class) - public TextEncryptor textEncryptor() { - return new EncryptorFactory(this.key.getSalt()).create(this.key.getKey()); - } - - } - - /** - * A Spring Boot condition for key encryption. - */ - public static class KeyCondition extends SpringBootCondition { - - @Override - public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { - Environment environment = context.getEnvironment(); - if (hasProperty(environment, "encrypt.key-store.location")) { - if (hasProperty(environment, "encrypt.key-store.password")) { - return ConditionOutcome.match("Keystore found in Environment"); - } - return ConditionOutcome.noMatch("Keystore found but no password in Environment"); - } - else if (hasProperty(environment, "encrypt.key")) { - return ConditionOutcome.match("Key found in Environment"); - } - return ConditionOutcome.noMatch("Keystore nor key found in Environment"); - } - - private boolean hasProperty(Environment environment, String key) { - String value = environment.getProperty(key); - if (value == null) { - return false; - } - return StringUtils.hasText(environment.resolvePlaceholders(value)); - } - - } - - @Deprecated - protected static class FailsafeTextEncryptor extends TextEncryptorUtils.FailsafeTextEncryptor { - - } - - class EncryptionHints implements RuntimeHintsRegistrar { - - @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - hints.reflection().registerTypeIfPresent(classLoader, - "org.springframework.security.rsa.crypto.RsaSecretEncryptor", - MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java deleted file mode 100644 index 10251059..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.cloud.bootstrap.BootstrapApplicationListener; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.Ordered; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.SystemEnvironmentPropertySource; -import org.springframework.security.crypto.encrypt.TextEncryptor; - -import static org.springframework.cloud.util.PropertyUtils.bootstrapEnabled; -import static org.springframework.cloud.util.PropertyUtils.useLegacyProcessing; - -/** - * Decrypt properties from the environment and insert them with high priority so they - * override the encrypted values. - * - * @author Dave Syer - * @author Tim Ysewyn - */ -public class EnvironmentDecryptApplicationInitializer extends AbstractEnvironmentDecrypt - implements ApplicationContextInitializer, Ordered { - - /** - * Name of the decrypted bootstrap property source. - */ - public static final String DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME = "decryptedBootstrap"; - - private int order = Ordered.HIGHEST_PRECEDENCE + 15; - - private TextEncryptor encryptor; - - public EnvironmentDecryptApplicationInitializer(TextEncryptor encryptor) { - this.encryptor = encryptor; - } - - @Override - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - ConfigurableEnvironment environment = applicationContext.getEnvironment(); - if (!bootstrapEnabled(environment) && !useLegacyProcessing(environment)) { - return; - } - - MutablePropertySources propertySources = environment.getPropertySources(); - - Set found = new LinkedHashSet<>(); - if (!propertySources.contains(DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - // No reason to decrypt bootstrap twice - PropertySource bootstrap = propertySources - .get(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME); - if (bootstrap != null) { - Map map = decrypt(bootstrap); - if (!map.isEmpty()) { - found.addAll(map.keySet()); - insert(applicationContext, - new SystemEnvironmentPropertySource(DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME, map)); - } - } - } - removeDecryptedProperties(applicationContext); - Map map = decrypt(this.encryptor, propertySources); - if (!map.isEmpty()) { - // We have some decrypted properties - found.addAll(map.keySet()); - insert(applicationContext, new SystemEnvironmentPropertySource(DECRYPTED_PROPERTY_SOURCE_NAME, map)); - } - if (!found.isEmpty()) { - ApplicationContext parent = applicationContext.getParent(); - if (parent != null) { - // The parent is actually the bootstrap context, and it is fully - // initialized, so we can fire an EnvironmentChangeEvent there to rebind - // @ConfigurationProperties, in case they were encrypted. - parent.publishEvent(new EnvironmentChangeEvent(parent, found)); - } - - } - } - - private void insert(ApplicationContext applicationContext, PropertySource propertySource) { - ApplicationContext parent = applicationContext; - while (parent != null) { - if (parent.getEnvironment() instanceof ConfigurableEnvironment mutable) { - insert(mutable.getPropertySources(), propertySource); - } - parent = parent.getParent(); - } - } - - private void insert(MutablePropertySources propertySources, PropertySource propertySource) { - if (propertySources.contains(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - if (DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME.equals(propertySource.getName())) { - propertySources.addBefore(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME, propertySource); - } - else { - propertySources.addAfter(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME, propertySource); - } - } - else { - propertySources.addFirst(propertySource); - } - } - - private void removeDecryptedProperties(ApplicationContext applicationContext) { - ApplicationContext parent = applicationContext; - while (parent != null) { - if (parent.getEnvironment() instanceof ConfigurableEnvironment) { - ((ConfigurableEnvironment) parent.getEnvironment()).getPropertySources() - .remove(DECRYPTED_PROPERTY_SOURCE_NAME); - } - parent = parent.getParent(); - } - } - - private Map decrypt(PropertySource source) { - Map properties = merge(source); - decrypt(this.encryptor, properties); - return properties; - } - - private Map merge(PropertySource source) { - Map properties = new LinkedHashMap<>(); - merge(source, properties); - return properties; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/KeyProperties.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/KeyProperties.java deleted file mode 100644 index 112f79b8..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/KeyProperties.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.Resource; - -/** - * Key encryption properties. - * - * @author Dave Syer - */ -@ConfigurationProperties(KeyProperties.PREFIX) -public class KeyProperties { - - /** - * ConfigurationProperties prefix for KeyProperties. - */ - public static final String PREFIX = "encrypt"; - - /** - * A symmetric key. As a stronger alternative, consider using a keystore. - */ - private String key; - - /** - * A salt for the symmetric key, in the form of a hex-encoded byte array. As a - * stronger alternative, consider using a keystore. - */ - private String salt = "deadbeef"; - - /** - * Flag to say that a process should fail if there is an encryption or decryption - * error. - */ - private boolean failOnError = true; - - /** - * The key store properties for locating a key in a Java Key Store (a file in a format - * defined and understood by the JVM). - */ - private KeyStore keyStore = new KeyStore(); - - public boolean isFailOnError() { - return this.failOnError; - } - - public void setFailOnError(boolean failOnError) { - this.failOnError = failOnError; - } - - public String getKey() { - return this.key; - } - - public void setKey(String key) { - this.key = key; - } - - public String getSalt() { - return this.salt; - } - - public void setSalt(String salt) { - this.salt = salt; - } - - public KeyStore getKeyStore() { - return this.keyStore; - } - - public void setKeyStore(KeyProperties.KeyStore keyStore) { - this.keyStore = keyStore; - } - - /** - * Key store properties. - */ - public static class KeyStore { - - /** - * Location of the key store file, e.g. classpath:/keystore.jks. - */ - private Resource location; - - /** - * Password that locks the keystore. - */ - private String password; - - /** - * Alias for a key in the store. - */ - private String alias; - - /** - * Secret protecting the key (defaults to the same as the password). - */ - private String secret; - - /** - * The KeyStore type. Defaults to jks. - */ - private String type = "jks"; - - public String getAlias() { - return this.alias; - } - - public void setAlias(String alias) { - this.alias = alias; - } - - public Resource getLocation() { - return this.location; - } - - public void setLocation(Resource location) { - this.location = location; - } - - public String getPassword() { - return this.password; - } - - public String getType() { - return type; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getSecret() { - return this.secret == null ? this.password : this.secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public void setType(String type) { - this.type = type; - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/RsaProperties.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/RsaProperties.java deleted file mode 100644 index 6f931883..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/RsaProperties.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.security.rsa.crypto.RsaAlgorithm; - -/** - * @author Ryan Baxter - */ -@ConditionalOnClass(RsaAlgorithm.class) -@ConfigurationProperties(RsaProperties.PREFIX) -public class RsaProperties { - - /** - * ConfigurationProperties prefix for RsaProperties. - */ - public static final String PREFIX = "encrypt.rsa"; - - /** - * The RSA algorithm to use (DEFAULT or OEAP). Once it is set, do not change it (or - * existing ciphers will not be decryptable). - */ - private RsaAlgorithm algorithm = RsaAlgorithm.DEFAULT; - - /** - * Flag to indicate that "strong" AES encryption should be used internally. If true, - * then the GCM algorithm is applied to the AES encrypted bytes. Default is false (in - * which case "standard" CBC is used instead). Once it is set, do not change it (or - * existing ciphers will not be decryptable). - */ - private boolean strong = false; - - /** - * Salt for the random secret used to encrypt cipher text. Once it is set, do not - * change it (or existing ciphers will not be decryptable). - */ - private String salt = "deadbeef"; - - public RsaAlgorithm getAlgorithm() { - return this.algorithm; - } - - public void setAlgorithm(RsaAlgorithm algorithm) { - this.algorithm = algorithm; - } - - public boolean isStrong() { - return this.strong; - } - - public void setStrong(boolean strong) { - this.strong = strong; - } - - public String getSalt() { - return this.salt; - } - - public void setSalt(String salt) { - this.salt = salt; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/TextEncryptorUtils.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/TextEncryptorUtils.java deleted file mode 100644 index 5571e46d..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/TextEncryptorUtils.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import java.util.Map; - -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.BootstrapContext; -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.context.properties.bind.BindHandler; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.cloud.bootstrap.TextEncryptorBindHandler; -import org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper; -import org.springframework.cloud.context.encrypt.EncryptorFactory; -import org.springframework.cloud.util.PropertyUtils; -import org.springframework.context.ApplicationContext; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.security.rsa.crypto.KeyStoreKeyFactory; -import org.springframework.security.rsa.crypto.RsaSecretEncryptor; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -public abstract class TextEncryptorUtils { - - /** - * Decrypt environment. See {@link DecryptEnvironmentPostProcessor}. - * @param decryptor the {@link AbstractEnvironmentDecrypt} - * @param environment the environment to get key properties from. - * @param propertySources the property sources to decrypt. - * @return the decrypted properties. - */ - static Map decrypt(AbstractEnvironmentDecrypt decryptor, ConfigurableEnvironment environment, - MutablePropertySources propertySources) { - TextEncryptor encryptor = getTextEncryptor(decryptor, environment); - return decryptor.decrypt(encryptor, propertySources); - } - - static TextEncryptor getTextEncryptor(AbstractEnvironmentDecrypt decryptor, ConfigurableEnvironment environment) { - Binder binder = Binder.get(environment); - KeyProperties keyProperties = binder.bind(KeyProperties.PREFIX, KeyProperties.class) - .orElseGet(KeyProperties::new); - if (TextEncryptorUtils.keysConfigured(keyProperties)) { - decryptor.setFailOnError(keyProperties.isFailOnError()); - if (ClassUtils.isPresent("org.springframework.security.rsa.crypto.RsaSecretEncryptor", null)) { - RsaProperties rsaProperties = binder.bind(RsaProperties.PREFIX, RsaProperties.class) - .orElseGet(RsaProperties::new); - return TextEncryptorUtils.createTextEncryptor(keyProperties, rsaProperties); - } - return new EncryptorFactory(keyProperties.getSalt()).create(keyProperties.getKey()); - } - // no keys configured - return new TextEncryptorUtils.FailsafeTextEncryptor(); - } - - /** - * Register all classes that need a {@link TextEncryptor} in - * {@link TextEncryptorConfigBootstrapper}. - * @param registry the BootstrapRegistry. - */ - public static void register(BootstrapRegistry registry) { - registry.registerIfAbsent(TextEncryptor.class, context -> { - KeyProperties keyProperties = context.get(KeyProperties.class); - if (TextEncryptorConfigBootstrapper.keysConfigured(keyProperties)) { - if (TextEncryptorConfigBootstrapper.RSA_IS_PRESENT) { - RsaProperties rsaProperties = context.get(RsaProperties.class); - return createTextEncryptor(keyProperties, rsaProperties); - } - return new EncryptorFactory(keyProperties.getSalt()).create(keyProperties.getKey()); - } - // no keys configured - return new FailsafeTextEncryptor(); - }); - registry.registerIfAbsent(BindHandler.class, context -> { - TextEncryptor textEncryptor = context.get(TextEncryptor.class); - if (textEncryptor != null) { - KeyProperties keyProperties = context.get(KeyProperties.class); - return new TextEncryptorBindHandler(textEncryptor, keyProperties); - } - return null; - }); - } - - /** - * Promote the {@link TextEncryptor} to the {@link ApplicationContext}. - * @param bootstrapContext the Context. - * @param beanFactory the bean factory. - */ - public static void promote(BootstrapContext bootstrapContext, ConfigurableListableBeanFactory beanFactory) { - TextEncryptor textEncryptor = bootstrapContext.get(TextEncryptor.class); - if (textEncryptor != null) { - beanFactory.registerSingleton("textEncryptor", textEncryptor); - } - } - - /** - * Utility to create a {@link TextEncryptor} via properties. - * @param keyProperties the Key properties. - * @param rsaProperties RSA properties. - * @return created {@link TextEncryptor}. - */ - public static TextEncryptor createTextEncryptor(KeyProperties keyProperties, RsaProperties rsaProperties) { - KeyProperties.KeyStore keyStore = keyProperties.getKeyStore(); - if (keyStore.getLocation() != null) { - if (keyStore.getLocation().exists()) { - return new RsaSecretEncryptor( - new KeyStoreKeyFactory(keyStore.getLocation(), keyStore.getPassword().toCharArray(), - keyStore.getType()).getKeyPair(keyStore.getAlias(), keyStore.getSecret().toCharArray()), - rsaProperties.getAlgorithm(), rsaProperties.getSalt(), rsaProperties.isStrong()); - } - - throw new IllegalStateException("Invalid keystore location"); - } - - return new EncryptorFactory(keyProperties.getSalt()).create(keyProperties.getKey()); - } - - /** - * Is a key configured. - * @param properties the Key properties. - * @return true if configured. - */ - public static boolean keysConfigured(KeyProperties properties) { - if (hasProperty(properties.getKeyStore().getLocation())) { - if (hasProperty(properties.getKeyStore().getPassword())) { - return true; - } - return false; - } - else if (hasProperty(properties.getKey())) { - return true; - } - return false; - } - - static boolean hasProperty(Object value) { - if (value instanceof String) { - return StringUtils.hasText((String) value); - } - return value != null; - } - - /** - * Method to check if legacy bootstrap mode is enabled. This is either if the boot - * legacy processing property is set or spring.cloud.bootstrap.enabled=true. - * @param environment where to check properties. - * @return true if bootstrap enabled. - */ - public static boolean isLegacyBootstrap(Environment environment) { - boolean isLegacy = PropertyUtils.useLegacyProcessing(environment); - boolean isBootstrapEnabled = PropertyUtils.bootstrapEnabled(environment); - return isLegacy || isBootstrapEnabled; - } - - /** - * TextEncryptor that just fails, so that users don't get a false sense of security - * adding ciphers to config files and not getting them decrypted. - * - * @author Dave Syer - * - */ - public static class FailsafeTextEncryptor implements TextEncryptor { - - @Override - public String encrypt(String text) { - throw new UnsupportedOperationException( - "No encryption for FailsafeTextEncryptor. Did you configure the keystore correctly?"); - } - - @Override - public String decrypt(String encryptedText) { - throw new UnsupportedOperationException( - "No decryption for FailsafeTextEncryptor. Did you configure the keystore correctly?"); - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/support/OriginTrackedCompositePropertySource.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/support/OriginTrackedCompositePropertySource.java deleted file mode 100644 index a169a511..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/support/OriginTrackedCompositePropertySource.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.support; - -import org.springframework.boot.origin.Origin; -import org.springframework.boot.origin.OriginLookup; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.PropertySource; - -public class OriginTrackedCompositePropertySource extends CompositePropertySource implements OriginLookup { - - /** - * Create a new {@code CompositePropertySource}. - * @param name the name of the property source - */ - public OriginTrackedCompositePropertySource(String name) { - super(name); - } - - @Override - @SuppressWarnings("unchecked") - public Origin getOrigin(String name) { - for (PropertySource propertySource : getPropertySources()) { - if (propertySource instanceof OriginLookup lookup) { - Origin origin = lookup.getOrigin(name); - if (origin != null) { - return origin; - } - } - } - return null; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/config/ContextRefreshedWithApplicationEvent.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/config/ContextRefreshedWithApplicationEvent.java deleted file mode 100644 index 796bd0c4..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/config/ContextRefreshedWithApplicationEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.config; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.event.SpringApplicationEvent; -import org.springframework.context.ConfigurableApplicationContext; - -/** - * A custom event for spring cloud context use cases that need the saved Spring - * Application. This prevents a duplicated ApplicationPreparedEvent from being - * republished. - */ -public class ContextRefreshedWithApplicationEvent extends SpringApplicationEvent { - - private final ConfigurableApplicationContext context; - - /** - * Create a new {@link ContextRefreshedWithApplicationEvent} instance. - * @param application the current application - * @param args the arguments the application is running with - * @param context the ApplicationContext about to be refreshed - */ - public ContextRefreshedWithApplicationEvent(SpringApplication application, String[] args, - ConfigurableApplicationContext context) { - super(application, args); - this.context = context; - } - - /** - * Return the application context. - * @return the context - */ - public ConfigurableApplicationContext getApplicationContext() { - return this.context; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java deleted file mode 100644 index dfea26ab..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.config.annotation; - -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.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.core.annotation.AliasFor; - -/** - * Convenience annotation to put a @Bean definition in - * {@link org.springframework.cloud.context.scope.refresh.RefreshScope refresh scope}. - * Beans annotated this way can be refreshed at runtime and any components that are using - * them will get a new instance on the next method call, fully initialized and injected - * with all dependencies. - * - * @author Dave Syer - * - */ -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Scope("refresh") -@Documented -public @interface RefreshScope { - - /** - * Alias for {@link Scope#proxyMode}. - * @see Scope#proxyMode() - * @return proxy mode - */ - @AliasFor(annotation = Scope.class) - ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/EncryptorFactory.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/EncryptorFactory.java deleted file mode 100644 index 1064704b..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/EncryptorFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.encrypt; - -import org.springframework.security.crypto.encrypt.Encryptors; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.security.rsa.crypto.RsaSecretEncryptor; - -/** - * @author Dave Syer - * @author Biju Kunjummen - */ -public class EncryptorFactory { - - private String salt = "deadbeef"; - - public EncryptorFactory() { - } - - public EncryptorFactory(String salt) { - this.salt = salt; - } - - public TextEncryptor create(String data) { - - TextEncryptor encryptor; - if (data.contains("RSA PRIVATE KEY")) { - encryptor = new RsaSecretEncryptor(data.replaceAll("\\n *", "")); - } - else if (data.startsWith("ssh-rsa") || data.contains("RSA PUBLIC KEY")) { - throw new KeyFormatException(); - } - else { - encryptor = Encryptors.text(data, this.salt); - } - - return encryptor; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/KeyFormatException.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/KeyFormatException.java deleted file mode 100644 index 5429f3e7..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/encrypt/KeyFormatException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.encrypt; - -/** - * Exception related to the format of key. - * - * @author Dave Syer - */ -@SuppressWarnings("serial") -public class KeyFormatException extends RuntimeException { - - public KeyFormatException() { - super(); - } - - public KeyFormatException(Throwable t) { - super(t); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java deleted file mode 100644 index 749a72de..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.environment; - -import java.util.Set; - -import org.springframework.context.ApplicationEvent; -import org.springframework.core.env.Environment; - -/** - * Event published to signal a change in the {@link Environment}. - * - * @author Dave Syer - * - */ -@SuppressWarnings("serial") -public class EnvironmentChangeEvent extends ApplicationEvent { - - private Set keys; - - public EnvironmentChangeEvent(Set keys) { - // Backwards compatible constructor with less utility (practically no use at all) - this(keys, keys); - } - - public EnvironmentChangeEvent(Object context, Set keys) { - super(context); - this.keys = keys; - } - - /** - * @return The keys. - */ - public Set getKeys() { - return this.keys; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java deleted file mode 100644 index 5cbe4688..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.environment; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.stereotype.Component; - -/** - * Entry point for making local (but volatile) changes to the {@link Environment} of a - * running application. Allows properties to be added and values changed, simply by adding - * them to a high-priority property source in the existing Environment. - * - * @author Dave Syer - * - */ -@Component -@ManagedResource -public class EnvironmentManager implements ApplicationEventPublisherAware { - - private static final String MANAGER_PROPERTY_SOURCE = "manager"; - - private Map map = new LinkedHashMap<>(); - - private ConfigurableEnvironment environment; - - private ApplicationEventPublisher publisher; - - public EnvironmentManager(ConfigurableEnvironment environment) { - this.environment = environment; - MutablePropertySources sources = environment.getPropertySources(); - if (sources.contains(MANAGER_PROPERTY_SOURCE)) { - @SuppressWarnings("unchecked") - Map map = (Map) sources.get(MANAGER_PROPERTY_SOURCE).getSource(); - this.map = map; - } - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; - } - - @ManagedOperation - public Map reset() { - Map result = new LinkedHashMap<>(this.map); - if (!this.map.isEmpty()) { - this.map.clear(); - publish(new EnvironmentChangeEvent(this.publisher, result.keySet())); - } - return result; - } - - @ManagedOperation - public void setProperty(String name, String value) { - - if (!this.environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) { - synchronized (this.map) { - if (!this.environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) { - MapPropertySource source = new MapPropertySource(MANAGER_PROPERTY_SOURCE, this.map); - this.environment.getPropertySources().addFirst(source); - } - } - } - - if (!value.equals(this.environment.getProperty(name))) { - this.map.put(name, value); - publish(new EnvironmentChangeEvent(this.publisher, Collections.singleton(name))); - } - - } - - @ManagedOperation - public Object getProperty(String name) { - return this.environment.getProperty(name); - } - - private void publish(EnvironmentChangeEvent environmentChangeEvent) { - if (this.publisher != null) { - this.publisher.publishEvent(environmentChangeEvent); - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpoint.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpoint.java deleted file mode 100644 index 0347a408..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpoint.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.environment; - -import org.springframework.boot.actuate.endpoint.SanitizingFunction; -import org.springframework.boot.actuate.endpoint.Show; -import org.springframework.boot.actuate.env.EnvironmentEndpoint; -import org.springframework.core.env.Environment; - -/** - * An extension of the standard {@link EnvironmentEndpoint} that allows to modify the - * environment at runtime. - * - * @author Stephane Nicoll - * @since 2.0.0 - */ -public class WritableEnvironmentEndpoint extends EnvironmentEndpoint { - - public WritableEnvironmentEndpoint(Environment environment, Iterable sanitizingFunctions, - Show showValues) { - super(environment, sanitizingFunctions, showValues); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpointWebExtension.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpointWebExtension.java deleted file mode 100644 index 3d2f0130..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/environment/WritableEnvironmentEndpointWebExtension.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.environment; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -import org.springframework.boot.actuate.endpoint.Show; -import org.springframework.boot.actuate.endpoint.annotation.DeleteOperation; -import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; -import org.springframework.boot.actuate.endpoint.web.annotation.EndpointWebExtension; -import org.springframework.boot.actuate.env.EnvironmentEndpointWebExtension; - -/** - * MVC endpoint for the {@link EnvironmentManager}, providing a POST to /env as a simple - * way to change the Environment. - * - * @author Dave Syer - * - */ -@EndpointWebExtension(endpoint = WritableEnvironmentEndpoint.class) -public class WritableEnvironmentEndpointWebExtension extends EnvironmentEndpointWebExtension { - - private EnvironmentManager environment; - - public WritableEnvironmentEndpointWebExtension(WritableEnvironmentEndpoint endpoint, EnvironmentManager environment, - Show showValues, Set roles) { - super(endpoint, showValues, roles); - this.environment = environment; - } - - @WriteOperation - public Object write(String name, String value) { - this.environment.setProperty(name, value); - return Collections.singletonMap(name, value); - } - - @DeleteOperation - public Map reset() { - return this.environment.reset(); - } - - public void setEnvironmentManager(EnvironmentManager environment) { - this.environment = environment; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/named/ClientFactoryObjectProvider.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/named/ClientFactoryObjectProvider.java deleted file mode 100644 index 2ce04041..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/named/ClientFactoryObjectProvider.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.named; - -import java.util.Iterator; -import java.util.Spliterator; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Stream; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.lang.Nullable; - -/** - * Special ObjectProvider that allows the actual ObjectProvider to be resolved later - * because of the creation of the named child context. - * - * @param - type of the provided object - */ -class ClientFactoryObjectProvider implements ObjectProvider { - - private final NamedContextFactory clientFactory; - - private final String name; - - private final Class type; - - private ObjectProvider provider; - - ClientFactoryObjectProvider(NamedContextFactory clientFactory, String name, Class type) { - this.clientFactory = clientFactory; - this.name = name; - this.type = type; - } - - @Override - public T getObject(Object... args) throws BeansException { - return delegate().getObject(args); - } - - @Override - @Nullable - public T getIfAvailable() throws BeansException { - return delegate().getIfAvailable(); - } - - @Override - public T getIfAvailable(Supplier defaultSupplier) throws BeansException { - return delegate().getIfAvailable(defaultSupplier); - } - - @Override - public void ifAvailable(Consumer dependencyConsumer) throws BeansException { - delegate().ifAvailable(dependencyConsumer); - } - - @Override - @Nullable - public T getIfUnique() throws BeansException { - return delegate().getIfUnique(); - } - - @Override - public T getIfUnique(Supplier defaultSupplier) throws BeansException { - return delegate().getIfUnique(defaultSupplier); - } - - @Override - public void ifUnique(Consumer dependencyConsumer) throws BeansException { - delegate().ifUnique(dependencyConsumer); - } - - @Override - public Iterator iterator() { - return delegate().iterator(); - } - - @Override - public Stream stream() { - return delegate().stream(); - } - - @Override - public T getObject() throws BeansException { - return delegate().getObject(); - } - - @Override - public void forEach(Consumer action) { - delegate().forEach(action); - } - - @Override - public Spliterator spliterator() { - return delegate().spliterator(); - } - - private ObjectProvider delegate() { - if (this.provider == null) { - this.provider = this.clientFactory.getProvider(this.name, this.type); - } - return this.provider; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/named/NamedContextFactory.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/named/NamedContextFactory.java deleted file mode 100644 index b6ed94a7..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/named/NamedContextFactory.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.named; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.aot.AotDetector; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.AnnotationConfigRegistry; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.ResolvableType; -import org.springframework.core.env.MapPropertySource; -import org.springframework.util.Assert; - -/** - * Creates a set of child contexts that allows a set of Specifications to define the beans - * in each child context. - * - * Ported from spring-cloud-netflix FeignClientFactory and SpringClientFactory - * - * @param specification - * @author Spencer Gibb - * @author Dave Syer - * @author Tommy Karlsson - * @author Olga Maciaszek-Sharma - */ -public abstract class NamedContextFactory - implements DisposableBean, ApplicationContextAware { - - private final Map> applicationContextInitializers; - - private final String propertySourceName; - - private final String propertyName; - - private final Map contexts = new ConcurrentHashMap<>(); - - private Map configurations = new ConcurrentHashMap<>(); - - private ApplicationContext parent; - - private Class defaultConfigType; - - public NamedContextFactory(Class defaultConfigType, String propertySourceName, String propertyName) { - this(defaultConfigType, propertySourceName, propertyName, new HashMap<>()); - } - - public NamedContextFactory(Class defaultConfigType, String propertySourceName, String propertyName, - Map> applicationContextInitializers) { - this.defaultConfigType = defaultConfigType; - this.propertySourceName = propertySourceName; - this.propertyName = propertyName; - this.applicationContextInitializers = applicationContextInitializers; - } - - @Override - public void setApplicationContext(ApplicationContext parent) throws BeansException { - this.parent = parent; - } - - public ApplicationContext getParent() { - return parent; - } - - public void setConfigurations(List configurations) { - for (C client : configurations) { - this.configurations.put(client.getName(), client); - } - } - - public Set getContextNames() { - return new HashSet<>(this.contexts.keySet()); - } - - @Override - public void destroy() { - Collection values = this.contexts.values(); - for (GenericApplicationContext context : values) { - // This can fail, but it never throws an exception (you see stack traces - // logged as WARN). - context.close(); - } - this.contexts.clear(); - } - - protected GenericApplicationContext getContext(String name) { - if (!this.contexts.containsKey(name)) { - synchronized (this.contexts) { - if (!this.contexts.containsKey(name)) { - this.contexts.put(name, createContext(name)); - } - } - } - return this.contexts.get(name); - } - - public GenericApplicationContext createContext(String name) { - GenericApplicationContext context = buildContext(name); - // there's an AOT initializer for this context - if (applicationContextInitializers.get(name) != null) { - applicationContextInitializers.get(name).initialize(context); - context.refresh(); - return context; - } - registerBeans(name, context); - context.refresh(); - return context; - } - - public void registerBeans(String name, GenericApplicationContext context) { - Assert.isInstanceOf(AnnotationConfigRegistry.class, context); - AnnotationConfigRegistry registry = (AnnotationConfigRegistry) context; - if (this.configurations.containsKey(name)) { - for (Class configuration : this.configurations.get(name).getConfiguration()) { - registry.register(configuration); - } - } - for (Map.Entry entry : this.configurations.entrySet()) { - if (entry.getKey().startsWith("default.")) { - for (Class configuration : entry.getValue().getConfiguration()) { - registry.register(configuration); - } - } - } - registry.register(PropertyPlaceholderAutoConfiguration.class, this.defaultConfigType); - } - - public GenericApplicationContext buildContext(String name) { - // https://github.com/spring-cloud/spring-cloud-netflix/issues/3101 - // https://github.com/spring-cloud/spring-cloud-openfeign/issues/475 - ClassLoader classLoader = getClass().getClassLoader(); - GenericApplicationContext context; - if (this.parent != null) { - DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); - if (parent instanceof ConfigurableApplicationContext) { - beanFactory.setBeanClassLoader( - ((ConfigurableApplicationContext) parent).getBeanFactory().getBeanClassLoader()); - } - else { - beanFactory.setBeanClassLoader(classLoader); - } - context = AotDetector.useGeneratedArtifacts() ? new GenericApplicationContext(beanFactory) - : new AnnotationConfigApplicationContext(beanFactory); - } - else { - context = AotDetector.useGeneratedArtifacts() ? new GenericApplicationContext() - : new AnnotationConfigApplicationContext(); - } - context.setClassLoader(classLoader); - context.getEnvironment().getPropertySources().addFirst( - new MapPropertySource(this.propertySourceName, Collections.singletonMap(this.propertyName, name))); - if (this.parent != null) { - // Uses Environment from parent as well as beans - context.setParent(this.parent); - } - context.setDisplayName(generateDisplayName(name)); - return context; - } - - protected String generateDisplayName(String name) { - return this.getClass().getSimpleName() + "-" + name; - } - - public T getInstance(String name, Class type) { - GenericApplicationContext context = getContext(name); - try { - return context.getBean(type); - } - catch (NoSuchBeanDefinitionException e) { - // ignore - } - return null; - } - - public ObjectProvider getLazyProvider(String name, Class type) { - return new ClientFactoryObjectProvider<>(this, name, type); - } - - public ObjectProvider getProvider(String name, Class type) { - GenericApplicationContext context = getContext(name); - return context.getBeanProvider(type); - } - - public T getInstance(String name, Class clazz, Class... generics) { - ResolvableType type = ResolvableType.forClassWithGenerics(clazz, generics); - return getInstance(name, type); - } - - @SuppressWarnings("unchecked") - public T getInstance(String name, ResolvableType type) { - GenericApplicationContext context = getContext(name); - String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, type); - if (beanNames.length > 0) { - for (String beanName : beanNames) { - if (context.isTypeMatch(beanName, type)) { - return (T) context.getBean(beanName); - } - } - } - return null; - } - - public Map getInstances(String name, Class type) { - GenericApplicationContext context = getContext(name); - - return BeanFactoryUtils.beansOfTypeIncludingAncestors(context, type); - } - - public Map getConfigurations() { - return configurations; - } - - /** - * Specification with name and configuration. - */ - public interface Specification { - - String getName(); - - Class[] getConfiguration(); - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesBeans.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesBeans.java deleted file mode 100644 index 84d9d843..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesBeans.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.properties; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.context.properties.ConfigurationPropertiesBean; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.stereotype.Component; - -/** - * Collects references to @ConfigurationProperties beans in the context and - * its parent. - * - * @author Dave Syer - */ -@Component -public class ConfigurationPropertiesBeans implements BeanPostProcessor, ApplicationContextAware { - - private Map beans = new HashMap<>(); - - private ApplicationContext applicationContext; - - private ConfigurableListableBeanFactory beanFactory; - - private String refreshScope; - - private boolean refreshScopeInitialized; - - private ConfigurationPropertiesBeans parent; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - if (applicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableListableBeanFactory) { - this.beanFactory = (ConfigurableListableBeanFactory) applicationContext.getAutowireCapableBeanFactory(); - } - if (applicationContext.getParent() != null && applicationContext.getParent() - .getAutowireCapableBeanFactory() instanceof ConfigurableListableBeanFactory listable) { - String[] names = listable.getBeanNamesForType(ConfigurationPropertiesBeans.class); - if (names.length == 1) { - this.parent = (ConfigurationPropertiesBeans) listable.getBean(names[0]); - this.beans.putAll(this.parent.beans); - } - } - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (isRefreshScoped(beanName)) { - return bean; - } - ConfigurationPropertiesBean propertiesBean = ConfigurationPropertiesBean.get(this.applicationContext, bean, - beanName); - if (propertiesBean != null) { - this.beans.put(beanName, propertiesBean); - } - return bean; - } - - private boolean isRefreshScoped(String beanName) { - if (this.refreshScope == null && !this.refreshScopeInitialized) { - this.refreshScopeInitialized = true; - for (String scope : this.beanFactory.getRegisteredScopeNames()) { - if (this.beanFactory.getRegisteredScope( - scope) instanceof org.springframework.cloud.context.scope.refresh.RefreshScope) { - this.refreshScope = scope; - break; - } - } - } - if (beanName == null || this.refreshScope == null) { - return false; - } - return this.beanFactory.containsBeanDefinition(beanName) - && this.refreshScope.equals(this.beanFactory.getBeanDefinition(beanName).getScope()); - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - - public Set getBeanNames() { - return new HashSet<>(this.beans.keySet()); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java deleted file mode 100644 index b79d5a7b..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.properties; - -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.util.ProxyUtils; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ApplicationListener; -import org.springframework.core.env.Environment; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - -/** - * Listens for {@link EnvironmentChangeEvent} and rebinds beans that were bound to the - * {@link Environment} using {@link ConfigurationProperties - * @ConfigurationProperties}. When these beans are re-bound and - * re-initialized, the changes are available immediately to any component that is using - * the @ConfigurationProperties bean. - * - * @author Dave Syer - * @see RefreshScope for a deeper and optionally more focused refresh of bean components. - * - */ -@Component -@ManagedResource -public class ConfigurationPropertiesRebinder - implements ApplicationContextAware, ApplicationListener { - - private ConfigurationPropertiesBeans beans; - - private ApplicationContext applicationContext; - - private Map errors = new ConcurrentHashMap<>(); - - public ConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) { - this.beans = beans; - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - this.applicationContext = applicationContext; - } - - /** - * A map of bean name to errors when instantiating the bean. - * @return The errors accumulated since the latest destroy. - */ - public Map getErrors() { - return this.errors; - } - - @ManagedOperation - public void rebind() { - this.errors.clear(); - for (String name : this.beans.getBeanNames()) { - rebind(name); - } - } - - @ManagedOperation - public boolean rebind(String name) { - if (!this.beans.getBeanNames().contains(name)) { - return false; - } - ApplicationContext appContext = this.applicationContext; - while (appContext != null) { - if (appContext.containsLocalBean(name)) { - return rebind(name, appContext); - } - else { - appContext = appContext.getParent(); - } - } - return false; - } - - /** - * WARNING: This method rebinds beans from any context in the hierarchy using the main - * application context. - * @param type bean type to rebind. - * @return true, if successful. - */ - public boolean rebind(Class type) { - String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.applicationContext, type); - if (beanNamesForType.length > 0) { - String name = beanNamesForType[0]; - if (ScopedProxyUtils.isScopedTarget(name)) { - name = ScopedProxyUtils.getOriginalBeanName(name); - } - return rebind(name, this.applicationContext); - } - return false; - } - - private boolean rebind(String name, ApplicationContext appContext) { - try { - Object bean = appContext.getBean(name); - if (AopUtils.isAopProxy(bean)) { - bean = ProxyUtils.getTargetObject(bean); - } - if (bean != null) { - // TODO: determine a more general approach to fix this. - // see - // https://github.com/spring-cloud/spring-cloud-commons/issues/571 - if (getNeverRefreshable().contains(bean.getClass().getName())) { - return false; // ignore - } - appContext.getAutowireCapableBeanFactory().destroyBean(bean); - appContext.getAutowireCapableBeanFactory().initializeBean(bean, name); - return true; - } - } - catch (RuntimeException e) { - this.errors.put(name, e); - throw e; - } - catch (Exception e) { - this.errors.put(name, e); - throw new IllegalStateException("Cannot rebind to " + name, e); - } - return false; - } - - @ManagedAttribute - public Set getNeverRefreshable() { - String neverRefresh = this.applicationContext.getEnvironment() - .getProperty("spring.cloud.refresh.never-refreshable", "com.zaxxer.hikari.HikariDataSource"); - return StringUtils.commaDelimitedListToSet(neverRefresh); - } - - @ManagedAttribute - public Set getBeanNames() { - return new HashSet<>(this.beans.getBeanNames()); - } - - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - if (this.applicationContext.equals(event.getSource()) - // Backwards compatible - || event.getKeys().equals(event.getSource())) { - rebind(); - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java deleted file mode 100644 index 08fc45ce..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresher.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.refresh; - -import java.util.List; -import java.util.function.Supplier; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.BootstrapContext; -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.ConfigurableBootstrapContext; -import org.springframework.boot.DefaultBootstrapContext; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.boot.logging.DeferredLogFactory; -import org.springframework.boot.util.Instantiator; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.ContextRefreshedWithApplicationEvent; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.core.io.support.SpringFactoriesLoader; - -/** - * @author Dave Syer - * @author Venil Noronha - */ -public class ConfigDataContextRefresher extends ContextRefresher - implements ApplicationListener { - - private SpringApplication application; - - @Deprecated - public ConfigDataContextRefresher(ConfigurableApplicationContext context, RefreshScope scope) { - super(context, scope); - } - - public ConfigDataContextRefresher(ConfigurableApplicationContext context, RefreshScope scope, - RefreshAutoConfiguration.RefreshProperties properties) { - super(context, scope, properties); - } - - @Override - public void onApplicationEvent(ContextRefreshedWithApplicationEvent event) { - application = event.getSpringApplication(); - } - - @Override - protected void updateEnvironment() { - if (logger.isTraceEnabled()) { - logger.trace("Re-processing environment to add config data"); - } - StandardEnvironment environment = copyEnvironment(getContext().getEnvironment()); - ConfigurableBootstrapContext bootstrapContext = getContext().getBeanProvider(ConfigurableBootstrapContext.class) - .getIfAvailable(DefaultBootstrapContext::new); - - // run thru all EnvironmentPostProcessor instances. This lets things like vcap and - // decrypt happen after refresh. The hard coded call to - // ConfigDataEnvironmentPostProcessor.applyTo() is now automated as well. - DeferredLogFactory logFactory = new PassthruDeferredLogFactory(); - List classNames = SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, - getClass().getClassLoader()); - Instantiator instantiator = new Instantiator<>(EnvironmentPostProcessor.class, - (parameters) -> { - parameters.add(DeferredLogFactory.class, logFactory); - parameters.add(Log.class, logFactory::getLog); - parameters.add(ConfigurableBootstrapContext.class, bootstrapContext); - parameters.add(BootstrapContext.class, bootstrapContext); - parameters.add(BootstrapRegistry.class, bootstrapContext); - }); - List postProcessors = instantiator.instantiate(classNames); - for (EnvironmentPostProcessor postProcessor : postProcessors) { - postProcessor.postProcessEnvironment(environment, application); - } - - if (environment.getPropertySources().contains(REFRESH_ARGS_PROPERTY_SOURCE)) { - environment.getPropertySources().remove(REFRESH_ARGS_PROPERTY_SOURCE); - } - MutablePropertySources target = getContext().getEnvironment().getPropertySources(); - String targetName = null; - for (PropertySource source : environment.getPropertySources()) { - String name = source.getName(); - if (target.contains(name)) { - targetName = name; - } - if (!this.standardSources.contains(name)) { - if (target.contains(name)) { - target.replace(name, source); - } - else { - if (targetName != null) { - target.addAfter(targetName, source); - // update targetName to preserve ordering - targetName = name; - } - else { - // targetName was null so we are at the start of the list - target.addFirst(source); - targetName = name; - } - } - } - } - } - - static class PassthruDeferredLogFactory implements DeferredLogFactory { - - @Override - public Log getLog(Supplier destination) { - return destination.get(); - } - - @Override - public Log getLog(Class destination) { - return getLog(() -> LogFactory.getLog(destination)); - } - - @Override - public Log getLog(Log destination) { - return getLog(() -> destination); - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java deleted file mode 100644 index 98149392..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/ContextRefresher.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.refresh; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.CommandLinePropertySource; -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; -import org.springframework.util.CollectionUtils; -import org.springframework.web.context.support.StandardServletEnvironment; - -/** - * @author Dave Syer - * @author Venil Noronha - */ -public abstract class ContextRefresher { - - protected final Log logger = LogFactory.getLog(getClass()); - - protected static final String REFRESH_ARGS_PROPERTY_SOURCE = "refreshArgs"; - - protected static final String[] DEFAULT_PROPERTY_SOURCES = new String[] { - // order matters, if cli args aren't first, things get messy - CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME, "defaultProperties" }; - - protected Set standardSources = new HashSet<>( - Arrays.asList(StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, - StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, - StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME, - StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME, - StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME, "configurationProperties")); - - protected final List additionalPropertySourcesToRetain; - - private ConfigurableApplicationContext context; - - private RefreshScope scope; - - @Deprecated - protected ContextRefresher(ConfigurableApplicationContext context, RefreshScope scope) { - this(context, scope, new RefreshAutoConfiguration.RefreshProperties()); - } - - @SuppressWarnings("unchecked") - protected ContextRefresher(ConfigurableApplicationContext context, RefreshScope scope, - RefreshAutoConfiguration.RefreshProperties properties) { - this.context = context; - this.scope = scope; - additionalPropertySourcesToRetain = properties.getAdditionalPropertySourcesToRetain(); - } - - protected ConfigurableApplicationContext getContext() { - return this.context; - } - - protected RefreshScope getScope() { - return this.scope; - } - - public synchronized Set refresh() { - Set keys = refreshEnvironment(); - this.scope.refreshAll(); - return keys; - } - - public synchronized Set refreshEnvironment() { - Map before = extract(this.context.getEnvironment().getPropertySources()); - updateEnvironment(); - Set keys = changes(before, extract(this.context.getEnvironment().getPropertySources())).keySet(); - this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys)); - return keys; - } - - protected abstract void updateEnvironment(); - - // Don't use ConfigurableEnvironment.merge() in case there are clashes with property - // source names - protected StandardEnvironment copyEnvironment(ConfigurableEnvironment input) { - StandardEnvironment environment = new StandardEnvironment(); - MutablePropertySources capturedPropertySources = environment.getPropertySources(); - // Only copy the default property source(s) and the profiles over from the main - // environment (everything else should be pristine, just like it was on startup). - List propertySourcesToRetain = new ArrayList<>(Arrays.asList(DEFAULT_PROPERTY_SOURCES)); - if (!CollectionUtils.isEmpty(additionalPropertySourcesToRetain)) { - propertySourcesToRetain.addAll(additionalPropertySourcesToRetain); - } - - for (String name : propertySourcesToRetain) { - if (input.getPropertySources().contains(name)) { - if (capturedPropertySources.contains(name)) { - capturedPropertySources.replace(name, input.getPropertySources().get(name)); - } - else { - capturedPropertySources.addLast(input.getPropertySources().get(name)); - } - } - } - environment.setActiveProfiles(input.getActiveProfiles()); - environment.setDefaultProfiles(input.getDefaultProfiles()); - return environment; - } - - private Map changes(Map before, Map after) { - Map result = new HashMap<>(); - for (String key : before.keySet()) { - if (!after.containsKey(key)) { - result.put(key, null); - } - else if (!equal(before.get(key), after.get(key))) { - result.put(key, after.get(key)); - } - } - for (String key : after.keySet()) { - if (!before.containsKey(key)) { - result.put(key, after.get(key)); - } - } - return result; - } - - private boolean equal(Object one, Object two) { - if (one == null && two == null) { - return true; - } - if (one == null || two == null) { - return false; - } - return one.equals(two); - } - - private Map extract(MutablePropertySources propertySources) { - Map result = new HashMap<>(); - List> sources = new ArrayList<>(); - for (PropertySource source : propertySources) { - sources.add(0, source); - } - for (PropertySource source : sources) { - if (!this.standardSources.contains(source.getName())) { - extract(source, result); - } - } - return result; - } - - private void extract(PropertySource parent, Map result) { - if (parent instanceof CompositePropertySource) { - try { - List> sources = new ArrayList<>(); - for (PropertySource source : ((CompositePropertySource) parent).getPropertySources()) { - sources.add(0, source); - } - for (PropertySource source : sources) { - extract(source, result); - } - } - catch (Exception e) { - return; - } - } - else if (parent instanceof EnumerablePropertySource) { - for (String key : ((EnumerablePropertySource) parent).getPropertyNames()) { - result.put(key, parent.getProperty(key)); - } - } - } - - @Configuration(proxyBeanMethods = false) - protected static class Empty { - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/LegacyContextRefresher.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/LegacyContextRefresher.java deleted file mode 100644 index 7f20daf2..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/refresh/LegacyContextRefresher.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.refresh; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.Banner; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.bootstrap.BootstrapApplicationListener; -import org.springframework.cloud.bootstrap.BootstrapConfigFileApplicationListener; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; - -import static org.springframework.cloud.util.PropertyUtils.BOOTSTRAP_ENABLED_PROPERTY; - -/** - * @author Dave Syer - * @author Venil Noronha - */ -public class LegacyContextRefresher extends ContextRefresher { - - @Deprecated - public LegacyContextRefresher(ConfigurableApplicationContext context, RefreshScope scope) { - super(context, scope); - } - - public LegacyContextRefresher(ConfigurableApplicationContext context, RefreshScope scope, - RefreshAutoConfiguration.RefreshProperties properties) { - super(context, scope, properties); - } - - @Override - protected void updateEnvironment() { - addConfigFilesToEnvironment(); - } - - /* For testing. */ ConfigurableApplicationContext addConfigFilesToEnvironment() { - ConfigurableApplicationContext capture = null; - try { - StandardEnvironment environment = copyEnvironment(getContext().getEnvironment()); - - Map map = new HashMap<>(); - map.put("spring.jmx.enabled", false); - map.put("spring.main.sources", ""); - // gh-678 without this apps with this property set to REACTIVE or SERVLET fail - map.put("spring.main.web-application-type", "NONE"); - map.put(BOOTSTRAP_ENABLED_PROPERTY, Boolean.TRUE.toString()); - environment.getPropertySources().addFirst(new MapPropertySource(REFRESH_ARGS_PROPERTY_SOURCE, map)); - - SpringApplicationBuilder builder = new SpringApplicationBuilder(Empty.class).bannerMode(Banner.Mode.OFF) - .web(WebApplicationType.NONE).environment(environment); - // Just the listeners that affect the environment (e.g. excluding logging - // listener because it has side effects) - builder.application().setListeners( - Arrays.asList(new BootstrapApplicationListener(), new BootstrapConfigFileApplicationListener())); - capture = builder.run(); - if (environment.getPropertySources().contains(REFRESH_ARGS_PROPERTY_SOURCE)) { - environment.getPropertySources().remove(REFRESH_ARGS_PROPERTY_SOURCE); - } - MutablePropertySources target = getContext().getEnvironment().getPropertySources(); - String targetName = null; - for (PropertySource source : environment.getPropertySources()) { - String name = source.getName(); - if (target.contains(name)) { - targetName = name; - } - if (!this.standardSources.contains(name)) { - if (target.contains(name)) { - target.replace(name, source); - } - else { - if (targetName != null) { - target.addAfter(targetName, source); - // update targetName to preserve ordering - targetName = name; - } - else { - // targetName was null so we are at the start of the list - target.addFirst(source); - targetName = name; - } - } - } - } - } - finally { - ConfigurableApplicationContext closeable = capture; - while (closeable != null) { - try { - closeable.close(); - } - catch (Exception e) { - // Ignore; - } - if (closeable.getParent() instanceof ConfigurableApplicationContext) { - closeable = (ConfigurableApplicationContext) closeable.getParent(); - } - else { - break; - } - } - } - return capture; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/PauseHandler.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/PauseHandler.java deleted file mode 100644 index 57f46473..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/PauseHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2020-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.restart; - -/** - * @author Dave Syer - */ -public interface PauseHandler { - - void pause(); - - void resume(); - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java deleted file mode 100644 index bbd841b6..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.restart; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -// -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.context.config.ContextRefreshedWithApplicationEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.integration.monitor.IntegrationMBeanExporter; -import org.springframework.util.ClassUtils; - -/** - * An endpoint that restarts the application context. Install as a bean and also register - * a {@link RestartListener} with the {@link SpringApplication} that starts the context. - * Those two components communicate via an {@link ApplicationEvent} and set up the state - * needed to doRestart the context. - * - * @author Dave Syer - * - */ -@Endpoint(id = "restart", enableByDefault = false) -public class RestartEndpoint implements ApplicationListener { - - private static Log logger = LogFactory.getLog(RestartEndpoint.class); - - private ConfigurableApplicationContext context; - - private SpringApplication application; - - private String[] args; - - private ContextRefreshedWithApplicationEvent event; - - private IntegrationShutdown integrationShutdown; - - private List pauseHandlers = Collections.emptyList(); - - private long timeout; - - // @ManagedAttribute - public long getTimeout() { - return this.timeout; - } - - public void setTimeout(long timeout) { - this.timeout = timeout; - } - - public void setIntegrationMBeanExporter(Object exporter) { - if (exporter != null) { - this.integrationShutdown = new IntegrationShutdown(exporter); - } - } - - @Override - public void onApplicationEvent(ContextRefreshedWithApplicationEvent input) { - this.event = input; - if (this.context == null) { - this.context = this.event.getApplicationContext(); - this.args = this.event.getArgs(); - this.application = this.event.getSpringApplication(); - this.application.addInitializers(new PostProcessorInitializer()); - this.pauseHandlers = this.context.getBeanProvider(PauseHandler.class).orderedStream() - .collect(Collectors.toList()); - } - } - - @WriteOperation - public Object restart() { - Thread thread = new Thread(this::safeRestart); - thread.setDaemon(false); - thread.start(); - return Collections.singletonMap("message", "Restarting"); - } - - private Boolean safeRestart() { - try { - doRestart(); - logger.info("Restarted"); - return true; - } - catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.info("Could not doRestart", e); - } - else { - logger.info("Could not doRestart: " + e.getMessage()); - } - return false; - } - } - - public PauseEndpoint getPauseEndpoint() { - return new PauseEndpoint(); - } - - public ResumeEndpoint getResumeEndpoint() { - return new ResumeEndpoint(); - } - - // @ManagedOperation - public synchronized ConfigurableApplicationContext doRestart() { - if (this.context != null) { - if (this.integrationShutdown != null) { - this.integrationShutdown.stop(this.timeout); - } - this.application.setEnvironment(this.context.getEnvironment()); - close(); - // If running in a webapp then the context classloader is probably going to - // die so we need to revert to a safe place before starting again - overrideClassLoaderForRestart(); - this.context = this.application.run(this.args); - } - return this.context; - } - - private void close() { - ApplicationContext context = this.context; - while (context instanceof Closeable) { - try { - ((Closeable) context).close(); - } - catch (IOException e) { - logger.error("Cannot close context: " + context.getId(), e); - } - context = context.getParent(); - } - } - - // @ManagedAttribute - public boolean isRunning() { - if (this.context != null) { - return this.context.isRunning(); - } - return false; - } - - // @ManagedOperation - public synchronized void doPause() { - for (PauseHandler handler : this.pauseHandlers) { - handler.pause(); - } - } - - // @ManagedOperation - public synchronized void doResume() { - for (int i = this.pauseHandlers.size(); i-- > 0;) { - PauseHandler handler = this.pauseHandlers.get(i); - handler.resume(); - } - } - - private void overrideClassLoaderForRestart() { - ClassUtils.overrideThreadContextClassLoader(this.application.getClass().getClassLoader()); - } - - class PostProcessorInitializer implements ApplicationContextInitializer { - - @Override - public void initialize(GenericApplicationContext context) { - context.registerBean(PostProcessor.class, PostProcessor::new); - } - - } - - class PostProcessor implements BeanPostProcessor { - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof RestartEndpoint) { - return RestartEndpoint.this; - } - return bean; - } - - } - - /** - * Pause endpoint configuration. - */ - @Endpoint(id = "pause") - public class PauseEndpoint { - - @WriteOperation - public Boolean pause() { - if (isRunning()) { - doPause(); - return true; - } - return false; - } - - } - - /** - * Resume endpoint configuration. - */ - @Endpoint(id = "resume") - @ConfigurationProperties("management.endpoint.resume") - public class ResumeEndpoint { - - @WriteOperation - public Boolean resume() { - if (!isRunning()) { - doResume(); - return true; - } - return false; - } - - } - - private class IntegrationShutdown { - - private IntegrationMBeanExporter exporter; - - IntegrationShutdown(Object exporter) { - this.exporter = (IntegrationMBeanExporter) exporter; - } - - public void stop(long timeout) { - this.exporter.stopActiveComponents(timeout); - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartListener.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartListener.java deleted file mode 100644 index 361aa076..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/restart/RestartListener.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.restart; - -import org.springframework.boot.context.event.ApplicationPreparedEvent; -import org.springframework.cloud.context.config.ContextRefreshedWithApplicationEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.event.ContextClosedEvent; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.context.event.SmartApplicationListener; - -/** - * A listener that stores enough information about an application, as it starts, to be - * able to restart it later if needed. - * - * @author Dave Syer - * - */ -public class RestartListener implements SmartApplicationListener { - - private ConfigurableApplicationContext context; - - private ContextRefreshedWithApplicationEvent event; - - @Override - public int getOrder() { - return 0; - } - - @Override - public boolean supportsEventType(Class eventType) { - return ApplicationPreparedEvent.class.isAssignableFrom(eventType) - || ContextRefreshedEvent.class.isAssignableFrom(eventType) - || ContextClosedEvent.class.isAssignableFrom(eventType); - - } - - @Override - public boolean supportsSourceType(Class sourceType) { - return true; - } - - @Override - public void onApplicationEvent(ApplicationEvent input) { - if (input instanceof ApplicationPreparedEvent applicationPreparedEvent) { - this.event = new ContextRefreshedWithApplicationEvent(applicationPreparedEvent.getSpringApplication(), - applicationPreparedEvent.getArgs(), applicationPreparedEvent.getApplicationContext()); - if (this.context == null) { - this.context = this.event.getApplicationContext(); - } - } - else if (input instanceof ContextRefreshedEvent) { - if (this.context != null && input.getSource().equals(this.context) && this.event != null) { - this.context.publishEvent(this.event); - } - } - else { - if (this.context != null && input.getSource().equals(this.context)) { - this.context = null; - this.event = null; - } - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/GenericScope.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/GenericScope.java deleted file mode 100644 index b75a564f..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/GenericScope.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope; - -import java.lang.reflect.Method; -import java.lang.reflect.UndeclaredThrowableException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.aop.framework.Advised; -import org.springframework.aop.scope.ScopedObject; -import org.springframework.aop.scope.ScopedProxyFactoryBean; -import org.springframework.aop.support.AopUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.Scope; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.expression.Expression; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.ParseException; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; - -/** - *

- * A generic Scope implementation. - *

- * - * @author Dave Syer - * @since 3.1 - * - */ -public class GenericScope - implements Scope, BeanFactoryPostProcessor, BeanDefinitionRegistryPostProcessor, DisposableBean { - - private static final Log logger = LogFactory.getLog(GenericScope.class); - - private BeanLifecycleWrapperCache cache = new BeanLifecycleWrapperCache(new StandardScopeCache()); - - private String name = "generic"; - - private ConfigurableListableBeanFactory beanFactory; - - private StandardEvaluationContext evaluationContext; - - private String id; - - private Map errors = new ConcurrentHashMap<>(); - - private ConcurrentMap locks = new ConcurrentHashMap<>(); - - static RuntimeException wrapIfNecessary(Throwable throwable) { - if (throwable instanceof RuntimeException) { - return (RuntimeException) throwable; - } - if (throwable instanceof Error) { - throw (Error) throwable; - } - return new IllegalStateException(throwable); - } - - /** - * Manual override for the serialization ID that will be used to identify the bean - * factory. The default is a unique key based on the bean names in the bean factory. - * @param id The ID to set. - */ - public void setId(String id) { - this.id = id; - } - - /** - * The cache implementation to use for bean instances in this scope. - * @param cache The cache to use. - */ - public void setScopeCache(ScopeCache cache) { - this.cache = new BeanLifecycleWrapperCache(cache); - } - - /** - * A map of bean name to errors when instantiating the bean. - * @return The errors accumulated since the latest destroy. - */ - public Map getErrors() { - return this.errors; - } - - @Override - public void destroy() { - List errors = new ArrayList<>(); - Collection wrappers = this.cache.clear(); - for (BeanLifecycleWrapper wrapper : wrappers) { - try { - Lock lock = this.locks.get(wrapper.getName()).writeLock(); - lock.lock(); - try { - wrapper.destroy(); - } - finally { - lock.unlock(); - } - } - catch (RuntimeException e) { - errors.add(e); - } - } - if (!errors.isEmpty()) { - throw wrapIfNecessary(errors.get(0)); - } - this.errors.clear(); - } - - /** - * Destroys the named bean (i.e. flushes it from the cache by default). - * @param name The bean name to flush. - * @return True if the bean was already cached; false otherwise. - */ - protected boolean destroy(String name) { - BeanLifecycleWrapper wrapper = this.cache.remove(name); - if (wrapper != null) { - Lock lock = this.locks.get(wrapper.getName()).writeLock(); - lock.lock(); - try { - wrapper.destroy(); - } - finally { - lock.unlock(); - } - this.errors.remove(name); - return true; - } - return false; - } - - @Override - public Object get(String name, ObjectFactory objectFactory) { - BeanLifecycleWrapper value = this.cache.put(name, new BeanLifecycleWrapper(name, objectFactory)); - this.locks.putIfAbsent(name, new ReentrantReadWriteLock()); - try { - return value.getBean(); - } - catch (RuntimeException e) { - this.errors.put(name, e); - throw e; - } - } - - @Override - public String getConversationId() { - return this.name; - } - - @Override - public void registerDestructionCallback(String name, Runnable callback) { - BeanLifecycleWrapper value = this.cache.get(name); - if (value == null) { - return; - } - value.setDestroyCallback(callback); - } - - @Override - public Object remove(String name) { - BeanLifecycleWrapper value = this.cache.remove(name); - if (value == null) { - return null; - } - // Someone might have added another object with the same key, but we - // keep the method contract by removing the - // value we found anyway - return value.getBean(); - } - - @Override - public Object resolveContextualObject(String key) { - Expression expression = parseExpression(key); - return expression.getValue(this.evaluationContext, this.beanFactory); - } - - private Expression parseExpression(String input) { - if (StringUtils.hasText(input)) { - ExpressionParser parser = new SpelExpressionParser(); - try { - return parser.parseExpression(input); - } - catch (ParseException e) { - throw new IllegalArgumentException("Cannot parse expression: " + input, e); - } - - } - else { - return null; - } - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - beanFactory.registerScope(this.name, this); - setSerializationId(beanFactory); - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - for (String name : registry.getBeanDefinitionNames()) { - BeanDefinition definition = registry.getBeanDefinition(name); - if (definition instanceof RootBeanDefinition root) { - if (root.getDecoratedDefinition() != null && root.hasBeanClass() - && root.getBeanClass() == ScopedProxyFactoryBean.class) { - if (getName().equals(root.getDecoratedDefinition().getBeanDefinition().getScope())) { - root.setBeanClass(LockedScopedProxyFactoryBean.class); - root.getConstructorArgumentValues().addGenericArgumentValue(this); - // surprising that a scoped proxy bean definition is not already - // marked as synthetic? - root.setSynthetic(true); - } - } - } - } - } - - /** - * If the bean factory is a DefaultListableBeanFactory, then it can serialize scoped - * beans and deserialize them in another context (even in another JVM), as long as the - * IDs of the bean factories match. This method sets up the serialization ID to be - * either the ID provided to the scope instance, or if that is null, a hash of all the - * bean names. - * @param beanFactory The bean factory to configure. - */ - private void setSerializationId(ConfigurableListableBeanFactory beanFactory) { - - if (beanFactory instanceof DefaultListableBeanFactory) { - - String id = this.id; - if (id == null) { - List list = new ArrayList<>(Arrays.asList(beanFactory.getBeanDefinitionNames())); - Collections.sort(list); - String names = list.toString(); - logger.debug("Generating bean factory id from names: " + names); - id = UUID.nameUUIDFromBytes(names.getBytes()).toString(); - } - - logger.info("BeanFactory id=" + id); - ((DefaultListableBeanFactory) beanFactory).setSerializationId(id); - - } - else { - logger.warn( - "BeanFactory was not a DefaultListableBeanFactory, scoped proxy beans " + "cannot be serialized."); - } - - } - - protected String getName() { - return this.name; - } - - /** - * The name of this scope. Default "generic". - * @param name The name value to set. - */ - public void setName(String name) { - this.name = name; - } - - protected ReadWriteLock getLock(String beanName) { - return this.locks.get(beanName); - } - - private static class BeanLifecycleWrapperCache { - - private final ScopeCache cache; - - BeanLifecycleWrapperCache(ScopeCache cache) { - this.cache = cache; - } - - public BeanLifecycleWrapper remove(String name) { - return (BeanLifecycleWrapper) this.cache.remove(name); - } - - public Collection clear() { - Collection values = this.cache.clear(); - Collection wrappers = new LinkedHashSet<>(); - for (Object object : values) { - wrappers.add((BeanLifecycleWrapper) object); - } - return wrappers; - } - - public BeanLifecycleWrapper get(String name) { - return (BeanLifecycleWrapper) this.cache.get(name); - } - - public BeanLifecycleWrapper put(String name, BeanLifecycleWrapper value) { - return (BeanLifecycleWrapper) this.cache.put(name, value); - } - - } - - /** - * Wrapper for a bean instance and any destruction callback (DisposableBean etc.) that - * is registered for it. Also decorates the bean to optionally guard it from - * concurrent access (for instance). - * - * @author Dave Syer - * - */ - private static class BeanLifecycleWrapper { - - private final String name; - - private final ObjectFactory objectFactory; - - private volatile Object bean; - - private Runnable callback; - - BeanLifecycleWrapper(String name, ObjectFactory objectFactory) { - this.name = name; - this.objectFactory = objectFactory; - } - - public String getName() { - return this.name; - } - - public void setDestroyCallback(Runnable callback) { - this.callback = callback; - } - - public Object getBean() { - if (this.bean == null) { - synchronized (this.name) { - if (this.bean == null) { - this.bean = this.objectFactory.getObject(); - } - } - } - return this.bean; - } - - public void destroy() { - if (this.callback == null) { - return; - } - synchronized (this.name) { - Runnable callback = this.callback; - if (callback != null) { - callback.run(); - } - this.callback = null; - this.bean = null; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - BeanLifecycleWrapper other = (BeanLifecycleWrapper) obj; - if (this.name == null) { - if (other.name != null) { - return false; - } - } - else if (!this.name.equals(other.name)) { - return false; - } - return true; - } - - } - - /** - * A factory bean with a locked scope. - * - * @param - a generic scope extension - */ - @SuppressWarnings("serial") - public static class LockedScopedProxyFactoryBean extends ScopedProxyFactoryBean - implements MethodInterceptor { - - private final S scope; - - private String targetBeanName; - - public LockedScopedProxyFactoryBean(S scope) { - this.scope = scope; - } - - @Override - public void setBeanFactory(BeanFactory beanFactory) { - super.setBeanFactory(beanFactory); - Object proxy = getObject(); - if (proxy instanceof Advised advised) { - advised.addAdvice(0, this); - } - } - - @Override - public void setTargetBeanName(String targetBeanName) { - super.setTargetBeanName(targetBeanName); - this.targetBeanName = targetBeanName; - } - - @Override - public Object invoke(MethodInvocation invocation) throws Throwable { - Method method = invocation.getMethod(); - if (AopUtils.isEqualsMethod(method) || AopUtils.isToStringMethod(method) - || AopUtils.isHashCodeMethod(method) || isScopedObjectGetTargetObject(method)) { - return invocation.proceed(); - } - Object proxy = getObject(); - ReadWriteLock readWriteLock = this.scope.getLock(this.targetBeanName); - if (readWriteLock == null) { - if (logger.isDebugEnabled()) { - logger.debug("For bean with name [" + this.targetBeanName - + "] there is no read write lock. Will create a new one to avoid NPE"); - } - readWriteLock = new ReentrantReadWriteLock(); - } - Lock lock = readWriteLock.readLock(); - lock.lock(); - try { - if (proxy instanceof Advised advised) { - ReflectionUtils.makeAccessible(method); - return ReflectionUtils.invokeMethod(method, advised.getTargetSource().getTarget(), - invocation.getArguments()); - } - return invocation.proceed(); - } - // see gh-349. Throw the original exception rather than the - // UndeclaredThrowableException - catch (UndeclaredThrowableException e) { - throw e.getUndeclaredThrowable(); - } - finally { - lock.unlock(); - } - } - - private boolean isScopedObjectGetTargetObject(Method method) { - return method.getDeclaringClass().equals(ScopedObject.class) && method.getName().equals("getTargetObject") - && method.getParameterTypes().length == 0; - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/ScopeCache.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/ScopeCache.java deleted file mode 100644 index df441e4b..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/ScopeCache.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope; - -import java.util.Collection; - -/** - * A special-purpose cache interface specifically for the {@link GenericScope} to use to - * manage cached bean instances. Implementations generally fall into two categories: those - * that store values "globally" (i.e. one instance per key), and those that store - * potentially multiple instances per key based on context (e.g. via a thread local). All - * implementations should be thread safe. - * - * @author Dave Syer - * - */ -public interface ScopeCache { - - /** - * Removes the object with this name from the cache. - * @param name The object name. - * @return The object removed, or null if there was none. - */ - Object remove(String name); - - /** - * Clears the cache and returns all objects in an unmodifiable collection. - * @return All objects stored in the cache. - */ - Collection clear(); - - /** - * Gets the named object from the cache. - * @param name The name of the object. - * @return The object with that name, or null if there is none. - */ - Object get(String name); - - /** - * Put a value in the cache if the key is not already used. If one is already present - * with the name provided, it is not replaced, but is returned to the caller. - * @param name The key. - * @param value The new candidate value. - * @return The value that is in the cache at the end of the operation. - */ - Object put(String name, Object value); - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/StandardScopeCache.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/StandardScopeCache.java deleted file mode 100644 index 8e55fb5a..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/StandardScopeCache.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * A simple cache implementation backed by a concurrent map. - * - * @author Dave Syer - * - */ -public class StandardScopeCache implements ScopeCache { - - private final ConcurrentMap cache = new ConcurrentHashMap<>(); - - @Override - public Object remove(String name) { - return this.cache.remove(name); - } - - @Override - public Collection clear() { - Collection values = new ArrayList<>(this.cache.values()); - this.cache.clear(); - return values; - } - - @Override - public Object get(String name) { - return this.cache.get(name); - } - - @Override - public Object put(String name, Object value) { - Object result = this.cache.putIfAbsent(name, value); - if (result != null) { - return result; - } - return value; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java deleted file mode 100644 index b08dfa0f..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.io.Serializable; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.cloud.context.scope.GenericScope; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ApplicationListener; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.core.Ordered; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; - -/** - *

- * A Scope implementation that allows for beans to be refreshed dynamically at runtime - * (see {@link #refresh(String)} and {@link #refreshAll()}). If a bean is refreshed then - * the next time the bean is accessed (i.e. a method is executed) a new instance is - * created. All lifecycle methods are applied to the bean instances, so any destruction - * callbacks that were registered in the bean factory are called when it is refreshed, and - * then the initialization callbacks are invoked as normal when the new instance is - * created. A new bean instance is created from the original bean definition, so any - * externalized content (property placeholders or expressions in string literals) is - * re-evaluated when it is created. - *

- * - *

- * Note that all beans in this scope are only initialized when first accessed, so - * the scope forces lazy initialization semantics. - *

- * - *

- * The scoped proxy approach adopted here has a side benefit that bean instances are - * automatically {@link Serializable}, and can be sent across the wire as long as the - * receiver has an identical application context on the other side. To ensure that the two - * contexts agree that they are identical, they have to have the same serialization ID. - * One will be generated automatically by default from the bean names, so two contexts - * with the same bean names are by default able to exchange beans by name. If you need to - * override the default ID, then provide an explicit {@link #setId(String) id} when the - * Scope is declared. - *

- * - * @author Dave Syer - * @since 3.1 - * - */ -@ManagedResource -public class RefreshScope extends GenericScope - implements ApplicationContextAware, ApplicationListener, Ordered { - - private ApplicationContext context; - - private BeanDefinitionRegistry registry; - - private boolean eager = true; - - private int order = Ordered.LOWEST_PRECEDENCE - 100; - - /** - * Creates a scope instance and gives it the default name: "refresh". - */ - public RefreshScope() { - super.setName("refresh"); - } - - @Override - public int getOrder() { - return this.order; - } - - public void setOrder(int order) { - this.order = order; - } - - /** - * Flag to determine whether all beans in refresh scope should be instantiated eagerly - * on startup. Default true. - * @param eager The flag to set. - */ - public void setEager(boolean eager) { - this.eager = eager; - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - this.registry = registry; - super.postProcessBeanDefinitionRegistry(registry); - } - - @Override - public void onApplicationEvent(ContextRefreshedEvent event) { - start(event); - } - - public void start(ContextRefreshedEvent event) { - if (event.getApplicationContext() == this.context && this.eager && this.registry != null) { - eagerlyInitialize(); - } - } - - private void eagerlyInitialize() { - for (String name : this.context.getBeanDefinitionNames()) { - BeanDefinition definition = this.registry.getBeanDefinition(name); - if (this.getName().equals(definition.getScope()) && !definition.isLazyInit()) { - Object bean = this.context.getBean(name); - if (bean != null) { - bean.getClass(); - } - } - } - } - - /** - * WARNING: This method refreshes beans from any context in the hierarchy using the - * main application context. - * @param type bean type to rebind. - * @return true, if successful. - */ - public boolean refresh(Class type) { - String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.context, type); - if (beanNamesForType.length > 0) { - return refresh(beanNamesForType[0]); - } - return false; - } - - @ManagedOperation(description = "Dispose of the current instance of bean name " - + "provided and force a refresh on next method execution.") - public boolean refresh(String name) { - if (!ScopedProxyUtils.isScopedTarget(name)) { - // User wants to refresh the bean with this name but that isn't the one in the - // cache... - name = ScopedProxyUtils.getTargetBeanName(name); - } - // Ensure lifecycle is finished if bean was disposable - if (super.destroy(name)) { - this.context.publishEvent(new RefreshScopeRefreshedEvent(name)); - return true; - } - return false; - } - - @ManagedOperation(description = "Dispose of the current instance of all beans " - + "in this scope and force a refresh on next method execution.") - public void refreshAll() { - super.destroy(); - this.context.publishEvent(new RefreshScopeRefreshedEvent()); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScopeRefreshedEvent.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScopeRefreshedEvent.java deleted file mode 100644 index b8cd198d..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScopeRefreshedEvent.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.springframework.context.ApplicationEvent; - -/** - * @author Spencer Gibb - */ -@SuppressWarnings("serial") -public class RefreshScopeRefreshedEvent extends ApplicationEvent { - - /** - * Default name for the refresh scope refreshed event. - */ - public static final String DEFAULT_NAME = "__refreshAll__"; - - private String name; - - public RefreshScopeRefreshedEvent() { - this(DEFAULT_NAME); - } - - public RefreshScopeRefreshedEvent(String name) { - super(name); - this.name = name; - } - - public String getName() { - return this.name; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadLocalScopeCache.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadLocalScopeCache.java deleted file mode 100644 index 1b25005e..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadLocalScopeCache.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.thread; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.springframework.cloud.context.scope.ScopeCache; - -/** - * @author Dave Syer - * - */ -public class ThreadLocalScopeCache implements ScopeCache { - - private ThreadLocal> data = ThreadLocal.withInitial(ConcurrentHashMap::new); - - @Override - public Object remove(String name) { - return this.data.get().remove(name); - } - - @Override - public Collection clear() { - ConcurrentMap map = this.data.get(); - Collection values = new ArrayList<>(map.values()); - map.clear(); - return values; - } - - @Override - public Object get(String name) { - return this.data.get().get(name); - } - - @Override - public Object put(String name, Object value) { - Object result = this.data.get().putIfAbsent(name, value); - if (result != null) { - return result; - } - return value; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadScope.java b/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadScope.java deleted file mode 100644 index 1eda94db..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/context/scope/thread/ThreadScope.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.thread; - -import org.springframework.cloud.context.scope.GenericScope; - -/** - * @author Dave Syer - * @since 3.1 - * - */ -public class ThreadScope extends GenericScope { - - /** - * Creates a scope instance and gives it the default name: "thread". - */ - public ThreadScope() { - super(); - super.setName("thread"); - super.setScopeCache(new ThreadLocalScopeCache()); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java b/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java deleted file mode 100644 index 1b234aae..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/RefreshEndpoint.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.endpoint; - -import java.util.Collection; -import java.util.Set; - -import org.springframework.boot.actuate.endpoint.annotation.Endpoint; -import org.springframework.boot.actuate.endpoint.annotation.WriteOperation; -import org.springframework.cloud.context.refresh.ContextRefresher; - -/** - * @author Dave Syer - * @author Venil Noronha - */ -@Endpoint(id = "refresh") -public class RefreshEndpoint { - - private ContextRefresher contextRefresher; - - public RefreshEndpoint(ContextRefresher contextRefresher) { - this.contextRefresher = contextRefresher; - } - - @WriteOperation - public Collection refresh() { - Set keys = this.contextRefresher.refresh(); - return keys; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEvent.java b/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEvent.java deleted file mode 100644 index a581b256..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEvent.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.endpoint.event; - -import org.springframework.cloud.endpoint.RefreshEndpoint; -import org.springframework.context.ApplicationEvent; - -/** - * Event that triggers a call to {@link RefreshEndpoint#refresh()}. - * - * @author Spencer Gibb - */ -@SuppressWarnings("serial") -public class RefreshEvent extends ApplicationEvent { - - private Object event; - - private String eventDesc; - - public RefreshEvent(Object source, Object event, String eventDesc) { - super(source); - this.event = event; - this.eventDesc = eventDesc; - } - - public Object getEvent() { - return this.event; - } - - public String getEventDesc() { - return this.eventDesc; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java b/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java deleted file mode 100644 index 9e081f26..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.endpoint.event; - -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.event.SmartApplicationListener; - -/** - * Calls {@link ContextRefresher#refresh} when a {@link RefreshEvent} is received. Only - * responds to {@link RefreshEvent} after receiving an {@link ApplicationReadyEvent}, as - * the RefreshEvents might come too early in the application lifecycle. - * - * @author Spencer Gibb - */ -public class RefreshEventListener implements SmartApplicationListener { - - private static Log log = LogFactory.getLog(RefreshEventListener.class); - - private ContextRefresher refresh; - - private AtomicBoolean ready = new AtomicBoolean(false); - - public RefreshEventListener(ContextRefresher refresh) { - this.refresh = refresh; - } - - @Override - public boolean supportsEventType(Class eventType) { - return ApplicationReadyEvent.class.isAssignableFrom(eventType) - || RefreshEvent.class.isAssignableFrom(eventType); - } - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof ApplicationReadyEvent) { - handle((ApplicationReadyEvent) event); - } - else if (event instanceof RefreshEvent) { - handle((RefreshEvent) event); - } - } - - public void handle(ApplicationReadyEvent event) { - this.ready.compareAndSet(false, true); - } - - public void handle(RefreshEvent event) { - if (this.ready.get()) { // don't handle events before app is ready - log.debug("Event received " + event.getEventDesc()); - Set keys = this.refresh.refresh(); - log.info("Refresh keys changed: " + keys); - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/env/EnvironmentUtils.java b/spring-cloud-context/src/main/java/org/springframework/cloud/env/EnvironmentUtils.java deleted file mode 100644 index 7ec952b8..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/env/EnvironmentUtils.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.env; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.core.env.Environment; - -/** - * @author Spencer Gibb - */ -public final class EnvironmentUtils { - - private EnvironmentUtils() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - public static Map getSubProperties(Environment environment, String keyPrefix) { - return Binder.get(environment).bind(keyPrefix, Bindable.mapOf(String.class, String.class)) - .orElseGet(Collections::emptyMap); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/health/RefreshScopeHealthIndicator.java b/spring-cloud-context/src/main/java/org/springframework/cloud/health/RefreshScopeHealthIndicator.java deleted file mode 100644 index abeea9de..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/health/RefreshScopeHealthIndicator.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.health; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.cloud.context.scope.refresh.RefreshScope; - -/** - * Health indicator for the refresh scope and configuration properties rebinding. If an - * environment change causes a bean to fail in instantiate or bind, this indicator will - * generally say what the problem was and switch to DOWN. - * - * @author Dave Syer - */ -public class RefreshScopeHealthIndicator extends AbstractHealthIndicator { - - private ObjectProvider scope; - - private ConfigurationPropertiesRebinder rebinder; - - public RefreshScopeHealthIndicator(ObjectProvider scope, ConfigurationPropertiesRebinder rebinder) { - this.scope = scope; - this.rebinder = rebinder; - } - - @Override - protected void doHealthCheck(Builder builder) { - RefreshScope refreshScope = this.scope.getIfAvailable(); - if (refreshScope != null) { - Map errors = new HashMap<>(refreshScope.getErrors()); - errors.putAll(this.rebinder.getErrors()); - if (errors.isEmpty()) { - builder.up(); - } - else { - builder.down(); - if (errors.size() == 1) { - builder.withException(errors.values().iterator().next()); - } - else { - for (String name : errors.keySet()) { - builder.withDetail(name, errors.get(name)); - } - } - } - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java b/spring-cloud-context/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java deleted file mode 100644 index 7a32686b..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.logging; - -import java.util.Collections; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.logging.LogLevel; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; - -/** - * Listener that looks for {@link EnvironmentChangeEvent} and rebinds logger levels if any - * changed. - * - * @author Dave Syer - * @author Olga Maciaszek-Sharma - * - */ -public class LoggingRebinder implements ApplicationListener, EnvironmentAware { - - private static final Bindable> STRING_STRING_MAP = Bindable.mapOf(String.class, String.class); - - private final Log logger = LogFactory.getLog(getClass()); - - private Environment environment; - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - if (this.environment == null) { - return; - } - LoggingSystem system = LoggingSystem.get(LoggingSystem.class.getClassLoader()); - setLogLevels(system, this.environment); - } - - protected void setLogLevels(LoggingSystem system, Environment environment) { - Map levels = Binder.get(environment).bind("logging.level", STRING_STRING_MAP) - .orElseGet(Collections::emptyMap); - for (Entry entry : levels.entrySet()) { - setLogLevel(system, environment, entry.getKey(), entry.getValue()); - } - } - - private void setLogLevel(LoggingSystem system, Environment environment, String name, String level) { - try { - if (name.equalsIgnoreCase("root")) { - name = null; - } - level = environment.resolvePlaceholders(level); - system.setLogLevel(name, resolveLogLevel(level)); - } - catch (RuntimeException ex) { - this.logger.error("Cannot set level: " + level + " for '" + name + "'"); - } - } - - private LogLevel resolveLogLevel(String level) { - String trimmedLevel = level.trim(); - if ("false".equalsIgnoreCase(trimmedLevel)) { - return LogLevel.OFF; - } - return LogLevel.valueOf(trimmedLevel.toUpperCase(Locale.ENGLISH)); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapDisabled.java b/spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapDisabled.java deleted file mode 100644 index 9a5f6d59..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapDisabled.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.util; - -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.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; -import org.springframework.context.annotation.Conditional; - -import static org.springframework.cloud.util.PropertyUtils.BOOTSTRAP_ENABLED_PROPERTY; -import static org.springframework.cloud.util.PropertyUtils.MARKER_CLASS; -import static org.springframework.cloud.util.PropertyUtils.USE_LEGACY_PROCESSING_PROPERTY; - -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Conditional(ConditionalOnBootstrapDisabled.OnBootstrapDisabledCondition.class) -public @interface ConditionalOnBootstrapDisabled { - - class OnBootstrapDisabledCondition extends NoneNestedConditions { - - OnBootstrapDisabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnClass(name = MARKER_CLASS) - static class OnBootstrapMarkerClassPresent { - - } - - @ConditionalOnProperty(name = USE_LEGACY_PROCESSING_PROPERTY) - static class OnUseLegacyProcessingEnabled { - - } - - @ConditionalOnProperty(name = BOOTSTRAP_ENABLED_PROPERTY) - static class OnBootstrapEnabled { - - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapEnabled.java b/spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapEnabled.java deleted file mode 100644 index 23c7faa3..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/util/ConditionalOnBootstrapEnabled.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.util; - -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.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Conditional; - -import static org.springframework.cloud.util.PropertyUtils.BOOTSTRAP_ENABLED_PROPERTY; -import static org.springframework.cloud.util.PropertyUtils.USE_LEGACY_PROCESSING_PROPERTY; - -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Conditional(ConditionalOnBootstrapEnabled.OnBootstrapEnabledCondition.class) -public @interface ConditionalOnBootstrapEnabled { - - class OnBootstrapEnabledCondition extends AnyNestedCondition { - - OnBootstrapEnabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnClass(name = PropertyUtils.MARKER_CLASS) - static class OnBootstrapMarkerClassPresent { - - } - - @ConditionalOnProperty(name = USE_LEGACY_PROCESSING_PROPERTY) - static class OnUseLegacyProcessingEnabled { - - } - - @ConditionalOnProperty(name = BOOTSTRAP_ENABLED_PROPERTY) - static class OnBootstrapEnabled { - - } - - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/util/PropertyUtils.java b/spring-cloud-context/src/main/java/org/springframework/cloud/util/PropertyUtils.java deleted file mode 100644 index 0150d2ad..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/util/PropertyUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.util; - -import org.springframework.core.env.Environment; -import org.springframework.util.ClassUtils; - -public abstract class PropertyUtils { - - /** - * Property name for checking if bootstrap is enabled. - */ - public static final String BOOTSTRAP_ENABLED_PROPERTY = "spring.cloud.bootstrap.enabled"; - - /** - * Property name for spring boot legacy processing. - */ - public static final String USE_LEGACY_PROCESSING_PROPERTY = "spring.config.use-legacy-processing"; - - /** - * Property name for bootstrap marker class name. - */ - public static final String MARKER_CLASS = "org.springframework.cloud.bootstrap.marker.Marker"; - - /** - * Boolean if bootstrap marker class exists. - */ - public static final boolean MARKER_CLASS_EXISTS = ClassUtils.isPresent(MARKER_CLASS, null); - - private PropertyUtils() { - throw new UnsupportedOperationException("unable to instatiate utils class"); - } - - public static boolean bootstrapEnabled(Environment environment) { - return environment.getProperty(BOOTSTRAP_ENABLED_PROPERTY, Boolean.class, false) || MARKER_CLASS_EXISTS; - } - - public static boolean useLegacyProcessing(Environment environment) { - return environment.getProperty(USE_LEGACY_PROCESSING_PROPERTY, Boolean.class, false); - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/util/ProxyUtils.java b/spring-cloud-context/src/main/java/org/springframework/cloud/util/ProxyUtils.java deleted file mode 100644 index 6dfb5528..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/util/ProxyUtils.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.util; - -import org.springframework.aop.framework.Advised; -import org.springframework.aop.support.AopUtils; -import org.springframework.util.Assert; - -/** - * @author Ryan Baxter - */ -public final class ProxyUtils { - - private ProxyUtils() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - @SuppressWarnings("unchecked") - public static T getTargetObject(Object candidate) { - Assert.notNull(candidate, "Candidate must not be null"); - try { - if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised) { - Object target = ((Advised) candidate).getTargetSource().getTarget(); - if (target != null) { - return (T) getTargetObject(target); - } - } - } - catch (Exception ex) { - throw new IllegalStateException("Failed to unwrap proxied object", ex); - } - return (T) candidate; - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySource.java b/spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySource.java deleted file mode 100644 index a9003051..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySource.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.util.random; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.core.env.PropertySource; -import org.springframework.util.StringUtils; - -/** - * @author Ryan Baxter - */ -public class CachedRandomPropertySource extends PropertySource { - - static final String NAME = "cachedrandom"; - - private static final String PREFIX = NAME + "."; - - private static Map> cache = new ConcurrentHashMap<>(); - - public CachedRandomPropertySource(PropertySource randomValuePropertySource) { - super(NAME, randomValuePropertySource); - - } - - CachedRandomPropertySource(PropertySource randomValuePropertySource, Map> cache) { - super(NAME, randomValuePropertySource); - CachedRandomPropertySource.cache = cache; - } - - @Override - public Object getProperty(String name) { - if (!name.startsWith(PREFIX) || name.length() == PREFIX.length()) { - return null; - } - else { - if (logger.isTraceEnabled()) { - logger.trace("Generating random property for '" + name + "'"); - } - // TO avoid any weirdness from the type or key including a "." we look for the - // last "." and substring everything instead of splitting on the "." - String keyAndType = name.substring(PREFIX.length()); - int lastIndexOfDot = keyAndType.lastIndexOf("."); - if (lastIndexOfDot < 0) { - return null; - } - String key = keyAndType.substring(0, lastIndexOfDot); - String type = keyAndType.substring(lastIndexOfDot + 1); - if (StringUtils.hasText(key) && StringUtils.hasText(type)) { - return getRandom(type, key); - } - else { - return null; - } - } - } - - private Object getRandom(String type, String key) { - Map randomValueCache = getCacheForKey(key); - if (logger.isDebugEnabled()) { - logger.debug("Looking in random cache for key " + key + " with type " + type); - } - return randomValueCache.computeIfAbsent(type, (theType) -> { - if (logger.isDebugEnabled()) { - logger.debug(String.format( - "No random value found in cache for key: %s and type: %s, generating a new value", key, type)); - } - return getSource().getProperty("random." + type); - }); - } - - private Map getCacheForKey(String key) { - if (logger.isDebugEnabled()) { - logger.debug("Looking in random cache for key: " + key); - } - return cache.computeIfAbsent(key, theKey -> { - if (logger.isDebugEnabled()) { - logger.debug("No cached value found for key: " + key); - } - return new ConcurrentHashMap<>(); - }); - } - - public static void clearCache() { - if (cache != null) { - cache.clear(); - } - } - -} diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySourceEnvironmentPostProcessor.java b/spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySourceEnvironmentPostProcessor.java deleted file mode 100644 index 5e359f50..00000000 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/util/random/CachedRandomPropertySourceEnvironmentPostProcessor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.util.random; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.boot.env.RandomValuePropertySource; -import org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; - -/** - * @author Ryan Baxter - */ -@Configuration(proxyBeanMethods = false) -public class CachedRandomPropertySourceEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered { - - private static final Log logger = LogFactory.getLog(CachedRandomPropertySourceEnvironmentPostProcessor.class); - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - MutablePropertySources propertySources = environment.getPropertySources(); - PropertySource propertySource = propertySources.get(RandomValuePropertySource.RANDOM_PROPERTY_SOURCE_NAME); - if (propertySource != null) { - PropertySource existing = propertySources.get(CachedRandomPropertySource.NAME); - if (existing != null) { - logger.trace("CachedRandomPropertySource already present"); - return; - } - propertySources.addLast(new CachedRandomPropertySource(propertySource)); - logger.trace("CachedRandomPropertySource added to Environment"); - } - } - - @Override - public int getOrder() { - return RandomValuePropertySourceEnvironmentPostProcessor.ORDER + 1; - } - -} diff --git a/spring-cloud-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index 835dae75..00000000 --- a/spring-cloud-context/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "properties": [ - { - "name": "management.health.refresh.enabled", - "type": "java.lang.Boolean", - "description": "Enable the health endpoint for the refresh scope.", - "defaultValue": true - }, - { - "name": "management.endpoint.env.post.enabled", - "type": "java.lang.Boolean", - "description": "Enable changing the Environment through a POST to /env.", - "defaultValue": false - }, - { - "name": "management.endpoint.refresh.enabled", - "type": "java.lang.Boolean", - "description": "Enable the /refresh endpoint to refresh configuration and re-initialize refresh scoped beans.", - "defaultValue": true - }, - { - "name": "management.endpoint.restart.enabled", - "type": "java.lang.Boolean", - "description": "Enable the /restart endpoint to restart the application context.", - "defaultValue": true - }, - { - "name": "management.endpoint.pause.enabled", - "type": "java.lang.Boolean", - "description": "Enable the /pause endpoint (to send Lifecycle.stop()).", - "defaultValue": true - }, - { - "name": "management.endpoint.resume.enabled", - "type": "java.lang.Boolean", - "description": "Enable the /resume endpoint (to send Lifecycle.start()).", - "defaultValue": true - }, - { - "name": "spring.cloud.refresh.extra-refreshable", - "type": "java.util.Set", - "description": "Additional class names for beans to post process into refresh scope.", - "defaultValue": true - }, - { - "name": "spring.cloud.refresh.never-refreshable", - "type": "java.lang.String", - "description": "Comma separated list of class names for beans to never be refreshed or rebound.", - "defaultValue": true - }, - { - "name": "spring.cloud.decrypt-environment-post-processor.enabled", - "type": "java.lang.Boolean", - "description": "Enable the DecryptEnvironmentPostProcessor.", - "defaultValue": true - } - ] -} - diff --git a/spring-cloud-context/src/main/resources/META-INF/spring.factories b/spring-cloud-context/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 6d43199b..00000000 --- a/spring-cloud-context/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,20 +0,0 @@ -# Application Listeners -org.springframework.context.ApplicationListener=\ -org.springframework.cloud.bootstrap.BootstrapApplicationListener,\ -org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\ -org.springframework.cloud.context.restart.RestartListener -# Spring Cloud Bootstrap components -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\ -org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\ -org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\ -org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration -# Spring Boot BootstrapRegistryInitializer -org.springframework.boot.BootstrapRegistryInitializer=\ -org.springframework.cloud.bootstrap.RefreshBootstrapRegistryInitializer,\ -org.springframework.cloud.bootstrap.TextEncryptorConfigBootstrapper -# Environment Post Processors -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.cloud.bootstrap.BootstrapConfigFileApplicationListener,\ -org.springframework.cloud.bootstrap.encrypt.DecryptEnvironmentPostProcessor,\ -org.springframework.cloud.util.random.CachedRandomPropertySourceEnvironmentPostProcessor diff --git a/spring-cloud-context/src/main/resources/META-INF/spring/aot.factories b/spring-cloud-context/src/main/resources/META-INF/spring/aot.factories deleted file mode 100644 index 8663a91e..00000000 --- a/spring-cloud-context/src/main/resources/META-INF/spring/aot.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.aot.hint.RuntimeHintsRegistrar=\ -org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration.EncryptionHints \ No newline at end of file diff --git a/spring-cloud-context/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-context/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index e214b115..00000000 --- a/spring-cloud-context/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,5 +0,0 @@ -org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration -org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration -org.springframework.cloud.autoconfigure.RefreshAutoConfiguration -org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration -org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java deleted file mode 100644 index cf3af23d..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/LifecycleMvcAutoConfigurationTests.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import java.util.List; -import java.util.function.Function; - -import org.assertj.core.util.Lists; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.context.restart.RestartEndpoint; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.ResponseEntity; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - */ -// TODO: super slow. Port to @SpringBootTest -public class LifecycleMvcAutoConfigurationTests { - - private static ConfigurableApplicationContext getApplicationContext(Class configuration, String... properties) { - - List defaultProperties = Lists.newArrayList(properties); - defaultProperties.add("server.port=0"); - defaultProperties.add("spring.jmx.default-domain=${random.uuid}"); - - return new SpringApplicationBuilder(configuration).properties(defaultProperties.toArray(new String[] {})).run(); - } - - @Test - public void environmentWebEndpointExtensionDisabled() { - beanNotCreated("writableEnvironmentEndpointWebExtension", "management.endpoint.env.enabled=false"); - } - - @Test - public void environmentWebEndpointExtensionGloballyDisabled() { - beanNotCreated("writableEnvironmentEndpointWebExtension", "management.endpoints.enabled-by-default=false"); - } - - @Test - public void environmentWebEndpointExtensionEnabled() { - beanCreated("writableEnvironmentEndpointWebExtension", "management.endpoint.env.enabled=true", - "management.endpoint.env.post.enabled=true", "management.endpoints.web.exposure.include=env"); - } - - // restartEndpoint - @Test - public void restartEndpointDisabled() { - beanNotCreated("restartEndpoint", "management.endpoint.restart.enabled=false"); - } - - @Test - public void restartEndpointGloballyDisabled() { - beanNotCreated("restartEndpoint", "management.endpoint.default.enabled=false"); - } - - @Test - public void restartEndpointEnabled() { - beanCreatedAndEndpointEnabled("restartEndpoint", RestartEndpoint.class, RestartEndpoint::restart, - "management.endpoint.restart.enabled=true", "management.endpoints.web.exposure.include=restart"); - } - - // pauseEndpoint - @Test - public void pauseEndpointDisabled() { - beanNotCreated("pauseEndpoint", "management.endpoint.pause.enabled=false"); - } - - @Test - public void pauseEndpointRestartDisabled() { - beanNotCreated("pauseEndpoint", "management.endpoint.restart.enabled=false", - "management.endpoint.pause.enabled=true"); - } - - @Test - public void pauseEndpointGloballyDisabled() { - beanNotCreated("pauseEndpoint", "management.endpoint.default.enabled=false"); - } - - @Test - public void pauseEndpointEnabled() { - beanCreatedAndEndpointEnabled("pauseEndpoint", RestartEndpoint.PauseEndpoint.class, - RestartEndpoint.PauseEndpoint::pause, "management.endpoint.restart.enabled=true", - "management.endpoints.web.exposure.include=restart,pause", "management.endpoint.pause.enabled=true"); - } - - // resumeEndpoint - @Test - public void resumeEndpointDisabled() { - beanNotCreated("resumeEndpoint", "management.endpoint.restart.enabled=true", - "management.endpoints.web.exposure.include=restart", "management.endpoint.resume.enabled=false"); - } - - @Test - public void resumeEndpointRestartDisabled() { - beanNotCreated("resumeEndpoint", "management.endpoint.restart.enabled=false", - "management.endpoints.web.exposure.include=resume", "management.endpoint.resume.enabled=true"); - } - - @Test - public void resumeEndpointGloballyDisabled() { - beanNotCreated("resumeEndpoint", "management.endpoint.default.enabled=false"); - } - - @Test - public void resumeEndpointEnabled() { - beanCreatedAndEndpointEnabled("resumeEndpoint", RestartEndpoint.ResumeEndpoint.class, - RestartEndpoint.ResumeEndpoint::resume, "management.endpoint.restart.enabled=true", - "management.endpoint.resume.enabled=true", "management.endpoints.web.exposure.include=restart,resume"); - } - - private void beanNotCreated(String beanName, String... contextProperties) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { - then(context.containsBeanDefinition(beanName)).as("%s bean was created", beanName).isFalse(); - } - } - - private void beanCreated(String beanName, String... contextProperties) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) { - then(context.containsBeanDefinition(beanName)).as("%s bean was not created", beanName).isTrue(); - } - } - - @SuppressWarnings("unchecked") - private void beanCreatedAndEndpointEnabled(String beanName, Class type, Function function, - String... properties) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, properties)) { - then(context.containsBeanDefinition(beanName)).as("%s bean was not created", beanName).isTrue(); - - Object endpoint = context.getBean(beanName, type); - Object result = function.apply((T) endpoint); - - then(result).as("result is wrong type").isNotInstanceOf(ResponseEntity.class); - } - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class Config { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java deleted file mode 100644 index 86e16a76..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.endpoint.event.RefreshEventListener; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - */ -@ClassPathExclusions({ "spring-boot-actuator-*.jar", "spring-boot-starter-actuator-*.jar" }) -public class RefreshAutoConfigurationClassPathTests { - - private static ConfigurableApplicationContext getApplicationContext(Class configuration, String... properties) { - return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE).properties(properties).run(); - } - - @Test - public void refreshEventListenerCreated() { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class)) { - then(context.getBeansOfType(RefreshEventListener.class)).as("RefreshEventListeners not created") - .isNotEmpty(); - then(context.containsBean("refreshEndpoint")).as("refreshEndpoint created").isFalse(); - } - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class Config { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationMoreClassPathTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationMoreClassPathTests.java deleted file mode 100644 index 664d12f5..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationMoreClassPathTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - */ -@ClassPathExclusions({ "spring-boot-actuator-autoconfigure-*.jar", "spring-boot-starter-actuator-*.jar" }) -@ExtendWith(OutputCaptureExtension.class) -public class RefreshAutoConfigurationMoreClassPathTests { - - private static ConfigurableApplicationContext getApplicationContext(Class configuration, String... properties) { - return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE).properties(properties).run(); - } - - @Test - public void unknownClassProtected(CapturedOutput outputCapture) { - try (ConfigurableApplicationContext context = getApplicationContext(Config.class, "debug=true")) { - String output = outputCapture.toString(); - then(output) - .doesNotContain("Failed to introspect annotations on " - + "[class org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration") - .doesNotContain("TypeNotPresentExceptionProxy"); - } - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class Config { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java deleted file mode 100644 index 04bf003c..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationTests.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.autoconfigure; - -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - */ -@ExtendWith(OutputCaptureExtension.class) -public class RefreshAutoConfigurationTests { - - private static ConfigurableApplicationContext getApplicationContext(WebApplicationType type, Class configuration, - String... properties) { - return new SpringApplicationBuilder(configuration).web(type).properties(properties).properties("server.port=0") - .run(); - } - - @Test - public void noWarnings(CapturedOutput output) { - try (ConfigurableApplicationContext context = getApplicationContext(WebApplicationType.NONE, Config.class)) { - then(context.containsBean("refreshScope")).isTrue(); - then(output.toString()).doesNotContain("WARN"); - } - } - - @Test - public void disabled() { - try (ConfigurableApplicationContext context = getApplicationContext(WebApplicationType.SERVLET, Config.class, - "spring.cloud.refresh.enabled:false")) { - then(context.containsBean("refreshScope")).isFalse(); - } - } - - @Test - public void refreshables() { - try (ConfigurableApplicationContext context = getApplicationContext(WebApplicationType.NONE, Config.class, - "config.foo=bar", "spring.cloud.refresh.refreshable:" + SealedConfigProps.class.getName())) { - context.getBean(SealedConfigProps.class); - context.getBean(ContextRefresher.class).refresh(); - } - } - - @Test - public void extraRefreshables() { - try (ConfigurableApplicationContext context = getApplicationContext(WebApplicationType.NONE, Config.class, - "sealedconfig.foo=bar", - "spring.cloud.refresh.extra-refreshable:" + SealedConfigProps.class.getName())) { - context.getBean(SealedConfigProps.class); - context.getBean(ContextRefresher.class).refresh(); - } - } - - @Test - public void neverRefreshable() { - try (ConfigurableApplicationContext context = getApplicationContext(WebApplicationType.NONE, Config.class, - "countingconfig.foo=bar", - "spring.cloud.refresh.never-refreshable:" + CountingConfigProps.class.getName())) { - CountingConfigProps configProps = context.getBean(CountingConfigProps.class); - context.getBean(ContextRefresher.class).refresh(); - assertThat(configProps.count).as("config props was rebound when it should not have been").hasValue(1); - } - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class) - @EnableConfigurationProperties({ SealedConfigProps.class, CountingConfigProps.class }) - static class Config { - - } - - @ConfigurationProperties("sealedconfig") - static class SealedConfigProps { - - private String foo; - - private boolean sealed; - - public String getFoo() { - return this.foo; - } - - public void setFoo(String foo) { - if (this.sealed) { - throw new IllegalStateException("Cannot set sealed property"); - } - this.foo = foo; - this.sealed = true; - } - - } - - @ConfigurationProperties("countingconfig") - static class CountingConfigProps { - - private final AtomicInteger count = new AtomicInteger(); - - private String foo; - - public String getFoo() { - return this.foo; - } - - public void setFoo(String foo) { - count.incrementAndGet(); - this.foo = foo; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapDisabledAutoConfigurationIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapDisabledAutoConfigurationIntegrationTests.java deleted file mode 100644 index a3ba747d..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapDisabledAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.bootstrap.BootstrapDisabledAutoConfigurationIntegrationTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = Application.class, properties = "spring.cloud.bootstrap.enabled:false") -public class BootstrapDisabledAutoConfigurationIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @Test - public void noBootstrapProperties() { - then(this.environment.getPropertySources().contains("bootstrap")).isFalse(); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - protected static class Application { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingAutoConfigurationIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingAutoConfigurationIntegrationTests.java deleted file mode 100644 index 693314ac..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.bootstrap.BootstrapOrderingAutoConfigurationIntegrationTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.context.ActiveProfiles; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = Application.class, - properties = { "encrypt.key:deadbeef", "spring.cloud.bootstrap.enabled=true" }) -@ActiveProfiles("encrypt") -public class BootstrapOrderingAutoConfigurationIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @Test - public void bootstrapPropertiesExist() { - then(this.environment.getPropertySources().contains("applicationConfig: [classpath:/bootstrap.properties]")) - .isTrue(); - } - - @Test - public void normalPropertiesDecrypted() { - then(this.environment.resolvePlaceholders("${foo}")).isEqualTo("foo"); - } - - @Test - public void bootstrapPropertiesDecrypted() { - then(this.environment.resolvePlaceholders("${bar}")).isEqualTo("bar"); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - protected static class Application { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomOverrideSystemPropertiesIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomOverrideSystemPropertiesIntegrationTests.java deleted file mode 100644 index 4842d873..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomOverrideSystemPropertiesIntegrationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.bootstrap.BootstrapOrderingCustomPropertySourceIntegrationTests.Application; -import org.springframework.cloud.bootstrap.config.PropertySourceLocator; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; - -import static java.util.Collections.singletonMap; -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest(classes = Application.class, - properties = { "spring.cloud.bootstrap.enabled=true", "spring.cloud.bootstrap.name:ordering" }) -public class BootstrapOrderingCustomOverrideSystemPropertiesIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @Test - public void orderingIsCorrect() { - MutablePropertySources propertySources = environment.getPropertySources(); - PropertySource test1 = propertySources.get("bootstrapProperties-testBootstrap1"); - PropertySource test2 = propertySources.get("bootstrapProperties-testBootstrap2"); - PropertySource test3 = propertySources.get("bootstrapProperties-testBootstrap3"); - int index1 = propertySources.precedenceOf(test1); - int index2 = propertySources.precedenceOf(test2); - int index3 = propertySources.precedenceOf(test3); - assertThat(index1).as("source1 index not less then source2").isLessThan(index2); - assertThat(index2).as("source2 index not less then source3").isLessThan(index3); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - protected static class Application { - - } - - @Configuration(proxyBeanMethods = false) - // This is added to bootstrap context as a source in ordering.properties - protected static class PropertySourceConfiguration implements PropertySourceLocator { - - @Override - public PropertySource locate(Environment environment) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection> locateCollection(Environment environment) { - ArrayList> sources = new ArrayList<>(); - sources.add(new MapPropertySource("testBootstrap1", singletonMap("key1", "value1"))); - sources.add(new MapPropertySource("testBootstrap2", singletonMap("key2", "value2"))); - Map map = new HashMap<>(); - map.put("key3", "value3"); - map.put("spring.cloud.config.override-system-properties", "false"); - sources.add(new MapPropertySource("testBootstrap3", map)); - return sources; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomPropertySourceIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomPropertySourceIntegrationTests.java deleted file mode 100644 index dc20fdeb..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingCustomPropertySourceIntegrationTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.bootstrap.BootstrapOrderingCustomPropertySourceIntegrationTests.Application; -import org.springframework.cloud.bootstrap.config.PropertySourceLocator; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.test.context.ActiveProfiles; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = Application.class, - properties = { "encrypt.key:deadbeef", "spring.cloud.bootstrap.name:custom", - "spring.cloud.bootstrap.enabled=true" }) -@ActiveProfiles("encrypt") -public class BootstrapOrderingCustomPropertySourceIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @Test - public void bootstrapPropertiesExist() { - then(this.environment.getPropertySources().contains("applicationConfig: [classpath:/custom.properties]")) - .isTrue(); - } - - @Test - public void customPropertiesDecrypted() { - then(this.environment.resolvePlaceholders("${custom.foo}")).isEqualTo("bar"); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - protected static class Application { - - } - - @Configuration(proxyBeanMethods = false) - // This is added to bootstrap context as a source in bootstrap.properties - protected static class PropertySourceConfiguration implements PropertySourceLocator { - - public static Map MAP = new HashMap<>(Collections.singletonMap("custom.foo", - "{cipher}6154ca04d4bb6144d672c4e3d750b5147116dd381946d51fa44f8bc25dc256f4")); - - @Override - public PropertySource locate(Environment environment) { - return new MapPropertySource("testBootstrap", MAP); - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingSpringApplicationJsonIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingSpringApplicationJsonIntegrationTests.java deleted file mode 100644 index a7a142c8..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingSpringApplicationJsonIntegrationTests.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.bootstrap.BootstrapOrderingSpringApplicationJsonIntegrationTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = Application.class, properties = "spring.cloud.bootstrap.name:json") -public class BootstrapOrderingSpringApplicationJsonIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @BeforeAll - public static void spikeJson() { - System.setProperty("SPRING_APPLICATION_JSON", "{\"message\":\"From JSON\"}"); - } - - @AfterAll - public static void unspikeJson() { - System.clearProperty("SPRING_APPLICATION_JSON"); - } - - @Test - public void bootstrapPropertiesExist() { - then(this.environment.getProperty("message")).isEqualTo("From JSON"); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - protected static class Application { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapSourcesOrderingTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapSourcesOrderingTests.java deleted file mode 100644 index 86ce73b1..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/BootstrapSourcesOrderingTests.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.bootstrap.BootstrapOrderingSpringApplicationJsonIntegrationTests.Application; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.cloud.bootstrap.TestHigherPriorityBootstrapConfiguration.firstToBeCreated; - -@SpringBootTest(classes = Application.class, properties = "spring.cloud.bootstrap.enabled=true") -public class BootstrapSourcesOrderingTests { - - @Test - public void sourcesAreOrderedCorrectly() { - Class firstConstructedClass = firstToBeCreated.get(); - then(firstConstructedClass).as("bootstrap sources not ordered correctly") - .isEqualTo(TestHigherPriorityBootstrapConfiguration.class); - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - protected static class Application { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/MessageSourceConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/MessageSourceConfigurationTests.java deleted file mode 100644 index faaf810a..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/MessageSourceConfigurationTests.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -/** - * @author Dave Syer - * - */ - -import java.util.Locale; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.bootstrap.MessageSourceConfigurationTests.TestApplication; -import org.springframework.context.MessageSource; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestApplication.class, properties = "debug=true") -public class MessageSourceConfigurationTests { - - @Autowired - private MessageSource messageSource; - - @Test - public void loadsMessage() { - then(this.messageSource.getMessage("hello.message", null, Locale.getDefault())).isEqualTo("Hello World!"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class TestApplication { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestBootstrapConfiguration.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestBootstrapConfiguration.java deleted file mode 100644 index 3be1123d..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestBootstrapConfiguration.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; - -import static org.springframework.cloud.bootstrap.TestHigherPriorityBootstrapConfiguration.firstToBeCreated; - -/** - * @author Spencer Gibb - */ -@Order(0) -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties -public class TestBootstrapConfiguration { - - public static List fooSightings = null; - - public TestBootstrapConfiguration() { - firstToBeCreated.compareAndSet(null, TestBootstrapConfiguration.class); - } - - @Bean - @Qualifier("foo-during-bootstrap") - public String fooDuringBootstrap(ConfigurableEnvironment environment, ApplicationEventPublisher publisher) { - String property = environment.getProperty("test.bootstrap.foo", "undefined"); - - if (fooSightings != null) { - fooSightings.add(property); - } - - return property; - } - - @Bean - public ApplicationContextInitializer customInitializer() { - return applicationContext -> { - ConfigurableEnvironment environment = applicationContext.getEnvironment(); - environment.getPropertySources().addLast(new MapPropertySource("customProperties", Collections - .singletonMap("custom.foo", environment.resolvePlaceholders("${spring.application.name:bar}")))); - }; - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestHigherPriorityBootstrapConfiguration.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestHigherPriorityBootstrapConfiguration.java deleted file mode 100644 index 40e9626e..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/TestHigherPriorityBootstrapConfiguration.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap; - -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; - -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; - -/** - * @author Spencer Gibb - */ -@Order(Ordered.HIGHEST_PRECEDENCE) -public class TestHigherPriorityBootstrapConfiguration { - - public static final AtomicInteger count = new AtomicInteger(); - static final AtomicReference> firstToBeCreated = new AtomicReference<>(); - - public TestHigherPriorityBootstrapConfiguration() { - count.incrementAndGet(); - firstToBeCreated.compareAndSet(null, TestHigherPriorityBootstrapConfiguration.class); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java deleted file mode 100644 index 1f7c3e0e..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java +++ /dev/null @@ -1,799 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.cloud.bootstrap.BootstrapApplicationListener; -import org.springframework.cloud.bootstrap.TestHigherPriorityBootstrapConfiguration; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - * - */ -public class BootstrapConfigurationTests { - - private ConfigurableApplicationContext context; - - private ConfigurableApplicationContext sibling; - - @AfterEach - public void close() { - // Expected.* is bound to the PropertySourceConfiguration below - System.clearProperty("expected.name"); - System.clearProperty("expected.fail"); - // Used to test system properties override - System.clearProperty("bootstrap.foo"); - PropertySourceConfiguration.MAP.clear(); - CompositePropertySourceConfiguration.MAP1.clear(); - CompositePropertySourceConfiguration.MAP2.clear(); - if (this.context != null) { - this.context.close(); - } - if (this.sibling != null) { - this.sibling.close(); - } - } - - @Test - public void pickupOnlyExternalBootstrapProperties() { - String externalPropertiesPath = getExternalProperties(); - pickupOnlyExternalBootstrapProperties("spring.cloud.bootstrap.location=" + externalPropertiesPath, - "spring.config.use-legacy-processing=true"); - } - - @Test - public void pickupOnlyExternalBootstrapPropertiesWithAppListener() { - String externalPropertiesPath = getExternalProperties(); - pickupOnlyExternalBootstrapProperties("spring.cloud.bootstrap.location=" + externalPropertiesPath, - "spring.config.use-legacy-processing=true", "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void pickupOnlyExternalBootstrapProperties(String... properties) { - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(BareConfiguration.class) - .properties(properties).run(); - then(this.context.getEnvironment().getProperty("info.name")).isEqualTo("externalPropertiesInfoName"); - then(this.context.getEnvironment().getProperty("info.desc")).isNull(); - then(this.context.getEnvironment().getPropertySources() - .contains(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap")) - .isTrue(); - } - - @Test - public void pickupAdditionalExternalBootstrapProperties() { - String externalPropertiesPath = getExternalProperties(); - pickupAdditionalExternalBootstrapProperties( - "spring.cloud.bootstrap.additional-location=" + externalPropertiesPath, - "spring.config.use-legacy-processing=true"); - } - - @Test - public void pickupAdditionalExternalBootstrapPropertiesWithAppListener() { - String externalPropertiesPath = getExternalProperties(); - pickupAdditionalExternalBootstrapProperties( - "spring.cloud.bootstrap.additional-location=" + externalPropertiesPath, - "spring.config.use-legacy-processing=true", "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void pickupAdditionalExternalBootstrapProperties(String... properties) { - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(BareConfiguration.class) - .properties(properties).run(); - then(this.context.getEnvironment().getProperty("info.name")).isEqualTo("externalPropertiesInfoName"); - then(this.context.getEnvironment().getProperty("info.desc")).isEqualTo("defaultPropertiesInfoDesc"); - then(this.context.getEnvironment().getPropertySources() - .contains(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap")) - .isTrue(); - } - - @Test - public void bootstrapPropertiesAvailableInInitializer() { - bootstrapPropertiesAvailableInInitializer("spring.config.use-legacy-processing=true"); - } - - @Test - public void bootstrapPropertiesAvailableInInitializerWithAppContext() { - bootstrapPropertiesAvailableInInitializer("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void bootstrapPropertiesAvailableInInitializer(String... properties) { - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).initializers(applicationContext -> { - // This property is defined in bootstrap.properties - then(applicationContext.getEnvironment().getProperty("info.name")).isEqualTo("child"); - }).run(); - then(this.context.getEnvironment().getPropertySources() - .contains(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap")) - .isTrue(); - } - - /** - * Running the test from maven will start from a different directory then starting it - * from intellij - * @return external properties resource location - */ - private String getExternalProperties() { - String externalPropertiesPath = "classpath:external-properties/bootstrap.properties"; - return externalPropertiesPath; - } - - @Test - public void picksUpAdditionalPropertySource() { - picksUpAdditionalPropertySource("spring.config.use-legacy-processing=true"); - } - - @Test - public void picksUpAdditionalPropertySourceWithAppContext() { - picksUpAdditionalPropertySource("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void picksUpAdditionalPropertySource(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("bar"); - then(this.context.getEnvironment().getPropertySources() - .contains(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap")) - .isTrue(); - } - - @Test - public void failsOnPropertySource() { - failsOnPropertySource("spring.config.use-legacy-processing=true"); - } - - @Test - public void failsOnPropertySourceWithAppContext() { - failsOnPropertySource("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void failsOnPropertySource(String... properties) { - System.setProperty("expected.fail", "true"); - Throwable throwable = Assertions.assertThrows(RuntimeException.class, () -> { - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - }); - then(throwable.getMessage().equals("Planned")); - } - - @Test - public void overrideSystemPropertySourceByDefault() { - overrideSystemPropertySourceByDefault("spring.config.use-legacy-processing=true"); - - } - - @Test - public void overrideSystemPropertySourceByDefaultWithAppContext() { - overrideSystemPropertySourceByDefault("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - - } - - private void overrideSystemPropertySourceByDefault(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - System.setProperty("bootstrap.foo", "system"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("bar"); - } - - @Test - public void systemPropertyOverrideFalse() { - systemPropertyOverrideFalse("spring.config.use-legacy-processing=true"); - } - - @Test - public void systemPropertyOverrideFalseWithAppContext() { - systemPropertyOverrideFalse("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void systemPropertyOverrideFalse(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - PropertySourceConfiguration.MAP.put("spring.cloud.config.overrideSystemProperties", "false"); - System.setProperty("bootstrap.foo", "system"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("system"); - } - - @Test - public void systemPropertyOverrideWhenOverrideDisallowed() { - systemPropertyOverrideWhenOverrideDisallowed("spring.config.use-legacy-processing=true"); - } - - @Test - public void systemPropertyOverrideWhenOverrideDisallowedWithAppContext() { - systemPropertyOverrideWhenOverrideDisallowed("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void systemPropertyOverrideWhenOverrideDisallowed(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - PropertySourceConfiguration.MAP.put("spring.cloud.config.overrideSystemProperties", "false"); - // If spring.cloud.config.allowOverride=false is in the remote property sources - // with sufficiently high priority it always wins. Admins can enforce it by adding - // their own remote property source. - PropertySourceConfiguration.MAP.put("spring.cloud.config.allowOverride", "false"); - System.setProperty("bootstrap.foo", "system"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("bar"); - } - - @Test - public void systemPropertyOverrideFalseWhenOverrideAllowed() { - systemPropertyOverrideFalseWhenOverrideAllowed("spring.config.use-legacy-processing=true"); - } - - @Test - public void systemPropertyOverrideFalseWhenOverrideAllowedWithAppContext() { - systemPropertyOverrideFalseWhenOverrideAllowed("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void systemPropertyOverrideFalseWhenOverrideAllowed(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - PropertySourceConfiguration.MAP.put("spring.cloud.config.overrideSystemProperties", "false"); - PropertySourceConfiguration.MAP.put("spring.cloud.config.allowOverride", "true"); - System.setProperty("bootstrap.foo", "system"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("system"); - } - - @Test - public void overrideAllWhenOverrideAllowed() { - overrideAllWhenOverrideAllowed("spring.config.use-legacy-processing=true"); - } - - @Test - public void overrideAllWhenOverrideAllowedWithAppContext() { - overrideAllWhenOverrideAllowed("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void overrideAllWhenOverrideAllowed(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - PropertySourceConfiguration.MAP.put("spring.cloud.config.overrideNone", "true"); - PropertySourceConfiguration.MAP.put("spring.cloud.config.allowOverride", "true"); - ConfigurableEnvironment environment = new StandardEnvironment(); - environment.getPropertySources().addLast( - new MapPropertySource("last", Collections.singletonMap("bootstrap.foo", "splat"))); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .environment(environment).sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("splat"); - } - - @Test - public void applicationNameInBootstrapAndMain() { - applicationNameInBootstrapAndMain("spring.cloud.bootstrap.name:other", - "spring.config.use-legacy-processing=true", "spring.config.name:plain"); - } - - @Test - public void applicationNameInBootstrapAndMainWithAppContext() { - applicationNameInBootstrapAndMain("spring.cloud.bootstrap.name:other", - "spring.config.use-legacy-processing=true", "spring.config.name:plain", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void applicationNameInBootstrapAndMain(String... properties) { - System.setProperty("expected.name", "main"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("spring.application.name")).isEqualTo("app"); - // The parent is called "main" because spring.application.name is specified in - // other.properties (the bootstrap properties) - then(this.context.getParent().getEnvironment().getProperty("spring.application.name")).isEqualTo("main"); - // The bootstrap context has the same "bootstrap" property source - then(((ConfigurableEnvironment) this.context.getParent().getEnvironment()).getPropertySources() - .get("bootstrap")).isEqualTo(this.context.getEnvironment().getPropertySources().get("bootstrap")); - then(this.context.getId()).isEqualTo("main-1"); - } - - @Test - public void applicationNameNotInBootstrap() { - applicationNameNotInBootstrap("spring.cloud.bootstrap.name:application", - "spring.config.use-legacy-processing=true", "spring.config.name:other"); - } - - @Test - public void applicationNameNotInBootstrapWithAppContext() { - applicationNameNotInBootstrap("spring.cloud.bootstrap.name:application", - "spring.config.use-legacy-processing=true", "spring.config.name:other", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void applicationNameNotInBootstrap(String... properties) { - System.setProperty("expected.name", "main"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().getProperty("spring.application.name")).isEqualTo("main"); - // The parent has no name because spring.application.name is not - // defined in the bootstrap properties - then(this.context.getParent().getEnvironment().getProperty("spring.application.name")).isEqualTo(null); - } - - @Test - public void applicationNameOnlyInBootstrap() { - applicationNameOnlyInBootstrap("spring.cloud.bootstrap.name:other", "spring.config.use-legacy-processing=true"); - } - - @Test - public void applicationNameOnlyInBootstrapWithAppContext() { - applicationNameOnlyInBootstrap("spring.cloud.bootstrap.name:other", "spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void applicationNameOnlyInBootstrap(String... properties) { - System.setProperty("expected.name", "main"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .sources(BareConfiguration.class).run(); - // The main context is called "main" because spring.application.name is specified - // in other.properties (and not in the main config file) - then(this.context.getEnvironment().getProperty("spring.application.name")).isEqualTo("main"); - // The parent is called "main" because spring.application.name is specified in - // other.properties (the bootstrap properties this time) - then(this.context.getParent().getEnvironment().getProperty("spring.application.name")).isEqualTo("main"); - then(this.context.getId()).isEqualTo("main-1"); - } - - @Test - public void environmentEnrichedOnceWhenSharedWithChildContext() { - environmentEnrichedOnceWhenSharedWithChildContext("spring.config.use-legacy-processing=true"); - } - - @Test - public void environmentEnrichedOnceWhenSharedWithChildContextWithAppContext() { - environmentEnrichedOnceWhenSharedWithChildContext("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void environmentEnrichedOnceWhenSharedWithChildContext(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - this.context = new SpringApplicationBuilder().sources(BareConfiguration.class).properties(properties) - .environment(new StandardEnvironment()).child(BareConfiguration.class).web(WebApplicationType.NONE) - .run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("bar"); - then(this.context.getParent().getEnvironment()).isEqualTo(this.context.getEnvironment()); - MutablePropertySources sources = this.context.getEnvironment().getPropertySources(); - PropertySource bootstrap = sources - .get(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap"); - then(bootstrap).isNotNull(); - then(sources.precedenceOf(bootstrap)).isEqualTo(0); - } - - @Test - public void onlyOneBootstrapContext() { - onlyOneBootstrapContext("spring.config.use-legacy-processing=true"); - } - - @Test - public void onlyOneBootstrapContextWithAppContext() { - onlyOneBootstrapContext("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void onlyOneBootstrapContext(String... properties) { - TestHigherPriorityBootstrapConfiguration.count.set(0); - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - this.context = new SpringApplicationBuilder().sources(BareConfiguration.class).properties(properties) - .child(BareConfiguration.class).web(WebApplicationType.NONE).run(); - then(TestHigherPriorityBootstrapConfiguration.count.get()).isEqualTo(1); - then(this.context.getParent()).isNotNull(); - then(this.context.getParent().getParent().getId()).isEqualTo("bootstrap"); - then(this.context.getParent().getParent().getParent()).isNull(); - then(this.context.getEnvironment().getProperty("custom.foo")).isEqualTo("bar"); - } - - @Test - public void listOverride() { - listOverride("spring.config.use-legacy-processing=true"); - } - - @Test - public void listOverrideWithAppContext() { - listOverride("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void listOverride(String... properties) { - this.context = new SpringApplicationBuilder().sources(BareConfiguration.class).properties(properties) - .child(BareConfiguration.class).web(WebApplicationType.NONE).run(); - ListProperties listProperties = new ListProperties(); - Binder.get(this.context.getEnvironment()).bind("list", Bindable.ofInstance(listProperties)); - then(listProperties.getFoo().size()).isEqualTo(1); - then(listProperties.getFoo().get(0)).isEqualTo("hello world"); - } - - @Test - public void bootstrapContextSharedBySiblings() { - bootstrapContextSharedBySiblings("spring.config.use-legacy-processing=true"); - } - - @Test - public void bootstrapContextSharedBySiblingsWithAppContext() { - bootstrapContextSharedBySiblings("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void bootstrapContextSharedBySiblings(String... properties) { - TestHigherPriorityBootstrapConfiguration.count.set(0); - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - SpringApplicationBuilder builder = new SpringApplicationBuilder().properties(properties) - .sources(BareConfiguration.class); - this.sibling = builder.child(BareConfiguration.class).properties("spring.application.name=sibling") - .web(WebApplicationType.NONE).run(); - this.context = builder.child(BareConfiguration.class).properties("spring.application.name=context") - .web(WebApplicationType.NONE).run(); - then(TestHigherPriorityBootstrapConfiguration.count.get()).isEqualTo(1); - then(this.context.getParent()).isNotNull(); - then(this.context.getParent().getParent().getId()).isEqualTo("bootstrap"); - then(this.context.getParent().getParent().getParent()).isNull(); - then(this.context.getEnvironment().getProperty("custom.foo")).isEqualTo("context"); - then(this.context.getEnvironment().getProperty("spring.application.name")).isEqualTo("context"); - then(this.sibling.getParent()).isNotNull(); - then(this.sibling.getParent().getParent().getId()).isEqualTo("bootstrap"); - then(this.sibling.getParent().getParent().getParent()).isNull(); - then(this.sibling.getEnvironment().getProperty("custom.foo")).isEqualTo("sibling"); - then(this.sibling.getEnvironment().getProperty("spring.application.name")).isEqualTo("sibling"); - } - - @Test - public void environmentEnrichedInParentContext() { - environmentEnrichedInParentContext("spring.config.use-legacy-processing=true"); - } - - @Test - public void environmentEnrichedInParentContextWithAppContext() { - environmentEnrichedInParentContext("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void environmentEnrichedInParentContext(String... properties) { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - this.context = new SpringApplicationBuilder().sources(BareConfiguration.class).properties(properties) - .child(BareConfiguration.class).web(WebApplicationType.NONE).run(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("bar"); - then(this.context.getParent().getEnvironment()).isNotSameAs(this.context.getEnvironment()); - then(this.context.getEnvironment().getPropertySources() - .contains(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap")) - .isTrue(); - then(((ConfigurableEnvironment) this.context.getParent().getEnvironment()).getPropertySources() - .contains(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap")) - .isTrue(); - } - - @Test - @Disabled // FIXME: legacy - public void differentProfileInChild() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - // Profiles are always merged with the child - ConfigurableApplicationContext parent = new SpringApplicationBuilder().sources(BareConfiguration.class) - .profiles("parent").web(WebApplicationType.NONE).run(); - this.context = new SpringApplicationBuilder(BareConfiguration.class) - .properties("spring.config.use-legacy-processing=true").profiles("child").parent(parent) - .web(WebApplicationType.NONE).run(); - then(this.context.getParent().getEnvironment()).isNotSameAs(this.context.getEnvironment()); - // The ApplicationContext merges profiles (profiles and property sources), see - // AbstractEnvironment.merge() - then(this.context.getEnvironment().acceptsProfiles("child", "parent")).isTrue(); - // But the parent is not a child - then(this.context.getParent().getEnvironment().acceptsProfiles("child")).isFalse(); - then(this.context.getParent().getEnvironment().acceptsProfiles("parent")).isTrue(); - then(((ConfigurableEnvironment) this.context.getParent().getEnvironment()).getPropertySources() - .contains(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-testBootstrap")) - .isTrue(); - then(this.context.getEnvironment().getProperty("bootstrap.foo")).isEqualTo("bar"); - // The "bootstrap" property source is not shared now, but it has the same - // properties in it because they are pulled from the PropertySourceConfiguration - // below - then(this.context.getParent().getEnvironment().getProperty("bootstrap.foo")).isEqualTo("bar"); - // The parent property source is there in the child because they are both in the - // "parent" profile (by virtue of the merge in AbstractEnvironment) - then(this.context.getEnvironment().getProperty("info.name")).isEqualTo("parent"); - } - - @Test - public void includeProfileFromBootstrapPropertySource() { - includeProfileFromBootstrapPropertySource("spring.config.use-legacy-processing=true"); - } - - @Test - public void includeProfileFromBootstrapPropertySourceWithAppContext() { - includeProfileFromBootstrapPropertySource("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void includeProfileFromBootstrapPropertySource(String... properties) { - PropertySourceConfiguration.MAP.put("spring.profiles.include", "bar,baz"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .profiles("foo").sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().acceptsProfiles("baz")).isTrue(); - then(this.context.getEnvironment().acceptsProfiles("bar")).isTrue(); - } - - @Test - public void activeProfileFromBootstrapPropertySource() { - activeProfileFromBootstrapPropertySource("spring.config.use-legacy-processing=true"); - then(this.context.getEnvironment().getActiveProfiles()).contains("foo"); - } - - @Test - public void activeProfileFromBootstrapPropertySourceWithAppContext() { - activeProfileFromBootstrapPropertySource("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - then(this.context.getEnvironment().getActiveProfiles()).doesNotContain("after"); - then(this.context.getEnvironment().getActiveProfiles()).contains("baz", "bar", "foo"); - } - - private void activeProfileFromBootstrapPropertySource(String... properties) { - PropertySourceConfiguration.MAP.put("spring.profiles.active", "bar,baz"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .profiles("foo").sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().acceptsProfiles("baz", "bar", "foo")).isTrue(); - - } - - @Test - public void activeAndIncludeProfileFromBootstrapPropertySource() { - activeAndIncludeProfileFromBootstrapPropertySource("spring.config.use-legacy-processing=true"); - } - - @Test - public void activeAndIncludeProfileFromBootstrapPropertySourceWithAppContext() { - activeAndIncludeProfileFromBootstrapPropertySource("spring.config.use-legacy-processing=true", - "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void activeAndIncludeProfileFromBootstrapPropertySource(String... properties) { - PropertySourceConfiguration.MAP.put("spring.profiles.active", "bar,baz"); - PropertySourceConfiguration.MAP.put("spring.profiles.include", "bar,baz,hello"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .profiles("foo").sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().acceptsProfiles("baz", "bar", "hello", "foo")).isTrue(); - then(this.context.getEnvironment().getActiveProfiles()).contains("baz", "bar", "foo", "hello"); - } - - @Test - public void activeAndIncludeProfileFromBootstrapPropertySourceWithReplacement() { - activeAndIncludeProfileFromBootstrapPropertySourceWithReplacement("spring.config.use-legacy-processing=true", - "barreplacement=bar"); - } - - @Test - public void activeAndIncludeProfileFromBootstrapPropertySourceWithReplacementWithAppContext() { - activeAndIncludeProfileFromBootstrapPropertySourceWithReplacement("spring.config.use-legacy-processing=true", - "barreplacement=bar", "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void activeAndIncludeProfileFromBootstrapPropertySourceWithReplacement(String... properties) { - PropertySourceConfiguration.MAP.put("spring.profiles.active", "${barreplacement},baz"); - PropertySourceConfiguration.MAP.put("spring.profiles.include", "${barreplacement},baz,hello"); - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).properties(properties) - .profiles("foo").sources(BareConfiguration.class).run(); - then(this.context.getEnvironment().acceptsProfiles("baz", "bar", "hello", "foo")).isTrue(); - then(this.context.getEnvironment().getActiveProfiles()).contains("baz", "bar", "foo", "hello"); - } - - @Test - public void includeProfileFromBootstrapProperties() { - includeProfileFromBootstrapProperties("spring.config.use-legacy-processing=true", - "spring.cloud.bootstrap.name=local"); - } - - @Test - public void includeProfileFromBootstrapPropertiesWithAppContext() { - includeProfileFromBootstrapProperties("spring.config.use-legacy-processing=true", - "spring.cloud.bootstrap.name=local", "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void includeProfileFromBootstrapProperties(String... properties) { - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(BareConfiguration.class) - .properties(properties).run(); - then(this.context.getEnvironment().acceptsProfiles("local")).isTrue(); - then(this.context.getEnvironment().getProperty("added")).isEqualTo("Hello added!"); - } - - @Test - public void nonEnumerablePropertySourceWorks() { - nonEnumerablePropertySourceWorks("spring.config.use-legacy-processing=true", - "spring.cloud.bootstrap.name=nonenumerable"); - } - - @Test - public void nonEnumerablePropertySourceWorksWithAppContext() { - nonEnumerablePropertySourceWorks("spring.config.use-legacy-processing=true", - "spring.cloud.bootstrap.name=nonenumerable", "spring.cloud.config.initialize-on-context-refresh=true"); - } - - private void nonEnumerablePropertySourceWorks(String... properties) { - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE).sources(BareConfiguration.class) - .properties(properties).run(); - then(this.context.getEnvironment().getProperty("foo")).isEqualTo("bar"); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - protected static class BareConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - // This is added to bootstrap context as a source in bootstrap.properties - protected static class SimplePropertySourceConfiguration implements PropertySourceLocator { - - @Override - public PropertySource locate(Environment environment) { - return new PropertySource("testBootstrapSimple", this) { - @Override - public Object getProperty(String name) { - return ("foo".equals(name)) ? "bar" : null; - } - }; - } - - } - - @Configuration(proxyBeanMethods = false) - @ConfigurationProperties("expected") - // This is added to bootstrap context as a source in bootstrap.properties - protected static class PropertySourceConfiguration implements PropertySourceLocator { - - public static Map MAP = new HashMap<>( - Collections.singletonMap("bootstrap.foo", "bar")); - - private String name; - - private boolean fail = false; - - @Override - public PropertySource locate(Environment environment) { - if (environment instanceof ConfigurableEnvironment) { - if (!((ConfigurableEnvironment) environment).getPropertySources() - .contains(BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - if (MAP.containsKey(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME)) { - // This additional profile, after, should not be added when - // initialize-on-context-refresh=true - MAP.put(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, - MAP.get(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME) + ",after"); - } - } - } - if (this.name != null) { - then(this.name).isEqualTo(environment.getProperty("spring.application.name")); - } - if (this.fail) { - throw new RuntimeException("Planned"); - } - - return new MapPropertySource("testBootstrap", MAP); - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public boolean isFail() { - return this.fail; - } - - public void setFail(boolean fail) { - this.fail = fail; - } - - } - - @Configuration - @ConfigurationProperties("compositeexpected") - // This is added to bootstrap context as a source in bootstrap.properties - protected static class CompositePropertySourceConfiguration implements PropertySourceLocator { - - public static Map MAP1 = new HashMap<>(); - - public static Map MAP2 = new HashMap<>(); - - public CompositePropertySourceConfiguration() { - MAP1.put("list.foo[0]", "hello"); - MAP1.put("list.food[1]", "world"); - MAP2.put("list.foo[0]", "hello world"); - } - - private String name; - - private boolean fail = false; - - @Override - public PropertySource locate(Environment environment) { - if (this.name != null) { - then(this.name).isEqualTo(environment.getProperty("spring.application.name")); - } - if (this.fail) { - throw new RuntimeException("Planned"); - } - CompositePropertySource compositePropertySource = new CompositePropertySource("listTestBootstrap"); - compositePropertySource.addFirstPropertySource(new MapPropertySource("testBootstrap1", MAP1)); - compositePropertySource.addFirstPropertySource(new MapPropertySource("testBootstrap2", MAP2)); - return compositePropertySource; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public boolean isFail() { - return this.fail; - } - - public void setFail(boolean fail) { - this.fail = fail; - } - - } - - protected static class ListProperties { - - private List foo; - - public List getFoo() { - return foo; - } - - public void setFoo(List foo) { - this.foo = foo; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapListenerHierarchyIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapListenerHierarchyIntegrationTests.java deleted file mode 100644 index aa5a8085..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapListenerHierarchyIntegrationTests.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.config; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.boot.WebApplicationType.NONE; - -/** - * Integration tests for Bootstrap Listener's functionality of adding a bootstrap context - * as the root Application Context. - * - * @author Biju Kunjummen - */ -public class BootstrapListenerHierarchyIntegrationTests { - - @Test - public void shouldAddInABootstrapContext() { - ConfigurableApplicationContext context = new SpringApplicationBuilder() - .properties("spring.cloud.bootstrap.enabled=true").sources(BasicConfiguration.class).web(NONE).run(); - - then(context.getParent()).isNotNull(); - } - - @Test - public void shouldAddInOneBootstrapForABasicParentChildHierarchy() { - ConfigurableApplicationContext context = new SpringApplicationBuilder() - .properties("spring.cloud.bootstrap.enabled=true").sources(RootConfiguration.class).web(NONE) - .child(BasicConfiguration.class).web(NONE).run(); - - // Should be RootConfiguration based context - ConfigurableApplicationContext parent = (ConfigurableApplicationContext) context.getParent(); - then(parent.getBean("rootBean", String.class)).isEqualTo("rootBean"); - - // Parent should have the bootstrap context as parent - then(parent.getParent()).isNotNull(); - - ConfigurableApplicationContext bootstrapContext = (ConfigurableApplicationContext) parent.getParent(); - - // Bootstrap should be the root, there should be no other parent - then(bootstrapContext.getParent()).isNull(); - } - - @Test - public void shouldAddInOneBootstrapForSiblingsBasedHierarchy() { - ConfigurableApplicationContext context = new SpringApplicationBuilder() - .properties("spring.cloud.bootstrap.enabled=true").sources(RootConfiguration.class).web(NONE) - .child(BasicConfiguration.class).web(NONE).sibling(BasicConfiguration.class).web(NONE).run(); - - // Should be RootConfiguration based context - ConfigurableApplicationContext parent = (ConfigurableApplicationContext) context.getParent(); - then(parent.getBean("rootBean", String.class)).isEqualTo("rootBean"); - - // Parent should have the bootstrap context as parent - then(parent.getParent()).isNotNull(); - - ConfigurableApplicationContext bootstrapContext = (ConfigurableApplicationContext) parent.getParent(); - - // Bootstrap should be the root, there should be no other parent - then(bootstrapContext.getParent()).isNull(); - } - - @Configuration(proxyBeanMethods = false) - static class BasicConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - static class RootConfiguration { - - @Bean - public String rootBean() { - return "rootBean"; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java deleted file mode 100644 index c078fdd0..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.security.rsa.crypto.RsaAlgorithm; - -import static org.assertj.core.api.BDDAssertions.then; - -public class EncryptionBootstrapConfigurationTests { - - @Test - public void symmetric() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(EncryptionBootstrapConfiguration.class) - .web(WebApplicationType.NONE).properties("encrypt.key:pie").run(); - TextEncryptor encryptor = context.getBean(TextEncryptor.class); - then(encryptor.decrypt(encryptor.encrypt("foo"))).isEqualTo("foo"); - context.close(); - } - - @Test - public void rsaKeyStore() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(EncryptionBootstrapConfiguration.class) - .web(WebApplicationType.NONE) - .properties("encrypt.keyStore.location:classpath:/server.jks", "encrypt.keyStore.password:letmein", - "encrypt.keyStore.alias:mytestkey", "encrypt.keyStore.secret:changeme") - .run(); - TextEncryptor encryptor = context.getBean(TextEncryptor.class); - then(encryptor.decrypt(encryptor.encrypt("foo"))).isEqualTo("foo"); - context.close(); - } - - @Test - public void rsaPkcs12KeyStore() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(EncryptionBootstrapConfiguration.class) - .web(WebApplicationType.NONE) - .properties("encrypt.keyStore.location:classpath:/server.p12", "encrypt.keyStore.password:letmein", - "encrypt.keyStore.alias:mytestkey", "encrypt.keyStore.type:PKCS12") - .run(); - TextEncryptor encryptor = context.getBean(TextEncryptor.class); - then(encryptor.decrypt(encryptor.encrypt("foo"))).isEqualTo("foo"); - context.close(); - } - - @Test - public void rsaKeyStoreWithRelaxedProperties() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(EncryptionBootstrapConfiguration.class) - .web(WebApplicationType.NONE) - .properties("encrypt.key-store.location:classpath:/server.jks", "encrypt.key-store.password:letmein", - "encrypt.key-store.alias:mytestkey", "encrypt.key-store.secret:changeme") - .run(); - TextEncryptor encryptor = context.getBean(TextEncryptor.class); - then(encryptor.decrypt(encryptor.encrypt("foo"))).isEqualTo("foo"); - context.close(); - } - - @Test - public void rsaProperties() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(EncryptionBootstrapConfiguration.class) - .web(WebApplicationType.NONE) - .properties("encrypt.key-store.location:classpath:/server.jks", "encrypt.key-store.password:letmein", - "encrypt.key-store.alias:mytestkey", "encrypt.key-store.secret:changeme", - "encrypt.rsa.strong:true", "encrypt.rsa.salt:foobar") - .run(); - RsaProperties properties = context.getBean(RsaProperties.class); - then(properties.getSalt()).isEqualTo("foobar"); - then(properties.isStrong()).isTrue(); - then(properties.getAlgorithm()).isEqualTo(RsaAlgorithm.DEFAULT); - context.close(); - } - - @Test - public void nonExistentKeystoreLocationShouldNotBeAllowed() { - try { - new SpringApplicationBuilder(EncryptionBootstrapConfiguration.class).web(WebApplicationType.NONE) - .properties("encrypt.key-store.location:classpath:/server.jks1", - "encrypt.key-store.password:letmein", "encrypt.key-store.alias:mytestkey", - "encrypt.key-store.secret:changeme") - .run(); - then(false).as("Should not create an application context with invalid keystore location").isTrue(); - } - catch (Exception e) { - then(e).isInstanceOf(IllegalStateException.class); - } - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionIntegrationTests.java deleted file mode 100644 index fd3635b4..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionIntegrationTests.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.cloud.context.test.TestConfigDataLocationResolver; -import org.springframework.cloud.context.test.TestEnvPostProcessor; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.security.crypto.encrypt.TextEncryptor; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.assertj.core.api.BDDAssertions.then; - -public class EncryptionIntegrationTests { - - @Test - public void legacySymmetricPropertyValues() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfiguration.class) - .web(WebApplicationType.NONE).properties("spring.cloud.bootstrap.enabled=true", "encrypt.key:pie", - "foo.password:{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getEnvironment().getProperty("foo.password")).isEqualTo("test"); - } - - @Test - public void legacySymmetricConfigurationProperties() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfiguration.class) - .web(WebApplicationType.NONE).properties("spring.cloud.bootstrap.enabled=true", "encrypt.key:pie", - "foo.password:{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getBean(PasswordProperties.class).getPassword()).isEqualTo("test"); - } - - @Test - public void propSymmetricPropertyValues() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfiguration.class) - .web(WebApplicationType.NONE).properties("spring.cloud.bootstrap.enabled=true", "encrypt.key:pie", - "foo.password:{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getEnvironment().getProperty("foo.password")).isEqualTo("test"); - } - - @Test - public void propSymmetricConfigurationProperties() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfiguration.class) - .web(WebApplicationType.NONE).properties("spring.cloud.bootstrap.enabled=true", "encrypt.key:pie", - "foo.password:{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getBean(PasswordProperties.class).getPassword()).isEqualTo("test"); - } - - @Test - public void symmetricPropertyValuesFailOnError() { - assertThatThrownBy(() -> { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestAutoConfiguration.class) - .web(WebApplicationType.NONE) - .properties("spring.config.use-legacy-processing=false", "encrypt.key:pie", - "foo.password:{cipher}ZZZbf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - }).isInstanceOf(IllegalStateException.class).hasMessageContaining("Cannot decrypt"); - } - - @Test - public void symmetricPropertyValuesFailOnErrorFalse() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestAutoConfiguration.class) - .web(WebApplicationType.NONE) - .properties("encrypt.fail-on-error=false", "spring.config.use-legacy-processing=false", - "encrypt.key:pie", - "foo.password:{cipher}ZZZbf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getEnvironment().getProperty("foo.password")).isEmpty(); - } - - @Test - public void symmetricPropertyValues() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestAutoConfiguration.class) - .web(WebApplicationType.NONE).properties("spring.config.use-legacy-processing=false", "encrypt.key:pie", - "foo.password:{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getEnvironment().getProperty("foo.password")).isEqualTo("test"); - } - - @Test - public void decryptEnvironmentPostProcessorDisabled() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestAutoConfiguration.class) - .web(WebApplicationType.NONE) - .properties("spring.config.use-legacy-processing=false", "encrypt.key:pie", - "spring.cloud.decrypt-environment-post-processor.enabled=false", - "foo.password:{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getEnvironment().getProperty("foo.password")).startsWith("{cipher}bf2945"); - } - - @Test - public void symmetricConfigurationProperties() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestAutoConfiguration.class) - .web(WebApplicationType.NONE).properties("spring.config.use-legacy-processing=false", "encrypt.key:pie", - "foo.password:{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95") - .run(); - then(context.getBean(PasswordProperties.class).getPassword()).isEqualTo("test"); - } - - @Test - public void decryptAfterRefresh() { - TestConfigDataLocationResolver.config.put("foo.password", - "{cipher}bf29452295df354e6153c5b31b03ef23c70e55fba24299aa85c63438f1c43c95"); - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestAutoConfiguration.class) - .web(WebApplicationType.NONE).properties("encrypt.key:pie", TestEnvPostProcessor.EPP_ENABLED + "=true", - "spring.cloud.refresh.enabled:true") - .run(); - TextEncryptor encryptor = context.getBean(TextEncryptor.class); - ContextRefresher refresher = context.getBean(ContextRefresher.class); - ConfigurableEnvironment env = context.getBean(ConfigurableEnvironment.class); - then(env.getProperty("foo.password")).isEqualTo("test"); - TestConfigDataLocationResolver.config.put("foo.password", "{cipher}" + encryptor.encrypt("newValue")); - refresher.refresh(); - then(env.getProperty("foo.password")).isEqualTo("newValue"); - context.close(); - TestConfigDataLocationResolver.config.clear(); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(PasswordProperties.class) - protected static class TestConfiguration { - - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @EnableConfigurationProperties(PasswordProperties.class) - protected static class TestAutoConfiguration { - - } - - @ConfigurationProperties("foo") - protected static class PasswordProperties { - - private String password; - - public String getPassword() { - return this.password; - } - - public void setPassword(String password) { - this.password = password; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptorFactoryTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptorFactoryTests.java deleted file mode 100644 index e6ef9d39..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptorFactoryTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import java.nio.charset.StandardCharsets; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.context.encrypt.EncryptorFactory; -import org.springframework.core.io.ClassPathResource; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.util.StreamUtils; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Biju Kunjummen - */ -public class EncryptorFactoryTests { - - @Test - public void testWithRsaPrivateKey() throws Exception { - String key = StreamUtils.copyToString(new ClassPathResource("/example-test-rsa-private-key").getInputStream(), - StandardCharsets.US_ASCII); - - TextEncryptor encryptor = new EncryptorFactory().create(key); - String toEncrypt = "sample text to encrypt"; - String encrypted = encryptor.encrypt(toEncrypt); - - then(encryptor.decrypt(encrypted)).isEqualTo(toEncrypt); - } - - @Test - public void testWithInvalidRsaPrivateKey() { - String key = """ - -----BEGIN RSA PRIVATE KEY----- - MIIEowIBAAKCAQEAwClFgrRa/PUHPIJr9gvIPL6g6Rjp/TVZmVNOf2fL96DYbkj5 - """; - Assertions.assertThrows(RuntimeException.class, () -> new EncryptorFactory().create(key)); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java deleted file mode 100644 index b8a8f670..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializerTests.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.test.util.TestPropertyValues.Type; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.security.crypto.encrypt.Encryptors; -import org.springframework.security.crypto.encrypt.TextEncryptor; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.bootstrap.BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME; -import static org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME; -import static org.springframework.cloud.bootstrap.encrypt.EnvironmentDecryptApplicationInitializer.DECRYPTED_PROPERTY_SOURCE_NAME; - -/** - * @author Dave Syer - * @author Biju Kunjummen - * @author Tim Ysewyn - */ -@ExtendWith(OutputCaptureExtension.class) -public class EnvironmentDecryptApplicationInitializerTests { - - private EnvironmentDecryptApplicationInitializer listener = new EnvironmentDecryptApplicationInitializer( - Encryptors.noOpText()); - - @Test - public void decryptCipherKey() { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "foo: {cipher}bar").applyTo(context); - this.listener.initialize(context); - then(context.getEnvironment().getProperty("foo")).isEqualTo("bar"); - } - - @Test - public void relaxedBinding() { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "FOO_TEXT: {cipher}bar") - .applyTo(context.getEnvironment(), TestPropertyValues.Type.SYSTEM_ENVIRONMENT); - this.listener.initialize(context); - then(context.getEnvironment().getProperty("foo.text")).isEqualTo("bar"); - } - - @Test - public void propertySourcesOrderedCorrectly() { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "foo: {cipher}bar").applyTo(context); - context.getEnvironment().getPropertySources() - .addFirst(new MapPropertySource("test_override", Collections.singletonMap("foo", "{cipher}spam"))); - this.listener.initialize(context); - then(context.getEnvironment().getProperty("foo")).isEqualTo("spam"); - } - - @Test - public void errorOnDecrypt(CapturedOutput output) { - this.listener = new EnvironmentDecryptApplicationInitializer(Encryptors.text("deadbeef", "AFFE37")); - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "foo: {cipher}bar").applyTo(context); - // catch IllegalStateException and verify - try { - this.listener.initialize(context); - } - catch (Exception e) { - then(e).isInstanceOf(IllegalStateException.class); - } - // Assert logs contain warning even when exception thrown - String sysOutput = output.toString(); - then(sysOutput).contains("Cannot decrypt: key=foo"); - } - - @Test - public void errorOnDecryptWithEmpty(CapturedOutput output) { - this.listener = new EnvironmentDecryptApplicationInitializer(Encryptors.text("deadbeef", "AFFE37")); - this.listener.setFailOnError(false); - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "foo: {cipher}bar").applyTo(context); - this.listener.initialize(context); - // Assert logs contain warning - String sysOutput = output.toString(); - then(sysOutput).contains("Cannot decrypt: key=foo"); - // Empty is safest fallback for undecryptable cipher - then(context.getEnvironment().getProperty("foo")).isEqualTo(""); - } - - @Test - @SuppressWarnings("unchecked") - public void indexedPropertiesCopied() { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - // tests that collections in another property source don't get copied into - // "decrypted" property source - TestPropertyValues - .of("spring.cloud.bootstrap.enabled=true", "yours[0].someValue: yourFoo", "yours[1].someValue: yourBar") - .applyTo(context); - - // collection with some encrypted keys and some not encrypted - TestPropertyValues - .of("mine[0].someValue: Foo", "mine[0].someKey: {cipher}Foo0", "mine[1].someValue: Bar", - "mine[1].someKey: {cipher}Bar1", "nonindexed: nonindexval") - .applyTo(context.getEnvironment(), Type.MAP, "combinedTest"); - this.listener.initialize(context); - - then(context.getEnvironment().getProperty("mine[0].someValue")).isEqualTo("Foo"); - then(context.getEnvironment().getProperty("mine[0].someKey")).isEqualTo("Foo0"); - then(context.getEnvironment().getProperty("mine[1].someValue")).isEqualTo("Bar"); - then(context.getEnvironment().getProperty("mine[1].someKey")).isEqualTo("Bar1"); - then(context.getEnvironment().getProperty("yours[0].someValue")).isEqualTo("yourFoo"); - then(context.getEnvironment().getProperty("yours[1].someValue")).isEqualTo("yourBar"); - - MutablePropertySources propertySources = context.getEnvironment().getPropertySources(); - PropertySource> decrypted = (PropertySource>) propertySources - .get(DECRYPTED_PROPERTY_SOURCE_NAME); - then(decrypted.getSource().size()).as("decrypted property source had wrong size").isEqualTo(4); - } - - @Test - public void testDecryptNonStandardParent() { - ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(); - EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer( - Encryptors.noOpText()); - - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "key:{cipher}value").applyTo(ctx); - - ApplicationContext ctxParent = mock(ApplicationContext.class); - when(ctxParent.getEnvironment()).thenReturn(mock(Environment.class)); - - ctx.setParent(ctxParent); - - initializer.initialize(ctx); - - then(ctx.getEnvironment().getProperty("key")).isEqualTo("value"); - } - - @Test - public void testDecryptCompositePropertySource() { - ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true").applyTo(ctx); - EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer( - Encryptors.noOpText()); - - MapPropertySource devProfile = new MapPropertySource("dev-profile", - Collections.singletonMap("key", "{cipher}value1")); - - MapPropertySource defaultProfile = new MapPropertySource("default-profile", - Collections.singletonMap("key", "{cipher}value2")); - - CompositePropertySource cps = mock(CompositePropertySource.class); - when(cps.getName()).thenReturn("mock-composite-source"); - when(cps.getPropertyNames()).thenReturn(devProfile.getPropertyNames()); - when(cps.getPropertySources()).thenReturn(Arrays.asList(devProfile, defaultProfile)); - ctx.getEnvironment().getPropertySources().addLast(cps); - - initializer.initialize(ctx); - then(ctx.getEnvironment().getProperty("key")).isEqualTo("value1"); - } - - @Test - public void propertySourcesOrderedCorrectlyWithUnencryptedOverrides() { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "foo: {cipher}bar").applyTo(context); - context.getEnvironment().getPropertySources() - .addFirst(new MapPropertySource("test_override", Collections.singletonMap("foo", "spam"))); - this.listener.initialize(context); - then(context.getEnvironment().getProperty("foo")).isEqualTo("spam"); - } - - @Test - public void doNotDecryptBootstrapTwice() { - TextEncryptor encryptor = mock(TextEncryptor.class); - when(encryptor.decrypt("bar")).thenReturn("bar"); - when(encryptor.decrypt("bar2")).thenReturn("bar2"); - when(encryptor.decrypt("bar3")).thenReturn("bar3"); - when(encryptor.decrypt("baz")).thenReturn("baz"); - - EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer(encryptor); - - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true").applyTo(context); - CompositePropertySource bootstrap = new CompositePropertySource(BOOTSTRAP_PROPERTY_SOURCE_NAME); - bootstrap.addPropertySource( - new MapPropertySource("configService", Collections.singletonMap("foo", "{cipher}bar"))); - context.getEnvironment().getPropertySources().addFirst(bootstrap); - - Map props = new HashMap<>(); - props.put("foo2", "{cipher}bar2"); - props.put("bar", "{cipher}baz"); - context.getEnvironment().getPropertySources().addAfter(BOOTSTRAP_PROPERTY_SOURCE_NAME, - new MapPropertySource("remote", props)); - - initializer.initialize(context); - - // Simulate retrieval of new properties via Spring Cloud Config - props.put("foo2", "{cipher}bar3"); - context.getEnvironment().getPropertySources().replace("remote", new MapPropertySource("remote", props)); - - initializer.initialize(context); - - verify(encryptor).decrypt("bar"); - verify(encryptor).decrypt("bar2"); - verify(encryptor).decrypt("bar3"); - verify(encryptor, times(2)).decrypt("baz"); - - // Check if all encrypted properties are still decrypted - PropertySource decryptedBootstrap = context.getEnvironment().getPropertySources() - .get(DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME); - then(decryptedBootstrap.getProperty("foo")).isEqualTo("bar"); - - PropertySource decrypted = context.getEnvironment().getPropertySources().get(DECRYPTED_PROPERTY_SOURCE_NAME); - then(decrypted.getProperty("foo2")).isEqualTo("bar3"); - then(decrypted.getProperty("bar")).isEqualTo("baz"); - } - - @Test - public void testOnlyDecryptIfNotOverridden() { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - TextEncryptor encryptor = mock(TextEncryptor.class); - when(encryptor.decrypt("bar2")).thenReturn("bar2"); - EnvironmentDecryptApplicationInitializer initializer = new EnvironmentDecryptApplicationInitializer(encryptor); - TestPropertyValues.of("spring.cloud.bootstrap.enabled=true", "foo: {cipher}bar", "foo2: {cipher}bar2") - .applyTo(context); - context.getEnvironment().getPropertySources() - .addFirst(new MapPropertySource("test_override", Collections.singletonMap("foo", "spam"))); - initializer.initialize(context); - then(context.getEnvironment().getProperty("foo")).isEqualTo("spam"); - then(context.getEnvironment().getProperty("foo2")).isEqualTo("bar2"); - verify(encryptor).decrypt("bar2"); - verifyNoMoreInteractions(encryptor); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/RsaDisabledTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/RsaDisabledTests.java deleted file mode 100644 index 80056cf4..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/RsaDisabledTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.encrypt; - -import java.util.Map; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Ryan Baxter - */ -@ClassPathExclusions({ "spring-security-rsa*.jar" }) -public class RsaDisabledTests { - - private ConfigurableApplicationContext context; - - @BeforeEach - public void setUp() { - this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE) - .sources(EncryptionBootstrapConfiguration.class).web(WebApplicationType.NONE) - .properties("encrypt.key:mykey", "encrypt.rsa.strong:true", "encrypt.rsa.salt:foobar").run(); - } - - @AfterEach - public void tearDown() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void testLoadBalancedRetryFactoryBean() throws Exception { - Map properties = this.context.getBeansOfType(RsaProperties.class); - then(properties.values()).hasSize(0); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerIntegrationTests.java deleted file mode 100644 index 63d31f25..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerIntegrationTests.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.environment; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import jakarta.servlet.ServletException; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; -import org.springframework.boot.actuate.env.EnvironmentEndpoint; -import org.springframework.boot.actuate.env.EnvironmentEndpointWebExtension; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.context.environment.EnvironmentManagerIntegrationTests.TestConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.MediaType; -import org.springframework.test.web.servlet.MockMvc; - -import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@SpringBootTest(classes = TestConfiguration.class, - properties = { "management.endpoints.web.exposure.include=*", "management.endpoint.env.post.enabled=true" }) -@AutoConfigureMockMvc -public class EnvironmentManagerIntegrationTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - @Autowired - private TestProperties properties; - - @Autowired - private ObjectMapper mapper; - - @Autowired - private MockMvc mvc; - - @Autowired - private ApplicationContext context; - - @Test - public void testRefresh() throws Exception { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - String content = property("message", "Foo"); - - this.mvc.perform(post(BASE_PATH + "/env").content(content).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andExpect(content().string("{\"message\":\"Foo\"}")); - then(this.properties.getMessage()).isEqualTo("Foo"); - } - - private String property(String name, String value) throws JsonProcessingException { - // Change the dynamic property source... - Map property = new HashMap<>(); - property.put("name", name); - property.put("value", value); - - return this.mapper.writeValueAsString(property); - } - - @Test - public void testRefreshFails() throws Exception { - try { - this.mvc.perform( - post(BASE_PATH + "/env").content(property("delay", "foo")).contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()).andExpect(status().is5xxServerError()); - fail("expected ServletException"); - } - catch (ServletException e) { - // The underlying BindException is not handled by the dispatcher servlet - } - then(this.properties.getDelay()).isEqualTo(0); - } - - @Test - public void coreWebExtensionAvailable() throws Exception { - this.mvc.perform(get(BASE_PATH + "/env/" + UUID.randomUUID())).andExpect(status().isNotFound()); - } - - @Test - public void environmentBeansConfiguredCorrectly() { - Map envbeans = this.context.getBeansOfType(EnvironmentEndpoint.class); - then(envbeans).hasSize(1).containsKey("writableEnvironmentEndpoint"); - then(envbeans.get("writableEnvironmentEndpoint")).isInstanceOf(WritableEnvironmentEndpoint.class); - - Map extbeans = this.context - .getBeansOfType(EnvironmentEndpointWebExtension.class); - then(extbeans).hasSize(1).containsKey("writableEnvironmentEndpointWebExtension"); - then(extbeans.get("writableEnvironmentEndpointWebExtension")) - .isInstanceOf(WritableEnvironmentEndpointWebExtension.class); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class TestConfiguration { - - @Bean - protected TestProperties properties() { - return new TestProperties(); - } - - } - - @ConfigurationProperties - protected static class TestProperties { - - private String message; - - private int delay; - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerTest.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerTest.java deleted file mode 100644 index f826e9c6..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.environment; - -import org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; - -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.mock.env.MockEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -public class EnvironmentManagerTest { - - @Test - public void testCorrectEvents() { - MockEnvironment environment = new MockEnvironment(); - ApplicationEventPublisher publisher = mock(ApplicationEventPublisher.class); - EnvironmentManager environmentManager = new EnvironmentManager(environment); - environmentManager.setApplicationEventPublisher(publisher); - - environmentManager.setProperty("foo", "bar"); - - then(environment.getProperty("foo")).isEqualTo("bar"); - ArgumentCaptor eventCaptor = ArgumentCaptor.forClass(ApplicationEvent.class); - verify(publisher, times(1)).publishEvent(eventCaptor.capture()); - then(eventCaptor.getValue()).isInstanceOf(EnvironmentChangeEvent.class); - EnvironmentChangeEvent event = (EnvironmentChangeEvent) eventCaptor.getValue(); - then(event.getKeys()).containsExactly("foo"); - - reset(publisher); - - environmentManager.reset(); - then(environment.getProperty("foo")).isNull(); - verify(publisher, times(1)).publishEvent(eventCaptor.capture()); - then(eventCaptor.getValue()).isInstanceOf(EnvironmentChangeEvent.class); - event = (EnvironmentChangeEvent) eventCaptor.getValue(); - then(event.getKeys()).containsExactly("foo"); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/named/NamedContextFactoryTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/named/NamedContextFactoryTests.java deleted file mode 100644 index f9accd98..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/named/NamedContextFactoryTests.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.named; - -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.util.ClassUtils; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Spencer Gibb - * @author Tommy Karlsson - * @author Olga Maciaszek-Sharma - */ -public class NamedContextFactoryTests { - - @Test - public void testChildContexts() { - AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); - parent.register(BaseConfig.class); - parent.refresh(); - testChildContexts(parent); - } - - private void testChildContexts(GenericApplicationContext parent) { - TestClientFactory factory = new TestClientFactory(); - factory.setApplicationContext(parent); - factory.setConfigurations(Arrays.asList(getSpec("foo", FooConfig.class), getSpec("bar", BarConfig.class))); - - Foo foo = factory.getInstance("foo", Foo.class); - then(foo).as("foo was null").isNotNull(); - - Bar bar = factory.getInstance("bar", Bar.class); - then(bar).as("bar was null").isNotNull(); - - then(factory.getContextNames()).as("context names not exposed").contains("foo", "bar"); - - Bar foobar = factory.getInstance("foo", Bar.class); - then(foobar).as("bar was not null").isNull(); - - Baz fooBaz = factory.getInstance("foo", Baz.class); - then(fooBaz).as("fooBaz was null").isNotNull(); - - Object fooContainerFoo = factory.getInstance("foo", Container.class, Foo.class); - then(fooContainerFoo).as("fooContainerFoo was null").isNotNull(); - - Object fooContainerBar = factory.getInstance("foo", Container.class, Bar.class); - then(fooContainerBar).as("fooContainerBar was not null").isNull(); - - Object barContainerBar = factory.getInstance("bar", Container.class, Bar.class); - then(barContainerBar).as("barContainerBar was null").isNotNull(); - - Map fooBazes = factory.getInstances("foo", Baz.class); - then(fooBazes).as("fooBazes was null").isNotNull(); - then(fooBazes.size()).as("fooBazes size was wrong").isEqualTo(1); - - Map barBazes = factory.getInstances("bar", Baz.class); - then(barBazes).as("barBazes was null").isNotNull(); - then(barBazes.size()).as("barBazes size was wrong").isEqualTo(2); - - // get the contexts before destroy() to verify these are the old ones - GenericApplicationContext fooContext = factory.getContext("foo"); - GenericApplicationContext barContext = factory.getContext("bar"); - - then(fooContext.getClassLoader()).as("foo context classloader does not match parent") - .isSameAs(parent.getClassLoader()); - - then(fooContext.getBeanFactory().getBeanClassLoader()) - .as("foo context bean factory classloader does not match parent") - .isSameAs(parent.getBeanFactory().getBeanClassLoader()); - - Assertions.assertThat(fooContext).hasFieldOrPropertyWithValue("customClassLoader", true); - - factory.destroy(); - - then(fooContext.isActive()).as("foo context wasn't closed").isFalse(); - - then(barContext.isActive()).as("bar context wasn't closed").isFalse(); - } - - @Test - void testBadThreadContextClassLoader() throws InterruptedException, ExecutionException, TimeoutException { - AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext(); - parent.setClassLoader(ClassUtils.getDefaultClassLoader()); - parent.register(BaseConfig.class); - parent.refresh(); - - ExecutorService es = Executors.newSingleThreadExecutor(r -> { - Thread t = new Thread(r); - t.setContextClassLoader(new ThrowingClassLoader()); - return t; - }); - - es.submit(() -> this.testChildContexts(parent)).get(5, TimeUnit.SECONDS); - } - - private TestSpec getSpec(String name, Class configClass) { - return new TestSpec(name, new Class[] { configClass }); - } - - static class ThrowingClassLoader extends ClassLoader { - - ThrowingClassLoader() { - super(null); - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException { - throw new ClassNotFoundException(name); - } - - } - - static class TestClientFactory extends NamedContextFactory { - - TestClientFactory() { - super(TestSpec.class, "testfactory", "test.client.name"); - } - - } - - static class TestSpec implements NamedContextFactory.Specification { - - private String name; - - private Class[] configuration; - - TestSpec() { - } - - TestSpec(String name, Class[] configuration) { - this.name = name; - this.configuration = configuration; - } - - @Override - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public Class[] getConfiguration() { - return this.configuration; - } - - public void setConfiguration(Class[] configuration) { - this.configuration = configuration; - } - - } - - static class BaseConfig { - - @Bean - Baz baz1() { - return new Baz(); - } - - } - - static class Baz { - - } - - @ConditionalOnClass(Object.class) - static class FooConfig { - - @Bean - Foo foo() { - return new Foo(); - } - - @Bean - Container fooContainer() { - return new Container<>(new Foo()); - } - - } - - static class Foo { - - } - - static class BarConfig { - - @Bean - Bar bar() { - return new Bar(); - } - - @Bean - Baz baz2() { - return new Baz(); - } - - @Bean - Container barContainer() { - return new Container<>(new Bar()); - } - - } - - static class Bar { - - } - - static class Container { - - private final T item; - - Container(T item) { - this.item = item; - } - - public T getItem() { - return this.item; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderIntegrationTests.java deleted file mode 100644 index a5dd76f6..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderIntegrationTests.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.properties; - -import org.aopalliance.intercept.MethodInterceptor; -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ActiveProfiles; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class, properties = "spring.cloud.bootstrap.enabled=true") -@ActiveProfiles("config") -public class ConfigurationPropertiesRebinderIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private ConfigProperties config; - - @Autowired - private ConfigurationPropertiesRebinder rebinder; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @DirtiesContext - public void testSimpleProperties() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - then(this.properties.getCount()).isEqualTo(1); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment); - // ...but don't refresh, so the bean stays the same: - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - then(this.properties.getCount()).isEqualTo(1); - } - - @Test - @DirtiesContext - public void testRefreshInParent() { - then(this.config.getName()).isEqualTo("parent"); - // Change the dynamic property source... - TestPropertyValues.of("config.name=foo").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.rebinder.rebind(); - then(this.config.getName()).isEqualTo("parent"); - } - - @Test - @DirtiesContext - public void testRefresh() { - then(this.properties.getCount()).isEqualTo(1); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.rebinder.rebind(); - then(this.properties.getMessage()).isEqualTo("Foo"); - then(this.properties.getCount()).isEqualTo(2); - } - - @Test - @DirtiesContext - public void testRefreshByName() { - then(this.properties.getCount()).isEqualTo(1); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.rebinder.rebind("properties"); - then(this.properties.getMessage()).isEqualTo("Foo"); - then(this.properties.getCount()).isEqualTo(2); - } - - interface SomeService { - - void foo(); - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - @ImportAutoConfiguration({ RefreshConfiguration.RebinderConfiguration.class, - PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - protected TestProperties properties() { - return new TestProperties(); - } - - // exposes https://github.com/spring-cloud/spring-cloud-commons/issues/337 - @Bean - @ConfigurationProperties("some.service") - public SomeService someService() { - return ProxyFactory.getProxy(SomeService.class, (MethodInterceptor) methodInvocation -> null); - } - - } - - // Hack out a protected inner class for testing - protected static class RefreshConfiguration extends RefreshAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - protected static class RebinderConfiguration extends ConfigurationPropertiesRebinderAutoConfiguration { - - } - - } - - @ConfigurationProperties - protected static class TestProperties implements InitializingBean { - - private String message; - - private int delay; - - private int count = 0; - - public int getCount() { - return this.count; - } - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() { - this.count++; - } - - } - - @Configuration - public static class ConfigPropertiesConfig { - - @Bean - @ConditionalOnMissingBean(ConfigProperties.class) - public ConfigProperties configProperties() { - return new ConfigProperties(); - } - - } - - @ConfigurationProperties("config") - public static class ConfigProperties { - - private String name; - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderLifecycleIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderLifecycleIntegrationTests.java deleted file mode 100644 index d50ec101..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderLifecycleIntegrationTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.properties; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderLifecycleIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -public class ConfigurationPropertiesRebinderLifecycleIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private ConfigurationPropertiesRebinder rebinder; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @DirtiesContext - public void testRefresh() { - then(this.properties.getCount()).isEqualTo(0); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.rebinder.rebind(); - then(this.properties.getMessage()).isEqualTo("Foo"); - then(this.properties.getCount()).isEqualTo(1); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - @Import({ RefreshConfiguration.RebinderConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - protected TestProperties properties() { - return new TestProperties(); - } - - } - - // Hack out a protected inner class for testing - protected static class RefreshConfiguration extends RefreshAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - protected static class RebinderConfiguration extends ConfigurationPropertiesRebinderAutoConfiguration { - - } - - } - - @ConfigurationProperties - protected static class TestProperties implements DisposableBean, InitializingBean { - - private String message; - - private int count = 0; - - public int getCount() { - return this.count; - } - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - @Override - public void afterPropertiesSet() throws Exception { - then(this.message).isNotEmpty(); - } - - @Override - public void destroy() throws Exception { - this.message = ""; - this.count++; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderListIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderListIntegrationTests.java deleted file mode 100644 index 676f2426..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderListIntegrationTests.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.properties; - -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderListIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.PropertySource; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class, properties = "messages=one,two") -public class ConfigurationPropertiesRebinderListIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private ConfigurationPropertiesRebinder rebinder; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @DirtiesContext - public void testAppendProperties() { - then(this.properties.getMessages()).containsOnly("one", "two"); - TestPropertyValues.of("messages[0]:foo").applyTo(this.environment); - this.rebinder.rebind(); - then(this.properties.getMessages()).containsOnly("foo"); - } - - @Test - @DirtiesContext - @Disabled("Can't rebind to list and re-initialize it (need refresh scope for this to work)") - public void testReplaceProperties() { - then(this.properties.getMessages()).containsOnly("one", "two"); - Map map = findTestProperties(); - map.clear(); - TestPropertyValues.of("messages[0]:foo").applyTo(this.environment); - this.rebinder.rebind(); - then(this.properties.getMessages()).containsOnly("foo"); - } - - private Map findTestProperties() { - for (PropertySource source : this.environment.getPropertySources()) { - if (source.getName().toLowerCase().contains("test")) { - @SuppressWarnings("unchecked") - Map map = (Map) source.getSource(); - return map; - } - } - throw new IllegalStateException("Could not find test property source"); - } - - @Test - @DirtiesContext - public void testReplacePropertiesWithCommaSeparated() { - then(this.properties.getMessages()).containsOnly("one", "two"); - Map map = findTestProperties(); - map.clear(); - TestPropertyValues.of("messages:foo").applyTo(this.environment); - this.rebinder.rebind(); - then(this.properties.getMessages()).containsOnly("foo"); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - @Import({ RefreshConfiguration.RebinderConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - protected TestProperties localTestProperties() { - return new TestProperties(); - } - - } - - // Hack out a protected inner class for testing - protected static class RefreshConfiguration extends RefreshAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - protected static class RebinderConfiguration extends ConfigurationPropertiesRebinderAutoConfiguration { - - } - - } - - @ConfigurationProperties - protected static class TestProperties implements InitializingBean { - - private List messages; - - private int count; - - public List getMessages() { - return this.messages; - } - - public void setMessages(List messages) { - this.messages = messages; - } - - public int getCount() { - return this.count; - } - - @Override - public void afterPropertiesSet() { - this.count++; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderProxyIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderProxyIntegrationTests.java deleted file mode 100644 index 70f01c85..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderProxyIntegrationTests.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.properties; - -import java.util.HashMap; -import java.util.Map; - -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Before; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderProxyIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class, properties = { "messages.expiry.one=168", "messages.expiry.two=76" }) -public class ConfigurationPropertiesRebinderProxyIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private ConfigurationPropertiesRebinder rebinder; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @DirtiesContext - public void testAppendProperties() { - // This comes out as a String not Integer if the rebinder processes the proxy - // instead of the target - then(this.properties.getExpiry().get("one")).isEqualTo(new Integer(168)); - TestPropertyValues.of("messages.expiry.one=56").applyTo(this.environment); - this.rebinder.rebind(); - then(this.properties.getExpiry().get("one")).isEqualTo(new Integer(56)); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - @Import({ Interceptor.class, RefreshConfiguration.RebinderConfiguration.class, - PropertyPlaceholderAutoConfiguration.class, AopAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - protected TestProperties properties() { - return new TestProperties(); - } - - } - - @Aspect - protected static class Interceptor { - - @Before("execution(* *..TestProperties.*(..))") - public void before() { - System.err.println("Before"); - } - - } - - // Hack out a protected inner class for testing - protected static class RefreshConfiguration extends RefreshAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - protected static class RebinderConfiguration extends ConfigurationPropertiesRebinderAutoConfiguration { - - } - - } - - @ConfigurationProperties("messages") - protected static class TestProperties { - - private final Map expiry = new HashMap<>(); - - private String name; - - public Map getExpiry() { - return this.expiry; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderRefreshScopeIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderRefreshScopeIntegrationTests.java deleted file mode 100644 index 598d97df..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderRefreshScopeIntegrationTests.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.properties; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderRefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class, properties = "spring.cloud.bootstrap.enabled=true") -public class ConfigurationPropertiesRebinderRefreshScopeIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private ConfigurationPropertiesRebinder rebinder; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope refreshScope; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @DirtiesContext - public void testSimpleProperties() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment); - // ...but don't refresh, so the bean stays the same: - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - then(this.properties.getCount()).isEqualTo(1); - } - - @Test - @DirtiesContext - public void testRefresh() { - then(this.properties.getCount()).isEqualTo(1); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - then(this.properties.getCount()).isEqualTo(1); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment); - // ...rebind, but the bean is not re-initialized: - this.rebinder.rebind(); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - then(this.properties.getCount()).isEqualTo(1); - // ...and then refresh, so the bean is re-initialized: - this.refreshScope.refreshAll(); - then(this.properties.getMessage()).isEqualTo("Foo"); - // It's a new instance so the initialization count is 1 - then(this.properties.getCount()).isEqualTo(1); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - @Import({ RefreshAutoConfiguration.class, ConfigurationPropertiesRebinderAutoConfiguration.class, - PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - @RefreshScope - protected TestProperties properties() { - return new TestProperties(); - } - - } - - @ConfigurationProperties - protected static class TestProperties implements InitializingBean { - - private String message; - - private int delay; - - private int count = 0; - - public int getCount() { - return this.count; - } - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() { - this.count++; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java deleted file mode 100644 index 75582bf2..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ConfigDataContextRefresherIntegrationTests.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.refresh; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.ConfigurableBootstrapContext; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.context.test.TestConfigDataLocationResolver; -import org.springframework.cloud.context.test.TestEnvPostProcessor; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; - -public class ConfigDataContextRefresherIntegrationTests { - - private TestProperties properties; - - private ConfigurableEnvironment environment; - - private ContextRefresher refresher; - - private ConfigurableApplicationContext context; - - @BeforeEach - public void setup() { - TestConfigDataLocationResolver.instance = new MyTestBean(); - System.setProperty("VCAP_SERVICES", - "{\"user-provided\":[{\"label\": \"user-provided\",\"name\": \"myvcap\",\"myvar\": \"myval\"}]}"); - context = new SpringApplication(TestConfiguration.class).run("--spring.datasource.hikari.read-only=false", - "--spring.profiles.active=configdatarefresh", "--" + TestEnvPostProcessor.EPP_ENABLED + "=true", - "--server.port=0"); - properties = context.getBean(TestProperties.class); - environment = context.getBean(ConfigurableEnvironment.class); - refresher = context.getBean(ContextRefresher.class); - } - - @AfterEach - public void after() { - System.clearProperty("VCAP_SERVICES"); - if (context != null) { - context.close(); - } - TestConfigDataLocationResolver.count.set(1); - TestConfigDataLocationResolver.instance = null; - } - - @Test - public void testSimpleProperties() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...but don't refresh, so the bean stays the same: - then(this.properties.getMessage()).isEqualTo("Foo"); - } - - @Test - public void testAdditionalPropertySourcesToRetain() { - then(environment.getProperty(TestEnvPostProcessor.EPP_VALUE)).isEqualTo("1"); - // ...and then refresh, to see if property source is retained during refresh - // that means an updated test datasource with EPP_VALUE set to 10 - TestConfigDataLocationResolver.count.set(10); - this.refresher.refresh(); - then(environment.getProperty(TestEnvPostProcessor.EPP_VALUE)).isEqualTo("10"); - } - - @Test - public void testRefreshBean() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.refresher.refresh(); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - } - - @Test - public void testVcapPlaceholderAfterRefresh() { - // an error will be thrown if count is 99 and myplaceholder contains ${vcap - TestConfigDataLocationResolver.count.set(99); - this.refresher.refresh(); - } - - @Test - public void testUpdateHikari() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - TestPropertyValues.of("spring.datasource.hikari.read-only=true").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.refresher.refresh(); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - } - - @Test - public void testCachedRandom() { - long cachedRandomLong = properties.getCachedRandomLong(); - long randomLong = properties.randomLong(); - then(cachedRandomLong).isNotNull(); - this.refresher.refresh(); - then(randomLong).isNotEqualTo(properties.randomLong()); - then(cachedRandomLong).isEqualTo(properties.cachedRandomLong); - } - - @Test - public void contextContainsBootstrapContext() { - ConfigurableBootstrapContext bootstrapContext = context.getBean(ConfigurableBootstrapContext.class); - then(bootstrapContext).isNotNull(); - then(bootstrapContext.isRegistered(MyTestBean.class)).isTrue(); - } - - protected static class MyTestBean { - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TestProperties.class) - @EnableAutoConfiguration - protected static class TestConfiguration { - - } - - @ConfigurationProperties - protected static class TestProperties { - - private String message; - - private int delay; - - private Long cachedRandomLong; - - private Long randomLong; - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - public Long getCachedRandomLong() { - return this.cachedRandomLong; - } - - public void setCachedRandomLong(Long cachedRandomLong) { - this.cachedRandomLong = cachedRandomLong; - } - - public long randomLong() { - return randomLong; - } - - public void setRandomLong(long randomLong) { - this.randomLong = randomLong; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherIntegrationTests.java deleted file mode 100644 index a77b0357..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherIntegrationTests.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.refresh; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.context.refresh.ContextRefresherIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class, - properties = { "spring.datasource.hikari.read-only=false", "spring.cloud.bootstrap.enabled=true" }) -public class ContextRefresherIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private ConfigurableEnvironment environment; - - @Autowired - private ContextRefresher refresher; - - @Test - @DirtiesContext - public void testSimpleProperties() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...but don't refresh, so the bean stays the same: - then(this.properties.getMessage()).isEqualTo("Foo"); - } - - @Test - @DirtiesContext - public void testRefreshBean() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.refresher.refresh(); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - } - - @Test - @DirtiesContext - public void testUpdateHikari() { - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - TestPropertyValues.of("spring.datasource.hikari.read-only=true").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.refresher.refresh(); - then(this.properties.getMessage()).isEqualTo("Hello scope!"); - } - - @Test - @DirtiesContext - public void testCachedRandom() { - long cachedRandomLong = properties.getCachedRandomLong(); - long randomLong = properties.randomLong(); - then(cachedRandomLong).isNotNull(); - this.refresher.refresh(); - then(randomLong).isNotEqualTo(properties.randomLong()); - then(cachedRandomLong).isEqualTo(properties.cachedRandomLong); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TestProperties.class) - @EnableAutoConfiguration - protected static class TestConfiguration { - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - private Long cachedRandomLong; - - private Long randomLong; - - @ManagedAttribute - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - public long getCachedRandomLong() { - return cachedRandomLong; - } - - public void setCachedRandomLong(long cachedRandomLong) { - this.cachedRandomLong = cachedRandomLong; - } - - public long randomLong() { - return randomLong; - } - - public void setRandomLong(long randomLong) { - this.randomLong = randomLong; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherOrderingIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherOrderingIntegrationTests.java deleted file mode 100644 index 41b741c3..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherOrderingIntegrationTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.refresh; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -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.bootstrap.config.PropertySourceLocator; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.test.annotation.DirtiesContext; - -import static java.util.Collections.singletonMap; -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest(properties = "spring.cloud.bootstrap.enabled=true") -@DirtiesContext -public class ContextRefresherOrderingIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @Autowired - private ContextRefresher refresher; - - private static String original; - - @BeforeAll - public static void beforeClass() { - original = System.getProperty("spring.cloud.bootstrap.sources"); - System.setProperty("spring.cloud.bootstrap.sources", - "org.springframework.cloud.context.refresh.ContextRefresherOrderingIntegrationTests.PropertySourceConfiguration"); - } - - @AfterAll - public static void afterClass() { - if (original != null) { - System.setProperty("spring.cloud.bootstrap.sources", original); - } - else { - System.clearProperty("spring.cloud.bootstrap.sources"); - } - } - - @Test - public void orderingIsCorrect() { - refresher.refresh(); - MutablePropertySources propertySources = environment.getPropertySources(); - PropertySource test1 = propertySources.get("bootstrapProperties-testContextRefresherOrdering1"); - PropertySource test2 = propertySources.get("bootstrapProperties-testContextRefresherOrdering2"); - PropertySource test3 = propertySources.get("bootstrapProperties-testContextRefresherOrdering3"); - int index1 = propertySources.precedenceOf(test1); - int index2 = propertySources.precedenceOf(test2); - int index3 = propertySources.precedenceOf(test3); - assertThat(index1).as("source1 index not less then source2").isLessThan(index2); - assertThat(index2).as("source2 index not less then source3").isLessThan(index3); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - protected static class Application { - - } - - @Configuration(proxyBeanMethods = false) - // This is added to bootstrap context as a source in - // contextrefresherordering.properties - protected static class PropertySourceConfiguration implements PropertySourceLocator { - - private static AtomicBoolean first = new AtomicBoolean(true); - - @Override - public PropertySource locate(Environment environment) { - throw new UnsupportedOperationException(); - } - - @Override - public Collection> locateCollection(Environment environment) { - if (first.compareAndSet(true, false)) { - return Collections.emptyList(); - } - ArrayList> sources = new ArrayList<>(); - sources.add(new MapPropertySource("testContextRefresherOrdering1", singletonMap("key1", "value1"))); - sources.add(new MapPropertySource("testContextRefresherOrdering2", singletonMap("key2", "value2"))); - sources.add(new MapPropertySource("testContextRefresherOrdering3", singletonMap("key3", "value3"))); - return sources; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java deleted file mode 100644 index 03721db0..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/refresh/ContextRefresherTests.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.refresh; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.test.util.TestPropertyValues.Type; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.bootstrap.TestBootstrapConfiguration; -import org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration; -import org.springframework.cloud.bootstrap.config.PropertySourceLocator; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.BDDAssertions.then; - -public class ContextRefresherTests { - - private RefreshScope scope = Mockito.mock(RefreshScope.class); - - @AfterEach - public void close() { - System.clearProperty(LoggingSystem.SYSTEM_PROPERTY); - TestLoggingSystem.count = 0; - } - - @Test - @Disabled // FIXME: legacy config - public void orderNewPropertiesConsistentWithNewContext() { - try (ConfigurableApplicationContext context = SpringApplication.run(Empty.class, - "--spring.cloud.bootstrap.enabled=true", "--spring.main.web-application-type=none", "--debug=false", - "--spring.main.bannerMode=OFF")) { - context.getEnvironment().setActiveProfiles("refresh"); - List names = names(context.getEnvironment().getPropertySources()); - then(names).doesNotContain("applicationConfig: [classpath:/bootstrap-refresh.properties]"); - LegacyContextRefresher refresher = new LegacyContextRefresher(context, this.scope); - refresher.refresh(); - names = names(context.getEnvironment().getPropertySources()); - then(names).contains("applicationConfig: [classpath:/bootstrap-refresh.properties]"); - then(names).containsSequence("applicationConfig: [classpath:/application.properties]", - "applicationConfig: [classpath:/bootstrap-refresh.properties]", - "applicationConfig: [classpath:/bootstrap.properties]"); - } - } - - @Test - public void bootstrapPropertySourceAlwaysFirst() { - // Use spring.cloud.bootstrap.name to switch off the defaults (which would pick up - // a bootstrapProperties immediately - try (ConfigurableApplicationContext context = SpringApplication.run(Empty.class, - "--spring.cloud.bootstrap.enabled=true", "--spring.main.web-application-type=none", "--debug=false", - "--spring.main.bannerMode=OFF", "--spring.cloud.bootstrap.name=refresh")) { - List names = names(context.getEnvironment().getPropertySources()); - System.err.println("***** " + context.getEnvironment().getPropertySources()); - then(names).doesNotContain("bootstrapProperties"); - ContextRefresher refresher = new LegacyContextRefresher(context, this.scope); - TestPropertyValues.of("spring.cloud.bootstrap.sources: " - + "org.springframework.cloud.context.refresh.ContextRefresherTests.PropertySourceConfiguration") - .applyTo(context.getEnvironment(), Type.MAP, "defaultProperties"); - refresher.refresh(); - names = names(context.getEnvironment().getPropertySources()); - then(names).first() - .isEqualTo(PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME + "-refreshTest"); - } - } - - @Test - public void parentContextIsClosed() { - // Use spring.cloud.bootstrap.name to switch off the defaults (which would pick up - // a bootstrapProperties immediately - try (ConfigurableApplicationContext context = SpringApplication.run(ContextRefresherTests.class, - "--spring.main.web-application-type=none", "--spring.cloud.bootstrap.enabled=true", "--debug=false", - "--spring.main.bannerMode=OFF", "--spring.cloud.bootstrap.name=refresh")) { - LegacyContextRefresher refresher = new LegacyContextRefresher(context, this.scope); - TestPropertyValues.of("spring.cloud.bootstrap.sources: " - + "org.springframework.cloud.context.refresh.ContextRefresherTests.PropertySourceConfiguration") - .applyTo(context); - - ConfigurableApplicationContext refresherContext = refresher.addConfigFilesToEnvironment(); - then(refresherContext.getParent()).isNotNull().isInstanceOf(ConfigurableApplicationContext.class); - ConfigurableApplicationContext parent = (ConfigurableApplicationContext) refresherContext.getParent(); - then(parent.isActive()).isFalse(); - } - } - - @Test - public void loggingSystemNotInitialized() { - System.setProperty(LoggingSystem.SYSTEM_PROPERTY, TestLoggingSystem.class.getName()); - TestLoggingSystem system = (TestLoggingSystem) LoggingSystem.get(getClass().getClassLoader()); - then(system.getCount()).isEqualTo(0); - try (ConfigurableApplicationContext context = SpringApplication.run(Empty.class, - "--spring.cloud.bootstrap.enabled=true", "--spring.main.web-application-type=none", "--debug=false", - "--spring.main.bannerMode=OFF", "--spring.cloud.bootstrap.name=refresh")) { - then(system.getCount()).isEqualTo(4); - ContextRefresher refresher = new LegacyContextRefresher(context, this.scope); - refresher.refresh(); - then(system.getCount()).isEqualTo(4); - } - } - - @Test - public void commandLineArgsPassedToBootstrapConfiguration() { - - TestBootstrapConfiguration.fooSightings = new ArrayList<>(); - - try (ConfigurableApplicationContext context = SpringApplication.run(ContextRefresherTests.class, - "--spring.main.web-application-type=none", "--spring.cloud.bootstrap.enabled=true", "--debug=false", - "--spring.main.bannerMode=OFF", "--spring.cloud.bootstrap.name=refresh", "--test.bootstrap.foo=bar")) { - context.getEnvironment().setActiveProfiles("refresh"); - ContextRefresher refresher = new LegacyContextRefresher(context, this.scope); - refresher.refresh(); - then(TestBootstrapConfiguration.fooSightings).containsExactly("bar", "bar"); - } - - TestBootstrapConfiguration.fooSightings = null; - } - - @Test - public void legacyContextRefresherCreatedUsingBootstrapEnabled() { - new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(RefreshAutoConfiguration.class)) - .withPropertyValues("spring.cloud.bootstrap.enabled=true").run(context -> { - assertThat(context).hasSingleBean(LegacyContextRefresher.class); - assertThat(context).hasSingleBean(ContextRefresher.class); - }); - } - - @Test - public void legacyContextRefresherCreated() { - new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(RefreshAutoConfiguration.class)) - .withPropertyValues("spring.cloud.bootstrap.enabled=true").run(context -> { - assertThat(context).hasSingleBean(LegacyContextRefresher.class); - assertThat(context).hasSingleBean(ContextRefresher.class); - }); - } - - @Test - public void configDataContextRefresherCreated() { - new ApplicationContextRunner().withConfiguration(AutoConfigurations.of(RefreshAutoConfiguration.class)) - .run(context -> { - assertThat(context).hasSingleBean(ConfigDataContextRefresher.class); - assertThat(context).hasSingleBean(ContextRefresher.class); - }); - } - - private List names(MutablePropertySources propertySources) { - List list = new ArrayList<>(); - for (PropertySource p : propertySources) { - list.add(p.getName()); - } - return list; - } - - @Configuration(proxyBeanMethods = false) - protected static class Empty { - - } - - @Configuration(proxyBeanMethods = false) - // This is added to bootstrap context as a source in bootstrap.properties - protected static class PropertySourceConfiguration implements PropertySourceLocator { - - public static Map MAP = new HashMap<>( - Collections.singletonMap("bootstrap.foo", "refresh")); - - @Override - public PropertySource locate(Environment environment) { - return new MapPropertySource("refreshTest", MAP); - } - - } - - public static class TestLoggingSystem extends LoggingSystem { - - private static int count; - - public TestLoggingSystem(ClassLoader loader) { - } - - public int getCount() { - return count; - } - - @Override - public void beforeInitialize() { - count++; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java deleted file mode 100644 index 34d943df..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.restart; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -public class RestartIntegrationTests { - - private ConfigurableApplicationContext context; - - @AfterEach - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - public void testRestartTwice() { - - this.context = SpringApplication.run(TestConfiguration.class, "--management.endpoint.restart.enabled=true", - "--server.port=0", "--spring.cloud.bootstrap.enabled=true", - "--management.endpoints.web.exposure.include=restart", "--spring.liveBeansView.mbeanDomain=livebeans"); - - RestartEndpoint endpoint = this.context.getBean(RestartEndpoint.class); - then(this.context.getParent()).isNotNull(); - then(this.context.getParent().getParent()).isNull(); - this.context = endpoint.doRestart(); - - then(this.context).isNotNull(); - then(this.context.getParent()).isNotNull(); - then(this.context.getParent().getParent()).isNull(); - - RestartEndpoint next = this.context.getBean(RestartEndpoint.class); - then(next).isSameAs(endpoint); - this.context = next.doRestart(); - - then(this.context).isNotNull(); - then(this.context.getParent()).isNotNull(); - then(this.context.getParent().getParent()).isNull(); - - // FIXME: 4.0.0 missing LiveBeansView - /* - * LiveBeansView beans = new LiveBeansView(); String json = - * beans.getSnapshotAsJson(); - * then(json).containsOnlyOnce("parent\": \"bootstrap"); - * then(json).containsOnlyOnce("parent\": null"); - */ - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/ImportRefreshScopeIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/ImportRefreshScopeIntegrationTests.java deleted file mode 100644 index 4798aa5a..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/ImportRefreshScopeIntegrationTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.ImportRefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -public class ImportRefreshScopeIntegrationTests { - - @Autowired - org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Autowired - private ConfigurableListableBeanFactory beanFactory; - - @Autowired - private ExampleService service; - - @Test - public void testSimpleProperties() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(this.beanFactory.getBeanDefinition(ScopedProxyUtils.getTargetBeanName("service")).getScope()) - .isEqualTo("refresh"); - then(this.service.getMessage()).isEqualTo("Hello scope!"); - } - - @Configuration(value = "service", proxyBeanMethods = false) - @RefreshScope - public static class ExampleService { - - public String getMessage() { - return "Hello scope!"; - } - - } - - @Configuration(proxyBeanMethods = false) - @Import({ RefreshAutoConfiguration.class, ExampleService.class }) - protected static class TestConfiguration { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/MoreRefreshScopeIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/MoreRefreshScopeIntegrationTests.java deleted file mode 100644 index ce9a757e..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/MoreRefreshScopeIntegrationTests.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.Advised; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.test.util.TestPropertyValues.Type; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.MoreRefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.Assertions.fail; -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -public class MoreRefreshScopeIntegrationTests { - - @Autowired - private TestService service; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Autowired - private ConfigurableEnvironment environment; - - @BeforeEach - public void init() { - then(TestService.getInitCount()).isEqualTo(1); - TestService.reset(); - } - - @AfterEach - public void close() { - TestService.reset(); - } - - @Test - @DirtiesContext - public void testSimpleProperties() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(this.service instanceof Advised).isTrue(); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment); - // ...but don't refresh, so the bean stays the same: - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(TestService.getInitCount()).isEqualTo(0); - then(TestService.getDestroyCount()).isEqualTo(0); - } - - @Test - @DirtiesContext - public void testRefresh() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - String id1 = this.service.toString(); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo").applyTo(this.environment, Type.MAP, "morerefreshtests"); - // ...and then refresh, so the bean is re-initialized: - this.scope.refreshAll(); - String id2 = this.service.toString(); - String message = this.service.getMessage(); - then(message).isEqualTo("Foo"); - then(TestService.getInitCount()).isEqualTo(1); - then(TestService.getDestroyCount()).isEqualTo(1); - then(id2).isNotSameAs(id1); - } - - @Test - @DirtiesContext - public void testRefreshFails() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - // Change the dynamic property source... - TestPropertyValues.of("message:Foo", "delay:foo").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.scope.refreshAll(); - try { - // If a refresh fails (e.g. a binding error in this case) the application is - // basically hosed. - then(this.service.getMessage()).isEqualTo("Hello scope!"); - fail("expected BeanCreationException"); - } - catch (BeanCreationException e) { - } - // But we can fix it by fixing the binding error: - TestPropertyValues.of("delay:0").applyTo(this.environment); - // ...and then refresh, so the bean is re-initialized: - this.scope.refreshAll(); - then(this.service.getMessage()).isEqualTo("Foo"); - } - - public static class TestService implements InitializingBean, DisposableBean { - - private static Log logger = LogFactory.getLog(TestService.class); - - private volatile static int initCount = 0; - - private volatile static int destroyCount = 0; - - private String message = null; - - private volatile long delay = 0; - - public static void reset() { - initCount = 0; - destroyCount = 0; - } - - public static int getInitCount() { - return initCount; - } - - public static int getDestroyCount() { - return destroyCount; - } - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing message: " + this.message); - initCount++; - } - - @Override - public void destroy() throws Exception { - logger.debug("Destroying message: " + this.message); - destroyCount++; - this.message = null; - } - - public String getMessage() { - logger.debug("Getting message: " + this.message); - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + message); - this.message = message; - } - - } - - @Configuration - @EnableConfigurationProperties - @EnableAutoConfiguration - protected static class TestConfiguration { - - @Bean - @RefreshScope - protected TestProperties properties() { - return new TestProperties(); - } - - @Bean - @RefreshScope - public TestService service() { - TestService service = new TestService(); - service.setMessage(properties().getMessage()); - service.setDelay(properties().getDelay()); - return service; - } - - } - - @ConfigurationProperties - // @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - // @ManagedAttribute - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - // @ManagedAttribute - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshEndpointIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshEndpointIntegrationTests.java deleted file mode 100644 index 4a699bc8..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshEndpointIntegrationTests.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Value; -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.test.web.server.LocalServerPort; -import org.springframework.cloud.context.scope.refresh.RefreshEndpointIntegrationTests.ClientApp; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -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.RequestEntity; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.BDDAssertions.then; -import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; - -/** - * @author Dave Syer - * - */ - -@SpringBootTest(classes = ClientApp.class, - properties = { "management.endpoints.web.exposure.include=*", "management.endpoint.env.post.enabled=true" }, - webEnvironment = RANDOM_PORT) -public class RefreshEndpointIntegrationTests { - - private static final String BASE_PATH = new WebEndpointProperties().getBasePath(); - - @LocalServerPort - private int port; - - @Test - public void webAccess() throws Exception { - TestRestTemplate template = new TestRestTemplate(); - ResponseEntity envResponse = template.exchange( - getUrlEncodedEntity("http://localhost:" + this.port + BASE_PATH + "/env", "message", "Hello Dave!"), - String.class); - assertThat(envResponse.getStatusCode()).isEqualTo(HttpStatus.OK); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity request = new HttpEntity(headers); - ResponseEntity refreshResponse = template - .postForEntity("http://localhost:" + this.port + BASE_PATH + "/refresh", request, String.class); - assertThat(refreshResponse.getStatusCode()).isEqualTo(HttpStatus.OK); - String message = template.getForObject("http://localhost:" + this.port + "/", String.class); - then(message).isEqualTo("Hello Dave!"); - } - - private RequestEntity getUrlEncodedEntity(String uri, String key, String value) throws URISyntaxException { - Map property = new HashMap<>(); - property.put("name", key); - property.put("value", value); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - RequestEntity> entity = new RequestEntity<>(property, headers, HttpMethod.POST, - new URI(uri)); - return entity; - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class ClientApp { - - @Bean - @org.springframework.cloud.context.config.annotation.RefreshScope - public Controller controller() { - return new Controller(); - } - - } - - @RestController - protected static class Controller { - - String message; - - @Value("${message:Hello World!}") - public void setMessage(String message) { - this.message = message; - } - - @GetMapping("/") - public String hello() { - return this.message; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConcurrencyTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConcurrencyTests.java deleted file mode 100644 index 403f1c10..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConcurrencyTests.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeConcurrencyTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.Repeat; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -public class RefreshScopeConcurrencyTests { - - private static Log logger = LogFactory.getLog(RefreshScopeConcurrencyTests.class); - - private ExecutorService executor = Executors.newSingleThreadExecutor(); - - @Autowired - private Service service; - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Test - @Repeat(10) - @DirtiesContext - public void testConcurrentRefresh() throws Exception { - - then(this.service.getMessage()).isEqualTo("Hello scope!"); - this.properties.setMessage("Foo"); - this.properties.setDelay(500); - final CountDownLatch latch = new CountDownLatch(1); - Future result = this.executor.submit(() -> { - logger.debug("Background started."); - try { - return RefreshScopeConcurrencyTests.this.service.getMessage(); - } - finally { - latch.countDown(); - logger.debug("Background done."); - } - }); - then(latch.await(15000, TimeUnit.MILLISECONDS)).isTrue(); - logger.info("Refreshing"); - this.scope.refreshAll(); - then(this.service.getMessage()).isEqualTo("Foo"); - /* - * This is the most important assertion: we don't want a null value because that - * means the bean was destroyed and not re-initialized before we accessed it. - */ - then(result.get()).isNotNull(); - then(result.get()).isEqualTo("Hello scope!"); - } - - public interface Service { - - String getMessage(); - - } - - public static class ExampleService implements Service, InitializingBean, DisposableBean { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private String message = null; - - private volatile long delay = 0; - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing message: " + this.message); - } - - @Override - public void destroy() throws Exception { - logger.debug("Destroying message: " + this.message); - this.message = null; - } - - @Override - public String getMessage() { - logger.debug("Getting message: " + this.message); - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + message); - this.message = message; - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TestProperties.class) - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Autowired - private TestProperties properties; - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage(this.properties.getMessage()); - service.setDelay(this.properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - @ManagedAttribute - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationScaleTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationScaleTests.java deleted file mode 100644 index ed9518ee..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationScaleTests.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeConfigurationScaleTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.Repeat; -import org.springframework.util.ObjectUtils; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class, properties = { - "logging.level.org.springframework.cloud.context.scope.refresh.RefreshScopeConfigurationScaleTests=DEBUG" }) -public class RefreshScopeConfigurationScaleTests { - - private static Log logger = LogFactory.getLog(RefreshScopeConfigurationScaleTests.class); - - @Autowired - org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - private ExecutorService executor = Executors.newFixedThreadPool(8); - - @Autowired - private ExampleService service; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @Repeat(10) - @DirtiesContext - public void testConcurrentRefresh() throws Exception { - - this.scope.setEager(false); - - // overload the thread pool and try to force Spring to create too many instances - int n = 80; - TestPropertyValues.of("message=Foo").applyTo(this.environment); - this.scope.refreshAll(); - final CountDownLatch latch = new CountDownLatch(n); - List> results = new ArrayList<>(); - for (int i = 0; i < n; i++) { - results.add(this.executor.submit(() -> { - logger.debug("Background started."); - try { - return RefreshScopeConfigurationScaleTests.this.service.getMessage(); - } - finally { - latch.countDown(); - logger.debug("Background done."); - } - })); - this.executor.submit(() -> { - logger.debug("Refreshing."); - RefreshScopeConfigurationScaleTests.this.scope.refreshAll(); - }); - } - then(latch.await(15000, TimeUnit.MILLISECONDS)).isTrue(); - then(this.service.getMessage()).isEqualTo("Foo"); - for (Future result : results) { - then(result.get()).isEqualTo("Foo"); - } - } - - public interface Service { - - String getMessage(); - - } - - public static class ExampleService implements Service, InitializingBean, DisposableBean { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private String message = null; - - private volatile long delay = 0; - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.debug("Initialized: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - } - - @Override - public void destroy() throws Exception { - logger.debug("Destroying message: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - this.message = null; - } - - @Override - public String getMessage() { - logger.debug("Returning message: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + ObjectUtils.getIdentityHexString(this) + ", " + message); - this.message = message; - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - @RefreshScope - public TestProperties properties() { - return new TestProperties(); - } - - @Bean - @RefreshScope - public ExampleService service(TestProperties properties) { - ExampleService service = new ExampleService(); - service.setMessage(properties.getMessage()); - service.setDelay(properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - protected static class TestProperties { - - private String message; - - private int delay; - - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationTests.java deleted file mode 100644 index 10dbf51e..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationTests.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.cloud.context.scope.refresh.RefreshScopeConfigurationTests.NestedApp.NestedController; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - * - */ -public class RefreshScopeConfigurationTests { - - private AnnotationConfigApplicationContext context; - - @AfterEach - public void init() { - if (this.context != null) { - this.context.close(); - } - } - - private void refresh() { - EnvironmentManager environmentManager = this.context.getBean(EnvironmentManager.class); - environmentManager.setProperty("message", "Hello Dave!"); - org.springframework.cloud.context.scope.refresh.RefreshScope scope = this.context - .getBean(org.springframework.cloud.context.scope.refresh.RefreshScope.class); - scope.refreshAll(); - } - - /** - * See gh-43 - */ - @Test - public void configurationWithRefreshScope() { - this.context = new AnnotationConfigApplicationContext(Application.class, - PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class, - LifecycleMvcEndpointAutoConfiguration.class); - Application application = this.context.getBean(Application.class); - then(this.context.getBeanDefinition(ScopedProxyUtils.getTargetBeanName("application")).getScope()) - .isEqualTo("refresh"); - application.hello(); - refresh(); - String message = application.hello(); - then(message).isEqualTo("Hello Dave!"); - } - - @Test - public void refreshScopeOnBean() { - this.context = new AnnotationConfigApplicationContext(ClientApp.class, - PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class, - LifecycleMvcEndpointAutoConfiguration.class); - Controller application = this.context.getBean(Controller.class); - application.hello(); - refresh(); - String message = application.hello(); - then(message).isEqualTo("Hello Dave!"); - } - - @Test - public void refreshScopeOnNested() { - this.context = new AnnotationConfigApplicationContext(NestedApp.class, - PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class, - LifecycleMvcEndpointAutoConfiguration.class); - NestedController application = this.context.getBean(NestedController.class); - application.hello(); - refresh(); - String message = application.hello(); - then(message).isEqualTo("Hello Dave!"); - } - - // WTF? Maven can't compile without the FQN on this one (not the others). - @org.springframework.context.annotation.Configuration - protected static class NestedApp { - - public static void main(String[] args) { - SpringApplication.run(ClientApp.class, args); - } - - @RestController - @RefreshScope - protected static class NestedController { - - @Value("${message:Hello World!}") - String message; - - @GetMapping("/") - public String hello() { - return this.message; - } - - } - - } - - @Configuration(value = "application", proxyBeanMethods = false) - @RefreshScope - protected static class Application { - - @Value("${message:Hello World!}") - String message = "Hello World"; - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - - @GetMapping("/") - public String hello() { - return this.message; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class ClientApp { - - public static void main(String[] args) { - SpringApplication.run(ClientApp.class, args); - } - - @Bean - @RefreshScope - public Controller controller() { - return new Controller(); - } - - } - - @RestController - protected static class Controller { - - @Value("${message:Hello World!}") - String message; - - @GetMapping("/") - // Deliberately use package scope - String hello() { - return this.message; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeIntegrationTests.java deleted file mode 100644 index 2516b1d7..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeIntegrationTests.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.Advised; -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -public class RefreshScopeIntegrationTests { - - @Autowired - private Service service; - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @BeforeEach - public void init() { - then(ExampleService.getInitCount()).isEqualTo(1); - ExampleService.reset(); - } - - @AfterEach - public void close() { - ExampleService.reset(); - } - - @Test - @DirtiesContext - public void testSimpleProperties() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(this.service instanceof Advised).isTrue(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...but don't refresh, so the bean stays the same: - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(ExampleService.getInitCount()).isEqualTo(0); - then(ExampleService.getDestroyCount()).isEqualTo(0); - } - - @Test - @DirtiesContext - public void testRefresh() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - String id1 = this.service.toString(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.scope.refreshAll(); - String id2 = this.service.toString(); - then(this.service.getMessage()).isEqualTo("Foo"); - then(ExampleService.getInitCount()).isEqualTo(1); - then(ExampleService.getDestroyCount()).isEqualTo(1); - then(id2).isNotSameAs(id1); - then(ExampleService.event).isNotNull(); - then(ExampleService.event.getName()).isEqualTo(RefreshScopeRefreshedEvent.DEFAULT_NAME); - } - - @Test - @DirtiesContext - public void testRefreshBean() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - String id1 = this.service.toString(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.scope.refresh("service"); - String id2 = this.service.toString(); - then(this.service.getMessage()).isEqualTo("Foo"); - then(this.service.getMessage()).isEqualTo("Foo"); - then(ExampleService.getInitCount()).isEqualTo(1); - then(ExampleService.getDestroyCount()).isEqualTo(1); - then(id2).isNotSameAs(id1); - then(ExampleService.event).isNotNull(); - then(ExampleService.event.getName()).isEqualTo(ScopedProxyUtils.getTargetBeanName("service")); - } - - // see gh-349 - @Test - @DirtiesContext - public void testCheckedException() { - Assertions.assertThrows(ServiceException.class, () -> this.service.throwsException()); - } - - public interface Service { - - String getMessage(); - - String throwsException() throws ServiceException; - - } - - public static class ExampleService - implements Service, InitializingBean, DisposableBean, ApplicationListener { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private volatile static int initCount = 0; - - private volatile static int destroyCount = 0; - - private volatile static RefreshScopeRefreshedEvent event; - - private String message = null; - - private volatile long delay = 0; - - public static void reset() { - initCount = 0; - destroyCount = 0; - event = null; - } - - public static int getInitCount() { - return initCount; - } - - public static int getDestroyCount() { - return destroyCount; - } - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing message: " + this.message); - initCount++; - } - - @Override - public void destroy() throws Exception { - logger.debug("Destroying message: " + this.message); - destroyCount++; - this.message = null; - } - - @Override - public String getMessage() { - logger.debug("Getting message: " + this.message); - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + message); - this.message = message; - } - - @Override - public String throwsException() throws ServiceException { - throw new ServiceException(); - } - - @Override - public void onApplicationEvent(RefreshScopeRefreshedEvent e) { - event = e; - } - - } - - @SuppressWarnings("serial") - public static class ServiceException extends Exception { - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TestProperties.class) - @EnableAutoConfiguration - protected static class TestConfiguration { - - @Autowired - private TestProperties properties; - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage(this.properties.getMessage()); - service.setDelay(this.properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - @ManagedAttribute - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeLazyIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeLazyIntegrationTests.java deleted file mode 100644 index 18414835..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeLazyIntegrationTests.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.Advised; -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeLazyIntegrationTests.TestConfiguration; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -public class RefreshScopeLazyIntegrationTests { - - @Autowired - private Service service; - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @BeforeEach - public void init() { - // The RefreshScope is lazy (eager=false) so it won't have been instantiated yet - then(ExampleService.getInitCount()).isEqualTo(0); - ExampleService.reset(); - } - - @AfterEach - public void close() { - ExampleService.reset(); - } - - @Test - @DirtiesContext - public void testSimpleProperties() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(this.service instanceof Advised).isTrue(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...but don't refresh, so the bean stays the same: - then(this.service.getMessage()).isEqualTo("Hello scope!"); - then(ExampleService.getInitCount()).isEqualTo(1); - then(ExampleService.getDestroyCount()).isEqualTo(0); - } - - @Test - @DirtiesContext - public void testRefresh() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - String id1 = this.service.toString(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.scope.refreshAll(); - String id2 = this.service.toString(); - then(this.service.getMessage()).isEqualTo("Foo"); - then(ExampleService.getInitCount()).isEqualTo(2); - then(ExampleService.getDestroyCount()).isEqualTo(1); - then(id2).isNotSameAs(id1); - then(ExampleService.event).isNotNull(); - then(ExampleService.event.getName()).isEqualTo(RefreshScopeRefreshedEvent.DEFAULT_NAME); - } - - @Test - @DirtiesContext - public void testRefreshBean() { - then(this.service.getMessage()).isEqualTo("Hello scope!"); - String id1 = this.service.toString(); - // Change the dynamic property source... - this.properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - this.scope.refresh("service"); - String id2 = this.service.toString(); - then(this.service.getMessage()).isEqualTo("Foo"); - then(ExampleService.getInitCount()).isEqualTo(2); - then(ExampleService.getDestroyCount()).isEqualTo(1); - then(id2).isNotSameAs(id1); - then(ExampleService.event).isNotNull(); - then(ExampleService.event.getName()).isEqualTo(ScopedProxyUtils.getTargetBeanName("service")); - } - - public interface Service { - - String getMessage(); - - } - - public static class ExampleService - implements Service, InitializingBean, DisposableBean, ApplicationListener { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private volatile static int initCount = 0; - - private volatile static int destroyCount = 0; - - private volatile static RefreshScopeRefreshedEvent event; - - private String message = null; - - private volatile long delay = 0; - - public static void reset() { - initCount = 0; - destroyCount = 0; - event = null; - } - - public static int getInitCount() { - return initCount; - } - - public static int getDestroyCount() { - return destroyCount; - } - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing message: " + this.message); - initCount++; - } - - @Override - public void destroy() throws Exception { - logger.debug("Destroying message: " + this.message); - destroyCount++; - this.message = null; - } - - @Override - public String getMessage() { - logger.debug("Getting message: " + this.message); - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + message); - this.message = message; - } - - @Override - public void onApplicationEvent(RefreshScopeRefreshedEvent e) { - event = e; - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TestProperties.class) - @ImportAutoConfiguration({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Autowired - private TestProperties properties; - - @Bean - public static org.springframework.cloud.context.scope.refresh.RefreshScope refreshScope() { - org.springframework.cloud.context.scope.refresh.RefreshScope scope = null; - scope = new org.springframework.cloud.context.scope.refresh.RefreshScope(); - scope.setEager(false); - return scope; - } - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage(this.properties.getMessage()); - service.setDelay(this.properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - @ManagedAttribute - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeListBindingIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeListBindingIntegrationTests.java deleted file mode 100644 index 9e54a336..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeListBindingIntegrationTests.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.framework.Advised; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeListBindingIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.PropertySource; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class, properties = { "test.messages[0]=one", "test.messages[1]=two" }) -public class RefreshScopeListBindingIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @DirtiesContext - public void testAppendProperties() { - then("[one, two]").isEqualTo(this.properties.getMessages().toString()); - then(this.properties instanceof Advised).isTrue(); - TestPropertyValues.of("test.messages[0]:foo").applyTo(this.environment); - this.scope.refreshAll(); - then(this.properties.getMessages().toString()).isEqualTo("[foo]"); - } - - @Test - @DirtiesContext - public void testReplaceProperties() { - then("[one, two]").isEqualTo(this.properties.getMessages().toString()); - then(this.properties instanceof Advised).isTrue(); - Map map = findTestProperties(); - map.clear(); - TestPropertyValues.of("test.messages[0]:foo").applyTo(this.environment); - this.scope.refreshAll(); - then(this.properties.getMessages().toString()).isEqualTo("[foo]"); - } - - private Map findTestProperties() { - for (PropertySource source : this.environment.getPropertySources()) { - if (source.getName().toLowerCase().contains("test")) { - @SuppressWarnings("unchecked") - Map map = (Map) source.getSource(); - return map; - } - } - throw new IllegalStateException("Could not find test property source"); - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - @RefreshScope - protected TestProperties properties() { - return new TestProperties(); - } - - } - - @ConfigurationProperties("test") - @ManagedResource - protected static class TestProperties { - - private List messages = new ArrayList<>(); - - public List getMessages() { - return this.messages; - } - - public void setMessages(List messages) { - this.messages = messages; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeNullBeanIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeNullBeanIntegrationTests.java deleted file mode 100644 index 8f7afa91..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeNullBeanIntegrationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.junit.jupiter.api.Test; - -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.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -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 static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = { RefreshScopeNullBeanIntegrationTests.TestConfiguration.class }) -public class RefreshScopeNullBeanIntegrationTests { - - @Autowired - private MyCustomComponent myCustomComponent; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Test - @DirtiesContext - public void testRefreshBean() { - then(this.myCustomComponent.optionalService).isNotNull(); - then(this.scope).isNotNull(); - // ...and then refresh, so the bean is re-initialized: - // this.scope.refreshAll(); - } - - protected static class OptionalService { - - } - - public static class MyCustomComponent { - - private final OptionalService optionalService; - - public MyCustomComponent(OptionalService optionalService) { - this.optionalService = optionalService; - } - - } - - @Configuration(proxyBeanMethods = false) - protected static class OptionalConfiguration { - - @Bean - @RefreshScope - public OptionalService service() { - return null; - } - - } - - @Configuration(proxyBeanMethods = false) - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, OptionalConfiguration.class }) - protected static class TestConfiguration { - - @Autowired(required = false) - private OptionalService optionalService; - - @Bean - public MyCustomComponent myCustomComponent() { - return new MyCustomComponent(this.optionalService); - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopePureScaleTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopePureScaleTests.java deleted file mode 100644 index 15a0efe2..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopePureScaleTests.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -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.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopePureScaleTests.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.annotation.Repeat; -import org.springframework.util.ObjectUtils; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -// , -// properties="logging.level.org.springframework.cloud.context.scope.refresh.RefreshScopePureScaleTests=DEBUG") -public class RefreshScopePureScaleTests { - - private static Log logger = LogFactory.getLog(RefreshScopePureScaleTests.class); - - @Autowired - org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - private ExecutorService executor = Executors.newFixedThreadPool(8); - - @Autowired - private ExampleService service; - - @Test - @Repeat(10) - @DirtiesContext - public void testConcurrentRefresh() throws Exception { - - // overload the thread pool and try to force Spring to create too many instances - int n = 80; - this.scope.refreshAll(); - final CountDownLatch latch = new CountDownLatch(n); - List> results = new ArrayList<>(); - for (int i = 0; i < n; i++) { - results.add(this.executor.submit(() -> { - logger.debug("Background started."); - try { - return RefreshScopePureScaleTests.this.service.getMessage(); - } - finally { - latch.countDown(); - logger.debug("Background done."); - } - })); - this.executor.submit(() -> { - logger.debug("Refreshing."); - RefreshScopePureScaleTests.this.scope.refreshAll(); - }); - } - then(latch.await(15000, TimeUnit.MILLISECONDS)).isTrue(); - then(this.service.getMessage()).isEqualTo("Foo"); - for (Future result : results) { - then(result.get()).isEqualTo("Foo"); - } - } - - public interface Service { - - String getMessage(); - - } - - public static class ExampleService implements Service, InitializingBean, DisposableBean { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private String message = null; - - private volatile long delay = 0; - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.debug("Initialized: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - } - - @Override - public void destroy() throws Exception { - logger.debug("Destroying message: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - this.message = null; - } - - @Override - public String getMessage() { - logger.debug("Returning message: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + ObjectUtils.getIdentityHexString(this) + ", " + message); - this.message = message; - } - - } - - @Configuration(proxyBeanMethods = false) - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage("Foo"); - return service; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeScaleTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeScaleTests.java deleted file mode 100644 index 7582604a..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeScaleTests.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeScaleTests.TestConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.Repeat; - -import static org.assertj.core.api.BDDAssertions.then; - -@SpringBootTest(classes = TestConfiguration.class) -public class RefreshScopeScaleTests { - - private static Log logger = LogFactory.getLog(RefreshScopeScaleTests.class); - - @Autowired - org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - private ExecutorService executor = Executors.newFixedThreadPool(8); - - @Autowired - private ExampleService service; - - @Autowired - private TestProperties properties; - - @Test - @Repeat(10) - @DirtiesContext - public void testConcurrentRefresh() throws Exception { - - // overload the thread pool and try to force Spring to create too many instances - int n = 80; - ExampleService.count = 0; - this.properties.setMessage("Foo"); - this.properties.setDelay(500); - this.scope.refreshAll(); - final CountDownLatch latch = new CountDownLatch(n); - Future result = null; - for (int i = 0; i < n; i++) { - result = this.executor.submit(() -> { - logger.debug("Background started."); - try { - return RefreshScopeScaleTests.this.service.getMessage(); - } - finally { - latch.countDown(); - logger.debug("Background done."); - } - }); - } - then(latch.await(15000, TimeUnit.MILLISECONDS)).isTrue(); - then(this.service.getMessage()).isEqualTo("Foo"); - then(result.get()).isNotNull(); - then(result.get()).isEqualTo("Foo"); - then(ExampleService.count).isEqualTo(1); - } - - public interface Service { - - String getMessage(); - - } - - public static class ExampleService implements Service, InitializingBean, DisposableBean { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private static volatile int count; - - private String message = null; - - private volatile long delay = 0; - - public void setDelay(long delay) { - this.delay = delay; - } - - @Override - public void afterPropertiesSet() throws Exception { - ExampleService.count++; - try { - Thread.sleep(this.delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.debug("Initializing message: " + this.message); - } - - @Override - public void destroy() throws Exception { - logger.debug("Destroying message: " + this.message); - this.message = null; - } - - @Override - public String getMessage() { - logger.debug("Returning message: " + this.message); - return this.message; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + message); - this.message = message; - } - - } - - @Configuration(proxyBeanMethods = false) - @EnableConfigurationProperties(TestProperties.class) - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Autowired - private TestProperties properties; - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage(this.properties.getMessage()); - service.setDelay(this.properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - @ManagedAttribute - public String getMessage() { - return this.message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return this.delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeSerializationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeSerializationTests.java deleted file mode 100644 index 1fda3f19..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeSerializationTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - */ -public class RefreshScopeSerializationTests { - - @Test - public void defaultApplicationContextId() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfiguration.class) - .properties("spring.cloud.bootstrap.enabled=true").web(WebApplicationType.NONE).run(); - then(context.getId()).isEqualTo("application-1"); - } - - @Test - public void serializationIdReproducible() { - String first = getBeanFactory().getSerializationId(); - String second = getBeanFactory().getSerializationId(); - then(first).isNotNull(); - then(first).isNotEqualTo("application"); - then(first).isEqualTo(second); - } - - private DefaultListableBeanFactory getBeanFactory() { - ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfiguration.class) - .web(WebApplicationType.NONE).run(); - DefaultListableBeanFactory factory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory(); - return factory; - } - - @Configuration(proxyBeanMethods = false) - protected static class TestConfiguration { - - @Bean - public RefreshScope refreshScope() { - return new RefreshScope(); - } - - @Bean - @org.springframework.cloud.context.config.annotation.RefreshScope - public TestBean testBean() { - return new TestBean(); - } - - } - - protected static class TestBean { - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeWebIntegrationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeWebIntegrationTests.java deleted file mode 100644 index 1d2a7a28..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeWebIntegrationTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.scope.refresh; - -import org.junit.jupiter.api.Test; - -import org.springframework.aop.scope.ScopedProxyUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.cloud.context.scope.refresh.RefreshScopeWebIntegrationTests.Application; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - * - */ -@SpringBootTest(classes = Application.class) -public class RefreshScopeWebIntegrationTests { - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Autowired - private EnvironmentManager environmentManager; - - @Autowired - private Client application; - - @Autowired - private ConfigurableListableBeanFactory beanFactory; - - @Test - public void scopeOnBeanDefinition() { - then(this.beanFactory.getBeanDefinition(ScopedProxyUtils.getTargetBeanName("application")).getScope()) - .isEqualTo("refresh"); - } - - @Test - public void beanAccess() { - this.application.hello(); - this.environmentManager.setProperty("message", "Hello Dave!"); - this.scope.refreshAll(); - String message = this.application.hello(); - then(message).isEqualTo("Hello Dave!"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - protected static class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - - @Bean - @RefreshScope - public Client application() { - return new Client(); - } - - } - - @RestController - protected static class Client { - - @Value("${message:Hello World!}") - String message; - - @GetMapping("/") - public String hello() { - return this.message; - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLoader.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLoader.java deleted file mode 100644 index 3b35f850..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLoader.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.test; - -import java.util.Collections; - -import org.springframework.boot.context.config.ConfigData; -import org.springframework.boot.context.config.ConfigDataLoader; -import org.springframework.boot.context.config.ConfigDataLoaderContext; -import org.springframework.boot.context.config.ConfigDataResourceNotFoundException; -import org.springframework.core.env.MapPropertySource; - -public class TestConfigDataLoader implements ConfigDataLoader { - - @Override - public ConfigData load(ConfigDataLoaderContext context, TestConfigDataResource resource) - throws ConfigDataResourceNotFoundException { - return new ConfigData( - Collections.singletonList(new MapPropertySource("testconfigdatadatasource", resource.props))); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLocationResolver.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLocationResolver.java deleted file mode 100644 index 6738c230..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataLocationResolver.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.test; - -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.context.config.ConfigDataLocation; -import org.springframework.boot.context.config.ConfigDataLocationNotFoundException; -import org.springframework.boot.context.config.ConfigDataLocationResolver; -import org.springframework.boot.context.config.ConfigDataLocationResolverContext; -import org.springframework.boot.context.config.ConfigDataResourceNotFoundException; -import org.springframework.boot.context.properties.bind.Bindable; - -public class TestConfigDataLocationResolver implements ConfigDataLocationResolver { - - public static AtomicInteger count = new AtomicInteger(1); - - public static Map config = new HashMap<>(); - - public static Object instance; - - @Override - public boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDataLocation location) { - return location.hasPrefix("testdatasource:"); - } - - @Override - public List resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location) - throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException { - if (instance != null) { - BootstrapRegistry.InstanceSupplier supplier = BootstrapRegistry.InstanceSupplier.of(instance); - Class aClass = (Class) instance.getClass(); - context.getBootstrapContext().registerIfAbsent(aClass, supplier); - } - String myplaceholder = context.getBinder().bind("myplaceholder", Bindable.of(String.class)).orElse("notfound"); - HashMap props = new HashMap<>(config); - props.put(TestEnvPostProcessor.EPP_VALUE, count.get()); - if (count.get() == 99 && myplaceholder.contains("${vcap")) { - throw new ConfigDataResourceNotFoundException(new TestConfigDataResource(props), - new IllegalArgumentException("placeholder not resolved")); - } - return Collections.singletonList(new TestConfigDataResource(props)); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataResource.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataResource.java deleted file mode 100644 index 5730e185..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestConfigDataResource.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.test; - -import java.util.HashMap; -import java.util.Objects; - -import org.springframework.boot.context.config.ConfigDataResource; - -public class TestConfigDataResource extends ConfigDataResource { - - final HashMap props; - - public TestConfigDataResource(HashMap props) { - this.props = props; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TestConfigDataResource that = (TestConfigDataResource) o; - return Objects.equals(this.props, that.props); - } - - @Override - public int hashCode() { - return Objects.hash(this.props); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestEnvPostProcessor.java b/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestEnvPostProcessor.java deleted file mode 100644 index 9c5299b3..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/context/test/TestEnvPostProcessor.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.context.test; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor; -import org.springframework.boot.env.EnvironmentPostProcessor; -import org.springframework.core.Ordered; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; - -public class TestEnvPostProcessor implements EnvironmentPostProcessor, Ordered { - - public static final String EPP_ENABLED = "configdatarefresh.epp.enabled"; - - public static final String EPP_VALUE = "configdatarefresh.epp.count"; - - @Override - public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - if (environment.getProperty(EPP_ENABLED, Boolean.class, false)) { - Map source = new HashMap<>(); - source.put("spring.cloud.refresh.additional-property-sources-to-retain", getClass().getSimpleName()); - source.put("spring.config.import", "testdatasource:"); - MapPropertySource propertySource = new MapPropertySource(getClass().getSimpleName(), source); - environment.getPropertySources().addFirst(propertySource); - } - } - - @Override - public int getOrder() { - return ConfigDataEnvironmentPostProcessor.ORDER - 1; - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java deleted file mode 100644 index ac4138bb..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/endpoint/RefreshEndpointTests.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.endpoint; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.DisabledForJreRange; -import org.junit.jupiter.api.condition.JRE; - -import org.springframework.boot.Banner.Mode; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.test.util.TestPropertyValues.Type; -import org.springframework.cloud.bootstrap.config.PropertySourceLocator; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.cloud.context.refresh.LegacyContextRefresher; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.event.SmartApplicationListener; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.stereotype.Component; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - * @author Venil Noronha - */ -public class RefreshEndpointTests { - - private ConfigurableApplicationContext context; - - @AfterEach - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - @Disabled // FIXME: legacy - public void keysComputedWhenAdded() { - this.context = new SpringApplicationBuilder(Empty.class).web(WebApplicationType.NONE).bannerMode(Mode.OFF) - .properties("spring.cloud.bootstrap.enabled=true", "spring.cloud.bootstrap.name:none").run(); - RefreshScope scope = new RefreshScope(); - scope.setApplicationContext(this.context); - this.context.getEnvironment().setActiveProfiles("local"); - ContextRefresher contextRefresher = new LegacyContextRefresher(this.context, scope); - RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); - Collection keys = endpoint.refresh(); - then(keys.contains("added")).isTrue().as("Wrong keys: " + keys); - } - - @Test - @Disabled // FIXME: legacy - public void keysComputedWhenOveridden() { - this.context = new SpringApplicationBuilder(Empty.class).web(WebApplicationType.NONE).bannerMode(Mode.OFF) - .properties("spring.cloud.bootstrap.enabled=true", "spring.cloud.bootstrap.name:none").run(); - RefreshScope scope = new RefreshScope(); - scope.setApplicationContext(this.context); - this.context.getEnvironment().setActiveProfiles("override"); - ContextRefresher contextRefresher = new LegacyContextRefresher(this.context, scope); - RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); - Collection keys = endpoint.refresh(); - then(keys.contains("message")).isTrue().as("Wrong keys: " + keys); - } - - @Test - public void keysComputedWhenChangesInExternalProperties() { - this.context = new SpringApplicationBuilder(Empty.class).web(WebApplicationType.NONE).bannerMode(Mode.OFF) - .properties("spring.cloud.bootstrap.name:none", "spring.cloud.bootstrap.enabled=true").run(); - RefreshScope scope = new RefreshScope(); - scope.setApplicationContext(this.context); - TestPropertyValues.of("spring.cloud.bootstrap.sources=" + ExternalPropertySourceLocator.class.getName()) - .applyTo(this.context.getEnvironment(), Type.MAP, "defaultProperties"); - ContextRefresher contextRefresher = new LegacyContextRefresher(this.context, scope); - RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); - Collection keys = endpoint.refresh(); - then(keys.contains("external.message")).isTrue().as("Wrong keys: " + keys); - } - - @Test - public void springMainSourcesEmptyInRefreshCycle() { - this.context = new SpringApplicationBuilder(Empty.class).web(WebApplicationType.NONE).bannerMode(Mode.OFF) - .properties("spring.cloud.bootstrap.name:none").run(); - RefreshScope scope = new RefreshScope(); - scope.setApplicationContext(this.context); - // spring.main.sources should be empty when the refresh cycle starts (we don't - // want any config files from the application context getting into the one used to - // construct the environment for refresh) - TestPropertyValues.of("spring.main.sources=" + ExternalPropertySourceLocator.class.getName()) - .applyTo(this.context); - ContextRefresher contextRefresher = new LegacyContextRefresher(this.context, scope); - RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); - Collection keys = endpoint.refresh(); - then(keys.contains("external.message")).as("Wrong keys: " + keys).isFalse(); - } - - @Test - public void eventsPublishedInOrder() { - this.context = new SpringApplicationBuilder(Empty.class).web(WebApplicationType.NONE).bannerMode(Mode.OFF) - .run(); - RefreshScope scope = new RefreshScope(); - scope.setApplicationContext(this.context); - ContextRefresher contextRefresher = new LegacyContextRefresher(this.context, scope); - RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); - Empty empty = this.context.getBean(Empty.class); - endpoint.refresh(); - int after = empty.events.size(); - then(2).isEqualTo(after).as("Shutdown hooks not cleaned on refresh"); - then(empty.events.get(0) instanceof EnvironmentChangeEvent).isTrue(); - } - - @Test - @DisabledForJreRange(min = JRE.JAVA_16) // FIXME: - public void shutdownHooksCleaned() { - try (ConfigurableApplicationContext context = new SpringApplicationBuilder(Empty.class) - .web(WebApplicationType.NONE).bannerMode(Mode.OFF).run()) { - RefreshScope scope = new RefreshScope(); - scope.setApplicationContext(context); - ContextRefresher contextRefresher = new LegacyContextRefresher(context, scope); - RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher); - int count = countShutdownHooks(); - endpoint.refresh(); - int after = countShutdownHooks(); - then(count).isEqualTo(after).as("Shutdown hooks not cleaned on refresh"); - } - } - - private int countShutdownHooks() { - Class type = ClassUtils.resolveClassName("java.lang.ApplicationShutdownHooks", null); - Field field = ReflectionUtils.findField(type, "hooks"); - ReflectionUtils.makeAccessible(field); - @SuppressWarnings("rawtypes") - Map map = (Map) ReflectionUtils.getField(field, null); - return map.size(); - } - - @Configuration(proxyBeanMethods = false) - protected static class Empty implements SmartApplicationListener { - - private List events = new ArrayList<>(); - - @Override - public boolean supportsEventType(Class eventType) { - return EnvironmentChangeEvent.class.isAssignableFrom(eventType) - || RefreshScopeRefreshedEvent.class.isAssignableFrom(eventType); - } - - @Override - public void onApplicationEvent(ApplicationEvent event) { - if (event instanceof EnvironmentChangeEvent || event instanceof RefreshScopeRefreshedEvent) { - this.events.add(event); - } - } - - } - - @Component - protected static class ExternalPropertySourceLocator implements PropertySourceLocator { - - @Override - public PropertySource locate(Environment environment) { - return new MapPropertySource("external", Collections.singletonMap("external.message", "I'm External")); - } - - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/health/RefreshScopeHealthIndicatorTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/health/RefreshScopeHealthIndicatorTests.java deleted file mode 100644 index ea549487..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/health/RefreshScopeHealthIndicatorTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.health; - -import java.util.Collections; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.BDDMockito; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.cloud.context.scope.refresh.RefreshScope; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * @author Dave Syer - */ -public class RefreshScopeHealthIndicatorTests { - - @SuppressWarnings("unchecked") - private ObjectProvider scopeProvider = mock(ObjectProvider.class); - - private ConfigurationPropertiesRebinder rebinder = mock(ConfigurationPropertiesRebinder.class); - - private RefreshScope scope = mock(RefreshScope.class); - - private RefreshScopeHealthIndicator indicator = new RefreshScopeHealthIndicator(this.scopeProvider, this.rebinder); - - @BeforeEach - public void init() { - BDDMockito.willReturn(this.scope).given(this.scopeProvider).getIfAvailable(); - when(this.rebinder.getErrors()).thenReturn(Collections.emptyMap()); - when(this.scope.getErrors()).thenReturn(Collections.emptyMap()); - } - - @Test - public void sunnyDay() { - then(this.indicator.health().getStatus()).isEqualTo(Status.UP); - } - - @Test - public void binderError() { - when(this.rebinder.getErrors()).thenReturn(Collections.singletonMap("foo", new RuntimeException("FOO"))); - then(this.indicator.health().getStatus()).isEqualTo(Status.DOWN); - } - - @Test - public void scopeError() { - when(this.scope.getErrors()).thenReturn(Collections.singletonMap("foo", new RuntimeException("FOO"))); - then(this.indicator.health().getStatus()).isEqualTo(Status.DOWN); - } - - @Test - public void bothError() { - when(this.rebinder.getErrors()).thenReturn(Collections.singletonMap("foo", new RuntimeException("FOO"))); - when(this.scope.getErrors()).thenReturn(Collections.singletonMap("bar", new RuntimeException("BAR"))); - then(this.indicator.health().getStatus()).isEqualTo(Status.DOWN); - } - - @Test - public void nullRefreshScope() { - ObjectProvider scopeProvider = mock(ObjectProvider.class); - BDDMockito.willReturn(null).given(scopeProvider).getIfAvailable(); - then(this.indicator.health().getStatus()).isEqualTo(Status.UP); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/logging/LoggingRebinderTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/logging/LoggingRebinderTests.java deleted file mode 100644 index e04401cd..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/logging/LoggingRebinderTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.logging; - -import java.util.Collections; - -import ch.qos.logback.classic.Level; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.springframework.boot.logging.LogLevel; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.core.env.StandardEnvironment; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Dave Syer - * @author Olga Maciaszek-Sharma - * - */ -public class LoggingRebinderTests { - - private LoggingRebinder rebinder = new LoggingRebinder(); - - private Logger logger = LoggerFactory.getLogger("org.springframework.web"); - - @AfterEach - public void reset() { - LoggingSystem.get(getClass().getClassLoader()).setLogLevel("org.springframework.web", LogLevel.INFO); - } - - @Test - public void logLevelsChanged() { - then(this.logger.isTraceEnabled()).isFalse(); - StandardEnvironment environment = new StandardEnvironment(); - TestPropertyValues.of("logging.level.org.springframework.web=TRACE").applyTo(environment); - this.rebinder.setEnvironment(environment); - this.rebinder.onApplicationEvent(new EnvironmentChangeEvent(environment, - Collections.singleton("logging.level.org.springframework.web"))); - then(this.logger.isTraceEnabled()).isTrue(); - } - - @Test - public void logLevelsLowerCase() { - then(this.logger.isTraceEnabled()).isFalse(); - StandardEnvironment environment = new StandardEnvironment(); - TestPropertyValues.of("logging.level.org.springframework.web=trace").applyTo(environment); - this.rebinder.setEnvironment(environment); - this.rebinder.onApplicationEvent(new EnvironmentChangeEvent(environment, - Collections.singleton("logging.level.org.springframework.web"))); - then(this.logger.isTraceEnabled()).isTrue(); - } - - @Test - public void logLevelFalseResolvedToOff() { - ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory - .getLogger("org.springframework.cloud"); - StandardEnvironment environment = new StandardEnvironment(); - TestPropertyValues.of("logging.level.org.springframework.cloud=false").applyTo(environment); - rebinder.setEnvironment(environment); - rebinder.onApplicationEvent(new EnvironmentChangeEvent(environment, - Collections.singleton("logging.level.org.springframework.cloud"))); - then(Level.OFF).isEqualTo((logger.getLevel())); - } - -} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/util/random/CachedRandomPropertySourceTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/util/random/CachedRandomPropertySourceTests.java deleted file mode 100644 index f39f93d5..00000000 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/util/random/CachedRandomPropertySourceTests.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.util.random; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; - -import org.springframework.core.env.PropertySource; -import org.springframework.test.annotation.DirtiesContext; - -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -/** - * @author Ryan Baxter - */ -@ExtendWith(MockitoExtension.class) -@DirtiesContext -public class CachedRandomPropertySourceTests { - - @Mock - private PropertySource randomValuePropertySource; - - @BeforeEach - public void setup() { - when(randomValuePropertySource.getProperty(eq("random.long"))).thenReturn(1234L); - } - - @Test - public void getProperty() { - HashMap keyCount = new HashMap<>(); - HashMap, String> typeToKeyLookup = new HashMap<>(); - HashMap typeCount = new HashMap<>(); - Map> cache = createCache(keyCount, typeToKeyLookup, typeCount); - Map typeCache = createTypeCache(typeToKeyLookup, typeCount); - typeCache.put("long", 5678L); - cache.put("foo", typeCache); - - CachedRandomPropertySource cachedRandomPropertySource = new CachedRandomPropertySource( - randomValuePropertySource, cache); - then(cachedRandomPropertySource.getProperty("foo.app.long")).isNull(); - then(cachedRandomPropertySource.getProperty("cachedrandom.app")).isNull(); - - then(cachedRandomPropertySource.getProperty("cachedrandom.app.long")).isEqualTo(1234L); - then(cachedRandomPropertySource.getProperty("cachedrandom.foo.long")).isEqualTo(5678L); - then(keyCount).containsOnlyKeys("app"); // verifies foo wasn't computed - then(keyCount.get("app").get()).isEqualTo(1); - then(typeCount).containsOnlyKeys("app.long"); // verifies foo.long wasn't computed - then(typeCount.get("app.long").get()).isEqualTo(1); - } - - private HashMap> createCache(HashMap keyCount, - HashMap, String> typeToKeyLookup, HashMap typeCount) { - return new HashMap<>() { - @Override - public Map computeIfAbsent(String key, - Function> mappingFunction) { - boolean computed = false; - if (!containsKey(key)) { - keyCount.computeIfAbsent(key, s -> new AtomicInteger()).incrementAndGet(); - computed = true; - } - Map value = super.computeIfAbsent(key, mappingFunction); - if (computed && value.isEmpty()) { - // replace value with instrumented map - value = createTypeCache(typeToKeyLookup, typeCount); - typeToKeyLookup.put(value, key); - } - return value; - } - }; - } - - private HashMap createTypeCache(HashMap, String> typeToKeyLookup, - HashMap typeCount) { - return new HashMap<>() { - @Override - public Object computeIfAbsent(String key, Function mappingFunction) { - if (!containsKey(key)) { - String parentKey = typeToKeyLookup.get(this); - typeCount.computeIfAbsent(parentKey + "." + key, s -> new AtomicInteger()).incrementAndGet(); - } - return super.computeIfAbsent(key, mappingFunction); - } - }; - } - -} diff --git a/spring-cloud-context/src/test/resources/META-INF/spring.factories b/spring-cloud-context/src/test/resources/META-INF/spring.factories deleted file mode 100644 index ca038dad..00000000 --- a/spring-cloud-context/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,15 +0,0 @@ -# Bootstrap components -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.bootstrap.TestBootstrapConfiguration,\ -org.springframework.cloud.bootstrap.TestHigherPriorityBootstrapConfiguration - -org.springframework.boot.env.EnvironmentPostProcessor=\ -org.springframework.cloud.context.test.TestEnvPostProcessor - -# ConfigData Location Resolvers -org.springframework.boot.context.config.ConfigDataLocationResolver=\ -org.springframework.cloud.context.test.TestConfigDataLocationResolver - -# ConfigData Loaders -org.springframework.boot.context.config.ConfigDataLoader=\ -org.springframework.cloud.context.test.TestConfigDataLoader \ No newline at end of file diff --git a/spring-cloud-context/src/test/resources/application-config.properties b/spring-cloud-context/src/test/resources/application-config.properties deleted file mode 100644 index b2456bd0..00000000 --- a/spring-cloud-context/src/test/resources/application-config.properties +++ /dev/null @@ -1 +0,0 @@ -config.name:main diff --git a/spring-cloud-context/src/test/resources/application-encrypt.properties b/spring-cloud-context/src/test/resources/application-encrypt.properties deleted file mode 100644 index 95f6d292..00000000 --- a/spring-cloud-context/src/test/resources/application-encrypt.properties +++ /dev/null @@ -1 +0,0 @@ -foo:{cipher}e4e061f9fe39ba5b14d8012d2f17d39775606039409b71ed4be0fdd033d5324a diff --git a/spring-cloud-context/src/test/resources/application-local.properties b/spring-cloud-context/src/test/resources/application-local.properties deleted file mode 100644 index 8f441186..00000000 --- a/spring-cloud-context/src/test/resources/application-local.properties +++ /dev/null @@ -1 +0,0 @@ -added:Hello added! diff --git a/spring-cloud-context/src/test/resources/application-override.properties b/spring-cloud-context/src/test/resources/application-override.properties deleted file mode 100644 index 5ccbd612..00000000 --- a/spring-cloud-context/src/test/resources/application-override.properties +++ /dev/null @@ -1 +0,0 @@ -message:Hello override! diff --git a/spring-cloud-context/src/test/resources/application.properties b/spring-cloud-context/src/test/resources/application.properties deleted file mode 100644 index d92f2ea4..00000000 --- a/spring-cloud-context/src/test/resources/application.properties +++ /dev/null @@ -1,10 +0,0 @@ -message:Hello scope! -delay:0 -cachedRandomLong: ${cachedrandom.app.long} -randomLong: ${random.long} -debug:true -#logging.level.org.springframework.web: DEBUG -#logging.level.org.springframework.context.annotation: DEBUG -logging.level.org.hibernate=ERROR -logging.level.com.zaxxer.hikari=ERROR -myplaceholder=${vcap.services.myvcap.myvar} diff --git a/spring-cloud-context/src/test/resources/bootstrap-config.properties b/spring-cloud-context/src/test/resources/bootstrap-config.properties deleted file mode 100644 index 3f222275..00000000 --- a/spring-cloud-context/src/test/resources/bootstrap-config.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.main.sources:org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderIntegrationTests.ConfigPropertiesConfig -config.name:parent diff --git a/spring-cloud-context/src/test/resources/bootstrap-encrypt.properties b/spring-cloud-context/src/test/resources/bootstrap-encrypt.properties deleted file mode 100644 index 81ce3411..00000000 --- a/spring-cloud-context/src/test/resources/bootstrap-encrypt.properties +++ /dev/null @@ -1 +0,0 @@ -bar:{cipher}6154ca04d4bb6144d672c4e3d750b5147116dd381946d51fa44f8bc25dc256f4 diff --git a/spring-cloud-context/src/test/resources/bootstrap-epptests.properties b/spring-cloud-context/src/test/resources/bootstrap-epptests.properties deleted file mode 100644 index 12a28129..00000000 --- a/spring-cloud-context/src/test/resources/bootstrap-epptests.properties +++ /dev/null @@ -1 +0,0 @@ -info.name=from bootstrap-epptests diff --git a/spring-cloud-context/src/test/resources/bootstrap-parent.properties b/spring-cloud-context/src/test/resources/bootstrap-parent.properties deleted file mode 100644 index 3ff20cea..00000000 --- a/spring-cloud-context/src/test/resources/bootstrap-parent.properties +++ /dev/null @@ -1 +0,0 @@ -info.name:parent diff --git a/spring-cloud-context/src/test/resources/bootstrap-refresh.properties b/spring-cloud-context/src/test/resources/bootstrap-refresh.properties deleted file mode 100644 index 3a3d334c..00000000 --- a/spring-cloud-context/src/test/resources/bootstrap-refresh.properties +++ /dev/null @@ -1,2 +0,0 @@ -info.name:refresh-child -test.bootstrap.foo:refresh diff --git a/spring-cloud-context/src/test/resources/bootstrap.properties b/spring-cloud-context/src/test/resources/bootstrap.properties deleted file mode 100644 index 00a59b28..00000000 --- a/spring-cloud-context/src/test/resources/bootstrap.properties +++ /dev/null @@ -1,5 +0,0 @@ -spring.main.sources:org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.PropertySourceConfiguration,org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.CompositePropertySourceConfiguration -info.name:child -info.desc: defaultPropertiesInfoDesc -test.property: from bootstrap.properties - diff --git a/spring-cloud-context/src/test/resources/custom.properties b/spring-cloud-context/src/test/resources/custom.properties deleted file mode 100644 index dd62949d..00000000 --- a/spring-cloud-context/src/test/resources/custom.properties +++ /dev/null @@ -1 +0,0 @@ -spring.main.sources:org.springframework.cloud.bootstrap.BootstrapOrderingCustomPropertySourceIntegrationTests.PropertySourceConfiguration diff --git a/spring-cloud-context/src/test/resources/example-test-rsa-private-key b/spring-cloud-context/src/test/resources/example-test-rsa-private-key deleted file mode 100644 index 1050b1dc..00000000 --- a/spring-cloud-context/src/test/resources/example-test-rsa-private-key +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAwClFgrRa/PUHPIJr9gvIPL6g6Rjp/TVZmVNOf2fL96DYbkj5 -4YbrwfKwjoTjk1M6gLQpOA4Blocx6zN5OnICnVGlVM9xymWxTxxCfc2tE2Fai9I1wchULCChhwm/UU5ZNi3KpXinlyamSYw+lMQkZ8gTXCgOEvs2j9E1quF4pvy1BZKvbD8tUnUQlyiKRnI6gOxQL8B6OAYPRdaa9FVNmrs1B4eDPG918L2f1pT090P1n+tw -iejNgQvtSD78/A88qt89OhzscsufALTrBjycn89kkfBd0zbVLF0W6+ZVLZrf97/y -LCoGSCcZL9LFPNvNqxOnleviDco7aOs4stQ9jQIDAQABAoIBAQC1TbthyN0YUe+T - 7dIDAbbZaVrU00biOtXgzjMADmTprP7Hf18UpIIIKfzfWw6FUD+gc1t4oe5pogE9 -UwGMXUmOORxu2pMYTb5vT9CEdexYnsAZsCo8PdD9GYSNrmquQef2MFpEqYQmHrdC - KWpaXn2i1ak+iCRPUGp4YwHpynZVxfE8z/AIsPn6NPDh6SnCXb1rTgQe2UCfXm93 -UJe5F/OR2kQi5KFO+dxLmCOBCwr6SGCLH+VotGpuxCVRUd9sJ/d4QpDZEgjuf7Ug -eQHfgMDS/tc09B9rl0dwKnEa31kcQ9X9KLkKP+w0Pqhh0Emny20eg9jS6XNayg61 -p/LQtW9BAoGBAO5veKMIcXfZmuh11WIIhdhLKkNtYyt5NDmrV8/IVScLFvjB0ftt -8PAtXo/ekOHkyITyIumQ9l4VCvacNw7DyV9FYk4WvrvVYOCL8aZi+O5+12NT67eO -Rr/voGlRoV05X7+inc90qbbYJ8lRmLSqvzmsm98mkuhw/FKGRhVZIfAJAoGBAM5R - I5vK6cJxOwXQOEGOd5/8B9JMFXyuendXo/N2/NxSQsbx4pc3v2rv/eGJYaY7Nx/y -2M/vdWYkpG59PAS3k2TrCA/0SGmyVqY+c8BomKisU5VaBlIPfGuec9tDPgWCp8Ur -3Jjt/2sVoa0vMkqymUqMb9HyH9tdI9oyh7EOOrplAoGAR6DlNNUMgVy11K/Rcqns -y5WJFMh/ykeXENwQfTNJoXkLZZ+UXVwhzYVTqxTJoZMBSi8TnecWnBzmNj+nqp/W - lvBZH+xlUDhB6jMgXUPOVJd2TTigz3vGdVKfdgQ33bGmugM4NWJuuacmDKyem2fQ - GptoGBmWeI24v3HnC/LC50ECgYAz0iN8hRnz0db+Xc9TgAJB997LDnszJuvxv9yZ - UWCvwiWtrKG6U7FLnd4J4STayPLOnoOgrsexETEP43rIwIdQCMysnTH3AmlLNlKC - mIMHksknsUX3JJaevVziTOBuJ+QV3S96ZgUKk5NZWYprQrLIC8AmXodr5NgVfS2h - 5i4QFQKBgFfbYHiMw5AAUQrBNkrAjLd1wIaO/6qS3w4OsCWKowhfaJLEXAbIRV7s -vAtgtlCovdasVj4RRLXFf+73naVTQjBZI+3jWHHyFk3+Zy86mQCSGv9WuDVV1IhS -h8InTVvK8wgdgX7qiw3pvU0roqNW4/j4j8OqJO3Zt4KO2iX8htsO ------END RSA PRIVATE KEY----- diff --git a/spring-cloud-context/src/test/resources/external-properties/bootstrap.properties b/spring-cloud-context/src/test/resources/external-properties/bootstrap.properties deleted file mode 100644 index ad04aa1c..00000000 --- a/spring-cloud-context/src/test/resources/external-properties/bootstrap.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.main.sources:org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.PropertySourceConfiguration -info.name:externalPropertiesInfoName diff --git a/spring-cloud-context/src/test/resources/local.properties b/spring-cloud-context/src/test/resources/local.properties deleted file mode 100644 index 34f56a4c..00000000 --- a/spring-cloud-context/src/test/resources/local.properties +++ /dev/null @@ -1 +0,0 @@ -spring.profiles.active:local diff --git a/spring-cloud-context/src/test/resources/messages.properties b/spring-cloud-context/src/test/resources/messages.properties deleted file mode 100644 index ce7bbd5e..00000000 --- a/spring-cloud-context/src/test/resources/messages.properties +++ /dev/null @@ -1 +0,0 @@ -hello.message=Hello World! diff --git a/spring-cloud-context/src/test/resources/nonenumerable.properties b/spring-cloud-context/src/test/resources/nonenumerable.properties deleted file mode 100644 index ffc4f272..00000000 --- a/spring-cloud-context/src/test/resources/nonenumerable.properties +++ /dev/null @@ -1 +0,0 @@ -spring.main.sources:org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.PropertySourceConfiguration,org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.SimplePropertySourceConfiguration diff --git a/spring-cloud-context/src/test/resources/ordering.properties b/spring-cloud-context/src/test/resources/ordering.properties deleted file mode 100644 index 7ace5026..00000000 --- a/spring-cloud-context/src/test/resources/ordering.properties +++ /dev/null @@ -1 +0,0 @@ -spring.main.sources:org.springframework.cloud.bootstrap.BootstrapOrderingCustomOverrideSystemPropertiesIntegrationTests.PropertySourceConfiguration diff --git a/spring-cloud-context/src/test/resources/other.properties b/spring-cloud-context/src/test/resources/other.properties deleted file mode 100644 index 0c4bb2a0..00000000 --- a/spring-cloud-context/src/test/resources/other.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name:main diff --git a/spring-cloud-context/src/test/resources/plain.properties b/spring-cloud-context/src/test/resources/plain.properties deleted file mode 100644 index 132334be..00000000 --- a/spring-cloud-context/src/test/resources/plain.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name:app diff --git a/spring-cloud-context/src/test/resources/server.jks b/spring-cloud-context/src/test/resources/server.jks deleted file mode 100644 index 560be5fed77efd4c75d2ca49a33bc6eb616b1af4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2239 zcmchY`8yPh7RP7C%rIjJLzY)zELn=NhDi1$y_4*e8X9X^Cu0pmj2Ow9$i74&`!?Ci zOPb7;C2J95j2C4a*OIP!?tPy3FStLPA3o>#{&1e}InVbTtsSia007W&0e=_lZYUlX zg!jRP9(ODO>AD#J00fLCLI7xPC|m&w1Ow$kyg(oX049Q0e@x9;9QG?AIP}u(CND%g zNL5^8ki_Z1zB6X`UVR^kr^@)Za%CW-5U~S{(x=E5SHze8uy8g$xVXbqb9SqI-=~O@ zDZ-raMhb2A?eA;^2tpvt&n0=Tv~MNkS+5cI%2ij=N0R1?xp!A9C1<%SwZ8R?wlAsRHE9}}VzAy?cNnNwj3mGJ ztO-#a(awjYi`pB4QZ3Sa>N48Czr(&Q=D8EzCsp2oRlI1!@Jy_}uMmM35Rjvce76Rn{sAPO-#KSC6*SKdCs(y+|98led18K-}~uxm*ZA&V^CZTUPC=1H?jjd$lM3^4l7AqAr-bX7jb``=cD5 zIMw4W+r|afp*>WF;-%HTL*$lgBv>W;L8@p+@?Kk>K6P2+eo?#rDto48>|$m{!Mv~| zZTB|eUT&A*oNw=a){D@F+($ge__?FdLyRjz*lRDez{=JYg4t z?T~Nt7#sXK7fcsAcfuQGw6HUwEVz3Mz5@Lwa*Hl=t%Lmw?4Z9v8jwg8nK}#Sqj)?@ z+BHxVUHV)dfenu1h-K@``b@EO8Sw3V_&_T`&^p}|BI4Vx{pNX5ssPQYGTg0~$E>ZZ zxZ>hl6L&y&)hn3)$)D@C!aF_SboqQait#%U_4yu{^2MAuH>-}q#;M{-yd1sEc}}h! z!#R{Sd)}9cwF7759L{M(#|V;PRF~2@PreCz|3njzoAGE%6!otuPeTYZZ^g%Z#3eRn zfshtdY)|?AhZHX!nd2(_w=WHNxPONdAds*OoAny-|6E(ZSi8K@(5{zd?hjA#*fa0A5i#N z%rmW5VdEX0hc-bhk02~eAijXoC+$e9-XlfzUF})OwsJnHR0sF zfatDpl0ix+$9?M5TCe{>$N+shXTFzo#jerT+q%)Oc~h}D?gBV^5n;FCWxdgBw&;N7 zN{wjk`x>K^_Es|RoSRFxBcx{L(Kp#025&_laa2I;_fiG}I zpoS4qhz7VB4~TLti;qdy^LItOQ4{U3yu8ra=~pg66Esfh%l#1~{PL5Y`|o&!I4G*4 zwEzIN05p;9E}96kEo1`$K_Kvn{YyP)E+|Ys-YkBX3kc*q4onYaPBaY4W($TQLAKV) z+-Srv;6OsG@mM@gnG4PNi`kK2Loa-&vH%+S3*krvCeQ=x>lKE@d-?hPPsND@+xmLp zm62%PUn({v+#csDZjB2J#s#8J3vwx|qgBybDk^9VRb{8&sDVEJU;O_KLIk4zX~OZB zU?T!g0MJAr97F^H0j<}O_wE`aZ!*0iCzaqH1hqf0+fr9?67F{Ebpew?$mhB&83hK4 zbBl&033s?#ah`4>B<<81CH3DC00DJZ)gi+s=F+}Lxi@H@0y83l;?Cqd`eXQ#9@lj+ z*#y&cb7JoMR$hRii5{jpak1L`W0@XCEZzJ8f+a?)$YvmD!kR3%;Q7;6H~C=qL9xcN zE25LR2KygI@^3lUo~-IaK@~>Y$IDilLxP+&>l4NrZp_yWTXyE$WaCT@$hiIBImvxD zhhd8Uq1WXUQzT+lYPkC>XO}>?TQ5vITGGgjB1B6T{_EE0gL2hVwBV}8_iuk9*`Z*d znazx?DX@+`hz$q;mPnw*(5H^Kc#0c*63j1Km`l&8nC&gig1yvy+y)X=VB!C1;_)RN zn+OCro@z?g7#s%qHRrwC^N|V3zjS?-I9tyi;S%$8bY$=6&e`}fp~OZ z|EKLrH4p2BRMUw)`_g&D+e3dF>4S>M{md%)*Au18*)bhS+QV7_<))PO@Rl^c)wbtG z4`Se;rC}V&=!-~igc?GjgpvaLkU=Y6o=rx%ZUo5@86BYt%_zS7>8*CS==nH7KCXF7 z&o@r*mXjiJChyy>&-+zlxc9rzJuA5g3ev~OryKWVMcd_O(`6AD4W$M$SEiOftl^v?Ht^0YZuAWk}0Qx X87oqp`%q!o8#z_2ZOluhie~)>Rnq1* diff --git a/spring-cloud-context/src/test/resources/server.p12 b/spring-cloud-context/src/test/resources/server.p12 deleted file mode 100644 index 9f3153ac1030381cddb12da8aded5f499164e9c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2421 zcmY+Ec{mh`8pdZ~82i42FqTeYjHSu0QNt*ElPzKtvdm=55@VSprAdZD$yO-)F45Q- zhZ_5G$=E_vhGdAi?tSh(_ntq#?|q)%`+e`9FMy2ORY|}kuy}zSz+4hk zij4#nKf=NY68p`+S?um?BzBi0?07U-2={-!c({O|ToT(Jg2cu`oP==w7axU7v5CMT z=NkuwPsptZnizGaDdXg(dt5+ZK!*(*iH!!u1NmlFwcBo^>w9@ZEqdIBQRZk?^bq|0 z#*E{0X0+n93HM?fVa6XXzpfJWujECnl~ayy(HrNKg`R$Ix%w~xe!T)pQE)nGI!Bxf z{0F8ACv;!+&JP;K0WL#Xi>2V$?c$ zyJlqlIClB?+0tWij0d}!QqD52@& zrqGy>vst!f)ocY43uu=c#Qt!pFJ=^%va|K}0~`X=NX<~M>)-n3+;t!4)5UzPce3Li zd!6A}x=;Xm6o2Ih%&Yqq0XA4d5qWAFtoe4Tj|{&@eKABR5v%4X{@UBoH#2ny^_X<| zoDD_2Ej+($vU-#1kK$NxoP%xp1|+;^2@8JrFQGG*sC}CuQ8zZ#L80ZF<+U$qk@1%W zPd*OpBRVE~qFrs@3}>pM?|Yhub-!%A3#WA+`ss-YHgtas4e@FT0(=|}e@0ThgjzZ+}s30fg<6!Iiu^ zZ$720t5q4<6nlt_yiBqo+ieLxn4l?FIfh*tK&3`Fsm4|IUZ`V)7*tVRP%c{9+eHN2~}Oe>tV0?Ylv!F_jF z=9lv7g%5Se_ru9~=)u<)ZwEL((K1LjZA>*%PBMRYu_ zZk@1WX_i)09hD4!=Gbf!0Bk@$Wy`Ld%kFl)H*ezRTcrNI{Gcwp`CE;%q4-E^P)k*M ztZkKwtt^SIwHxmLb=^OL#a{;+H$~m*q4)&W_@|%fx#D=$$w)gif z6Rg8R*tu12WAXQ_YT~$Dr#B<$O>6ncZp!%%BjFi-XFls3ao>*7!W(h*{UwI@N=qM! zU`ftvYVksk5c3?wjm4E9)uFjr+cZ&Fk-!TDO{Y)jwX58GB#8eg7ZmU1@b2c|`FBAR z>#-VA9&W4lqeV6JC|zw{SBA7P>GB6}2hlkGB0^Xq9;B2{-A|Hb_%Q5pcdn=+3+^N? z95;Bq{-n*N{_Lx)N{Hq`u>6i%*Gfb9$FEzDe^wUXF$O}U-yJy|D^5i4IRV$rnyr$| zV`7rns4-Lo{S%YcR(FeWa_HWR@G)M!LI6A<0uTc51Oy*#zax$K{}WLS5jG*L58hKw1F5Nr(A7a|Yaz9f z2ogB!uN)3YE(uINLia&Hz>$#t=K%lKvygxFtfRD&sGYwzcDk2AtxwIdYso=YN~kW;zM%k4qUa7517^UZ|km|-(5 zrIx#)qa1I?!bKUVbmn9GVl{bV3TIDpVEagWiF(A~GtLmtQZtz%`RFi=KyK=+*Uf5+ zWy2Sh)Fiey7;?mZ(NLT8B5y-5})YvXfU*Nt-2;AhSRX>^xWyRXn~(u zGAHxM_aZ8|uP+Q(cb@s>HnskM{z;rd20Vn5{N&b~EQOPF4)cE>@W#+~nkRxCspQREQFZ^Z~0H4UGZJ(z6jRa{2w41agc*VOsF#KNd%%<<>ZDrkKVof$iYM)j0R({3q8e31Wc=pmxNekMw z{Gr(AsiJPVxMVx2cPG0UAN6*7LrSc6Nyd)m>L>#p1Kl*=^FqKR0#@&OoU6b5X3&LG zQh99>m74QNi1z- z1D9!DovWCJt8gY_DT;$Y$3;j-R3=*Mg^2*%HS;V1JtrbxZ|VOuIQ+E>_706L%d7jx zXhFNQ3!z-_QqEg7^bIpnr9(@mKYlU;M+_w!>GNt^7ETYn?r*6p zr5ILqZCm`J#>{um8doZ&gw>pxO)fsxx7aQUU7GrRNJXw080(lCINX+EVw - - 4.0.0 - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - spring-cloud-loadbalancer - jar - Spring Cloud Load Balancer - Spring Cloud Balancer - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.cloud - spring-cloud-context - - - org.springframework.boot - spring-boot-starter-actuator - true - - - - org.apache.logging.log4j - log4j-to-slf4j - - - - - io.projectreactor - reactor-core - - - io.projectreactor.addons - reactor-extra - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-webflux - true - - - org.springframework.boot - spring-boot-starter-cache - true - - - com.github.ben-manes.caffeine - caffeine - true - - - com.stoyanr - evictor - ${evictor.version} - true - - - org.springframework.retry - spring-retry - true - - - javax.annotation - javax.annotation-api - - - - - - io.micrometer - micrometer-core - true - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.boot - spring-boot-starter-web - test - - - org.springframework.cloud - spring-cloud-test-support - test - - - io.projectreactor - reactor-test - test - - - org.springframework - spring-core-test - test - - - org.awaitility - awaitility - test - - - org.junit.platform - junit-platform-launcher - test - - - diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClient.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClient.java deleted file mode 100644 index 4dd581ee..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClient.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.annotation; - -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.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.annotation.AliasFor; - -/** - * Declarative configuration for a load balancer client. Add this annotation to any - * @Configuration and then inject a {@link LoadBalancerClientFactory} to - * access the client that is created. - * - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@Import(LoadBalancerClientConfigurationRegistrar.class) -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface LoadBalancerClient { - - /** - * Synonym for name (the name of the client). - * - * @see #name() - * @return the name of the load balancer client - */ - @AliasFor("name") - String value() default ""; - - /** - * The name of the load balancer client, uniquely identifying a set of client - * resources, including a load balancer. - * @return the name of the load balancer client - */ - @AliasFor("value") - String name() default ""; - - /** - * A custom @Configuration for the load balancer client. Can contain - * override @Bean definition for the pieces that make up the client. - * - * @see LoadBalancerClientConfiguration for the defaults - * @return configuration classes for the load balancer client. - */ - Class[] configuration() default {}; - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java deleted file mode 100644 index f0aae50c..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfiguration.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.annotation; - -import reactor.util.retry.RetrySpec; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -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.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled; -import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; -import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; -import org.springframework.cloud.loadbalancer.core.RetryAwareServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer; -import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.XForwardedHeadersTransformer; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.cloud.loadbalancer.support.LoadBalancerEnvironmentPropertyUtils; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.core.annotation.Order; -import org.springframework.core.env.Environment; -import org.springframework.core.type.AnnotatedTypeMetadata; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Tim Ysewyn - * @author BaoLin Zhu - * @author changjin wei(魏昌进) - * @author Zhuozhi Ji - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnDiscoveryEnabled -public class LoadBalancerClientConfiguration { - - private static final int REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER = 193827465; - - @Bean - @ConditionalOnMissingBean - public ReactorLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, - LoadBalancerClientFactory loadBalancerClientFactory) { - String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); - return new RoundRobinLoadBalancer( - loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnReactiveDiscoveryEnabled - @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER) - public static class ReactiveSupportConfiguration { - - @Bean - @ConditionalOnBean(ReactiveDiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(DefaultConfigurationCondition.class) - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().build(context); - } - - @Bean - @ConditionalOnBean(ReactiveDiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(ZonePreferenceConfigurationCondition.class) - public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().withZonePreference() - .build(context); - } - - @Bean - @ConditionalOnBean(LoadBalancerClientFactory.class) - @ConditionalOnMissingBean - public XForwardedHeadersTransformer xForwarderHeadersTransformer(LoadBalancerClientFactory clientFactory) { - return new XForwardedHeadersTransformer(clientFactory); - } - - @Bean - @ConditionalOnBean({ ReactiveDiscoveryClient.class, WebClient.Builder.class }) - @ConditionalOnMissingBean - @Conditional(HealthCheckConfigurationCondition.class) - public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withDiscoveryClient().withHealthChecks().build(context); - } - - @Bean - @ConditionalOnBean(ReactiveDiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(RequestBasedStickySessionConfigurationCondition.class) - public ServiceInstanceListSupplier requestBasedStickySessionDiscoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching() - .withRequestBasedStickySession().build(context); - } - - @Bean - @ConditionalOnBean(ReactiveDiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(SameInstancePreferenceConfigurationCondition.class) - public ServiceInstanceListSupplier sameInstancePreferenceServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching() - .withSameInstancePreference().build(context); - } - - @Bean - @ConditionalOnBean(ReactiveDiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(WeightedConfigurationCondition.class) - public ServiceInstanceListSupplier weightedServiceInstanceListSupplier(ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withDiscoveryClient().withCaching().withWeighted() - .build(context); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnBlockingDiscoveryEnabled - @Order(REACTIVE_SERVICE_INSTANCE_SUPPLIER_ORDER + 1) - public static class BlockingSupportConfiguration { - - @Bean - @ConditionalOnBean(DiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(DefaultConfigurationCondition.class) - public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching().build(context); - } - - @Bean - @ConditionalOnBean(DiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(ZonePreferenceConfigurationCondition.class) - public ServiceInstanceListSupplier zonePreferenceDiscoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching() - .withZonePreference().build(context); - } - - @Bean - @ConditionalOnBean({ DiscoveryClient.class, RestTemplate.class }) - @ConditionalOnMissingBean - @Conditional(HealthCheckConfigurationCondition.class) - public ServiceInstanceListSupplier healthCheckDiscoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withBlockingHealthChecks() - .build(context); - } - - @Bean - @ConditionalOnBean(DiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(RequestBasedStickySessionConfigurationCondition.class) - public ServiceInstanceListSupplier requestBasedStickySessionDiscoveryClientServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching() - .withRequestBasedStickySession().build(context); - } - - @Bean - @ConditionalOnBean(DiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(SameInstancePreferenceConfigurationCondition.class) - public ServiceInstanceListSupplier sameInstancePreferenceServiceInstanceListSupplier( - ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching() - .withSameInstancePreference().build(context); - } - - @Bean - @ConditionalOnBean(DiscoveryClient.class) - @ConditionalOnMissingBean - @Conditional(WeightedConfigurationCondition.class) - public ServiceInstanceListSupplier weightedServiceInstanceListSupplier(ConfigurableApplicationContext context) { - return ServiceInstanceListSupplier.builder().withBlockingDiscoveryClient().withCaching().withWeighted() - .build(context); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnBlockingDiscoveryEnabled - @ConditionalOnClass(RetryTemplate.class) - @Conditional(BlockingOnAvoidPreviousInstanceAndRetryEnabledCondition.class) - @AutoConfigureAfter(BlockingSupportConfiguration.class) - @ConditionalOnBean(ServiceInstanceListSupplier.class) - public static class BlockingRetryConfiguration { - - @Bean - @ConditionalOnBean(DiscoveryClient.class) - @Primary - public ServiceInstanceListSupplier retryAwareDiscoveryClientServiceInstanceListSupplier( - ServiceInstanceListSupplier delegate) { - return new RetryAwareServiceInstanceListSupplier(delegate); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnReactiveDiscoveryEnabled - @Conditional(ReactiveOnAvoidPreviousInstanceAndRetryEnabledCondition.class) - @AutoConfigureAfter(ReactiveSupportConfiguration.class) - @ConditionalOnBean(ServiceInstanceListSupplier.class) - @ConditionalOnClass(RetrySpec.class) - public static class ReactiveRetryConfiguration { - - @Bean - @ConditionalOnBean(DiscoveryClient.class) - @Primary - public ServiceInstanceListSupplier retryAwareDiscoveryClientServiceInstanceListSupplier( - ServiceInstanceListSupplier delegate) { - return new RetryAwareServiceInstanceListSupplier(delegate); - } - - } - - static final class BlockingOnAvoidPreviousInstanceAndRetryEnabledCondition extends AllNestedConditions { - - private BlockingOnAvoidPreviousInstanceAndRetryEnabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true", - matchIfMissing = true) - static class LoadBalancerRetryEnabled { - - } - - @Conditional(AvoidPreviousInstanceEnabledCondition.class) - static class AvoidPreviousInstanceEnabled { - - } - - } - - static final class ReactiveOnAvoidPreviousInstanceAndRetryEnabledCondition extends AllNestedConditions { - - private ReactiveOnAvoidPreviousInstanceAndRetryEnabledCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnProperty(value = "spring.cloud.loadbalancer.retry.enabled", havingValue = "true") - static class LoadBalancerRetryEnabled { - - } - - @Conditional(AvoidPreviousInstanceEnabledCondition.class) - static class AvoidPreviousInstanceEnabled { - - } - - } - - static class AvoidPreviousInstanceEnabledCondition implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return LoadBalancerEnvironmentPropertyUtils.trueOrMissingForClientOrDefault(context.getEnvironment(), - "retry.avoid-previous-instance"); - } - - } - - static class DefaultConfigurationCondition implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return LoadBalancerEnvironmentPropertyUtils.equalToOrMissingForClientOrDefault(context.getEnvironment(), - "configurations", "default"); - } - - } - - static class ZonePreferenceConfigurationCondition implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(context.getEnvironment(), - "configurations", "zone-preference"); - } - - } - - static class HealthCheckConfigurationCondition implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(context.getEnvironment(), - "configurations", "health-check"); - } - - } - - static class RequestBasedStickySessionConfigurationCondition implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(context.getEnvironment(), - "configurations", "request-based-sticky-session"); - } - - } - - static class SameInstancePreferenceConfigurationCondition implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(context.getEnvironment(), - "configurations", "same-instance-preference"); - } - - } - - static class WeightedConfigurationCondition implements Condition { - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(context.getEnvironment(), - "configurations", "weighted"); - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationRegistrar.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationRegistrar.java deleted file mode 100644 index a109b398..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationRegistrar.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.annotation; - -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 LoadBalancerClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar { - - private static 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 @LoadBalancerClient"); - } - - private static void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, - Object configuration) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder - .genericBeanDefinition(LoadBalancerClientSpecification.class); - builder.addConstructorArgValue(name); - builder.addConstructorArgValue(configuration); - registry.registerBeanDefinition(name + ".LoadBalancerClientSpecification", builder.getBeanDefinition()); - } - - @Override - public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { - Map attrs = metadata.getAnnotationAttributes(LoadBalancerClients.class.getName()); - 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(LoadBalancerClient.class.getName()); - String name = getClientName(client); - if (name != null) { - registerClientConfiguration(registry, name, client.get("configuration")); - } - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientSpecification.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientSpecification.java deleted file mode 100644 index 8ffff712..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientSpecification.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.annotation; - -import java.util.Arrays; -import java.util.Objects; - -import org.springframework.cloud.context.named.NamedContextFactory; -import org.springframework.core.style.ToStringCreator; -import org.springframework.util.Assert; - -/** - * @author Dave Syer - */ -public class LoadBalancerClientSpecification implements NamedContextFactory.Specification { - - private String name; - - private Class[] configuration; - - public LoadBalancerClientSpecification() { - } - - public LoadBalancerClientSpecification(String name, Class[] configuration) { - Assert.hasText(name, "name must not be empty"); - this.name = name; - Assert.notNull(configuration, "configuration must not be null"); - this.configuration = configuration; - } - - @Override - public String getName() { - return this.name; - } - - public void setName(String name) { - Assert.hasText(name, "name must not be empty"); - this.name = name; - } - - @Override - public Class[] getConfiguration() { - return this.configuration; - } - - public void setConfiguration(Class[] configuration) { - Assert.notNull(configuration, "configuration must not be null"); - this.configuration = configuration; - } - - @Override - public String toString() { - ToStringCreator to = new ToStringCreator(this); - to.append("name", this.name); - to.append("configuration", this.configuration); - return to.toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LoadBalancerClientSpecification that = (LoadBalancerClientSpecification) o; - return Objects.equals(this.name, that.name) && Arrays.equals(this.configuration, that.configuration); - } - - @Override - public int hashCode() { - return Objects.hash(this.name, Arrays.hashCode(this.configuration)); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClients.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClients.java deleted file mode 100644 index eeaac9a9..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClients.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.annotation; - -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.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Convenience annotation that allows user to combine multiple - * @LoadBalancerClient annotations on a single class (including in Java 7). - * - * @author Dave Syer - */ -@Configuration(proxyBeanMethods = false) -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE }) -@Documented -@Import(LoadBalancerClientConfigurationRegistrar.class) -public @interface LoadBalancerClients { - - LoadBalancerClient[] value() default {}; - - /** - * {@link LoadBalancerClientConfigurationRegistrar} creates a - * {@link LoadBalancerClientSpecification} with this as an argument. These in turn are - * added as default contexts in {@link LoadBalancerClientFactory}. Configuration - * defined in these classes are used as defaults if values aren't defined via - * {@link LoadBalancerClient#configuration()} - * @return classes for default configurations - */ - Class[] defaultConfiguration() default {}; - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializer.java deleted file mode 100644 index fdc9c039..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializer.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.aot; - -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.lang.model.element.Modifier; - -import org.springframework.aot.generate.GeneratedMethod; -import org.springframework.aot.generate.GenerationContext; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.aot.BeanRegistrationAotContribution; -import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor; -import org.springframework.beans.factory.aot.BeanRegistrationCode; -import org.springframework.beans.factory.support.RegisteredBean; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientSpecification; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.aot.ApplicationContextAotGenerator; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.javapoet.ClassName; -import org.springframework.util.Assert; - -/** - * A {@link BeanRegistrationAotProcessor} that creates an - * {@link BeanRegistrationAotContribution} for LoadBalancer child contexts. - * - * @author Olga Maciaszek-Sharma - */ -public class LoadBalancerChildContextInitializer implements BeanRegistrationAotProcessor { - - private final ApplicationContext applicationContext; - - private final LoadBalancerClientFactory loadBalancerClientFactory; - - public LoadBalancerChildContextInitializer(LoadBalancerClientFactory loadBalancerClientFactory, - ApplicationContext applicationContext) { - this.loadBalancerClientFactory = loadBalancerClientFactory; - this.applicationContext = applicationContext; - } - - @Override - public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) { - Assert.isInstanceOf(ConfigurableApplicationContext.class, applicationContext); - ConfigurableApplicationContext context = ((ConfigurableApplicationContext) applicationContext); - BeanFactory applicationBeanFactory = context.getBeanFactory(); - if (!(registeredBean.getBeanClass().equals(LoadBalancerClientFactory.class) - && registeredBean.getBeanFactory().equals(applicationBeanFactory))) { - return null; - } - Set contextIds = new HashSet<>(); - contextIds.addAll(getContextIdsFromConfig()); - contextIds.addAll(getEagerLoadContextIds()); - Map childContextAotContributions = contextIds.stream() - .map(contextId -> Map.entry(contextId, buildChildContext(contextId))) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - return new AotContribution(childContextAotContributions); - } - - private Set getContextIdsFromConfig() { - Map configurations = loadBalancerClientFactory.getConfigurations(); - return configurations.keySet().stream().filter(key -> !key.startsWith("default.")).collect(Collectors.toSet()); - } - - private Set getEagerLoadContextIds() { - return Binder.get(applicationContext.getEnvironment()) - .bind("spring.cloud.loadbalancer.eager-load.clients", Bindable.setOf(String.class)) - .orElse(Collections.emptySet()); - } - - private GenericApplicationContext buildChildContext(String contextId) { - GenericApplicationContext childContext = loadBalancerClientFactory.buildContext(contextId); - loadBalancerClientFactory.registerBeans(contextId, childContext); - return childContext; - } - - private static class AotContribution implements BeanRegistrationAotContribution { - - private final Map childContexts; - - AotContribution(Map childContexts) { - this.childContexts = childContexts.entrySet().stream().filter(entry -> entry.getValue() != null) - .map(entry -> Map.entry(entry.getKey(), entry.getValue())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - } - - @Override - public void applyTo(GenerationContext generationContext, BeanRegistrationCode beanRegistrationCode) { - Map generatedInitializerClassNames = childContexts.entrySet().stream().map(entry -> { - String name = entry.getValue().getDisplayName(); - name = name.replaceAll("[-]", "_"); - GenerationContext childGenerationContext = generationContext.withName(name); - ClassName initializerClassName = new ApplicationContextAotGenerator() - .processAheadOfTime(entry.getValue(), childGenerationContext); - return Map.entry(entry.getKey(), initializerClassName); - }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); - GeneratedMethod postProcessorMethod = beanRegistrationCode.getMethods().add("addChildContextInitializer", - method -> { - method.addJavadoc("Use AOT child context management initialization") - .addModifiers(Modifier.PRIVATE, Modifier.STATIC) - .addParameter(RegisteredBean.class, "registeredBean") - .addParameter(LoadBalancerClientFactory.class, "instance") - .returns(LoadBalancerClientFactory.class) - .addStatement("$T initializers = new $T<>()", Map.class, HashMap.class); - generatedInitializerClassNames.keySet() - .forEach(contextId -> method.addStatement("initializers.put($S, new $L())", contextId, - generatedInitializerClassNames.get(contextId))); - method.addStatement("return instance.withApplicationContextInitializers(initializers)"); - }); - beanRegistrationCode.addInstancePostProcessor(postProcessorMethod.toMethodReference()); - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java deleted file mode 100644 index 282a0f4a..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformer.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.blocking; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; - -/** - * To add X-Forwarded-Host and X-Forwarded-Proto Headers. - * - * @author Gandhimathi Velusamy - * @author Olga Maciaszek-Sharma - * @author junjie shen(沈俊杰) - * @since 3.1.0 - */ - -public class XForwardedHeadersTransformer implements LoadBalancerRequestTransformer { - - private final ReactiveLoadBalancer.Factory factory; - - public XForwardedHeadersTransformer(ReactiveLoadBalancer.Factory factory) { - this.factory = factory; - } - - @Override - public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) { - if (instance == null) { - return request; - } - LoadBalancerProperties.XForwarded xForwarded = factory.getProperties(instance.getServiceId()).getXForwarded(); - if (xForwarded.isEnabled()) { - HttpHeaders headers = request.getHeaders(); - String xForwardedHost = request.getURI().getHost(); - String xForwardedProto = request.getURI().getScheme(); - headers.add("X-Forwarded-Host", xForwardedHost); - headers.add("X-Forwarded-Proto", xForwardedProto); - } - return request; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClient.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClient.java deleted file mode 100644 index c490a46d..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClient.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.blocking.client; - -import java.io.IOException; -import java.net.URI; -import java.util.Set; - -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.HttpRequestLoadBalancerRequest; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycleValidator; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestAdapter; -import org.springframework.cloud.client.loadbalancer.LoadBalancerUriTools; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.cloud.client.loadbalancer.TimedRequestContext; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.util.ReflectionUtils; - -import static org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer.REQUEST; - -/** - * The default {@link LoadBalancerClient} implementation. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class BlockingLoadBalancerClient implements LoadBalancerClient { - - private final ReactiveLoadBalancer.Factory loadBalancerClientFactory; - - public BlockingLoadBalancerClient(ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - this.loadBalancerClientFactory = loadBalancerClientFactory; - } - - @Override - public T execute(String serviceId, LoadBalancerRequest request) throws IOException { - String hint = getHint(serviceId); - LoadBalancerRequestAdapter lbRequest = new LoadBalancerRequestAdapter<>(request, - buildRequestContext(request, hint)); - Set supportedLifecycleProcessors = getSupportedLifecycleProcessors(serviceId); - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest)); - ServiceInstance serviceInstance = choose(serviceId, lbRequest); - if (serviceInstance == null) { - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, new EmptyResponse()))); - throw new IllegalStateException("No instances available for " + serviceId); - } - return execute(serviceId, serviceInstance, lbRequest); - } - - private TimedRequestContext buildRequestContext(LoadBalancerRequest delegate, String hint) { - if (delegate instanceof HttpRequestLoadBalancerRequest) { - HttpRequest request = ((HttpRequestLoadBalancerRequest) delegate).getHttpRequest(); - if (request != null) { - RequestData requestData = new RequestData(request); - return new RequestDataContext(requestData, hint); - } - } - return new DefaultRequestContext(delegate, hint); - } - - @Override - public T execute(String serviceId, ServiceInstance serviceInstance, LoadBalancerRequest request) - throws IOException { - if (serviceInstance == null) { - throw new IllegalArgumentException("Service Instance cannot be null"); - } - DefaultResponse defaultResponse = new DefaultResponse(serviceInstance); - Set supportedLifecycleProcessors = getSupportedLifecycleProcessors(serviceId); - Request lbRequest = request instanceof Request ? (Request) request : new DefaultRequest<>(); - supportedLifecycleProcessors - .forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, new DefaultResponse(serviceInstance))); - try { - T response = request.apply(serviceInstance); - Object clientResponse = getClientResponse(response); - supportedLifecycleProcessors - .forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, - lbRequest, defaultResponse, clientResponse))); - return response; - } - catch (IOException iOException) { - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.FAILED, iOException, lbRequest, defaultResponse))); - throw iOException; - } - catch (Exception exception) { - supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbRequest, defaultResponse))); - ReflectionUtils.rethrowRuntimeException(exception); - } - return null; - } - - private Object getClientResponse(T response) { - ClientHttpResponse clientHttpResponse = null; - if (response instanceof ClientHttpResponse) { - clientHttpResponse = (ClientHttpResponse) response; - } - if (clientHttpResponse != null) { - try { - return new ResponseData(clientHttpResponse, null); - } - catch (IOException ignored) { - } - } - return response; - } - - private Set getSupportedLifecycleProcessors(String serviceId) { - return LoadBalancerLifecycleValidator.getSupportedLifecycleProcessors( - loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class), - DefaultRequestContext.class, Object.class, ServiceInstance.class); - } - - @Override - public URI reconstructURI(ServiceInstance serviceInstance, URI original) { - return LoadBalancerUriTools.reconstructURI(serviceInstance, original); - } - - @Override - public ServiceInstance choose(String serviceId) { - return choose(serviceId, REQUEST); - } - - @Override - public ServiceInstance choose(String serviceId, Request request) { - ReactiveLoadBalancer loadBalancer = loadBalancerClientFactory.getInstance(serviceId); - if (loadBalancer == null) { - return null; - } - Response loadBalancerResponse = Mono.from(loadBalancer.choose(request)).block(); - if (loadBalancerResponse == null) { - return null; - } - return loadBalancerResponse.getServer(); - } - - private String getHint(String serviceId) { - LoadBalancerProperties properties = loadBalancerClientFactory.getProperties(serviceId); - String defaultHint = properties.getHint().getOrDefault("default", "default"); - String hintPropertyValue = properties.getHint().get(serviceId); - return hintPropertyValue != null ? hintPropertyValue : defaultHint; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryFactory.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryFactory.java deleted file mode 100644 index 6a8bc07c..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.blocking.retry; - -import org.springframework.cloud.client.ServiceInstance; -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.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; - -/** - * An implementation of {@link LoadBalancedRetryFactory} for - * {@link BlockingLoadBalancerClient}. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.6 - */ -public class BlockingLoadBalancedRetryFactory implements LoadBalancedRetryFactory { - - private final ReactiveLoadBalancer.Factory loadBalancerFactory; - - public BlockingLoadBalancedRetryFactory(ReactiveLoadBalancer.Factory loadBalancerFactory) { - this.loadBalancerFactory = loadBalancerFactory; - } - - @Override - public LoadBalancedRetryPolicy createRetryPolicy(String serviceId, ServiceInstanceChooser serviceInstanceChooser) { - return new BlockingLoadBalancedRetryPolicy(loadBalancerFactory.getProperties(serviceId)); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicy.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicy.java deleted file mode 100644 index fc97c720..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicy.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.blocking.retry; - -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; -import org.springframework.http.HttpMethod; - -/** - * A {@link LoadBalancedRetryPolicy} implementation for - * {@link BlockingLoadBalancerClient}. Based on RibbonLoadBalancedRetryPolicy - * to achieve feature-parity. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.6 - */ -public class BlockingLoadBalancedRetryPolicy implements LoadBalancedRetryPolicy { - - private final LoadBalancerProperties properties; - - private int sameServerCount = 0; - - private int nextServerCount = 0; - - public BlockingLoadBalancedRetryPolicy(LoadBalancerProperties properties) { - this.properties = properties; - } - - public boolean canRetry(LoadBalancedRetryContext context) { - HttpMethod method = context.getRequest().getMethod(); - return HttpMethod.GET.equals(method) || properties.getRetry().isRetryOnAllOperations(); - } - - @Override - public boolean canRetrySameServer(LoadBalancedRetryContext context) { - return sameServerCount < properties.getRetry().getMaxRetriesOnSameServiceInstance() && canRetry(context); - } - - @Override - public boolean canRetryNextServer(LoadBalancedRetryContext context) { - // After the failure, we increment first and then check, hence the equality check - return nextServerCount <= properties.getRetry().getMaxRetriesOnNextServiceInstance() && canRetry(context); - } - - @Override - public void close(LoadBalancedRetryContext context) { - - } - - @Override - public void registerThrowable(LoadBalancedRetryContext context, Throwable throwable) { - if (!canRetrySameServer(context) && canRetry(context)) { - // Reset same server since we are moving to a new ServiceInstance - sameServerCount = 0; - nextServerCount++; - if (!canRetryNextServer(context)) { - context.setExhaustedOnly(); - } - else { - // We want the service instance to be set by - // `RetryLoadBalancerInterceptor` - // in order to get the entire data of the request - context.setServiceInstance(null); - } - } - else { - sameServerCount++; - } - } - - @Override - public boolean retryableStatusCode(int statusCode) { - return properties.getRetry().getRetryableStatusCodes().contains(statusCode); - } - - @Override - public boolean retryableException(Throwable throwable) { - if (throwable == null) { - return true; - } - if (properties.getRetry().isRetryOnAllExceptions()) { - return true; - } - return properties.getRetry().getRetryableExceptions().stream() - .anyMatch(exception -> exception.isInstance(throwable) || exception.isInstance(throwable.getCause())); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/CaffeineBasedLoadBalancerCacheManager.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/CaffeineBasedLoadBalancerCacheManager.java deleted file mode 100644 index 67a0269f..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/CaffeineBasedLoadBalancerCacheManager.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.cache; - -import com.github.benmanes.caffeine.cache.Caffeine; - -import org.springframework.cache.caffeine.CaffeineCacheManager; -import org.springframework.util.StringUtils; - -import static org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME; - -/** - * A Spring Cloud LoadBalancer specific implementation of {@link CaffeineCacheManager} - * that implements the {@link LoadBalancerCacheManager} marker interface. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - * @see Evictor - * @see ConcurrentMapWithTimedEviction - * @see ConcurrentMapCache - */ -public class DefaultLoadBalancerCache extends AbstractValueAdaptingCache { - - private final String name; - - private final ConcurrentMapWithTimedEviction cache; - - private final long evictMs; - - DefaultLoadBalancerCache(String name, ConcurrentMapWithTimedEviction cache, long evictMs, - boolean allowNullValues) { - super(allowNullValues); - Assert.notNull(name, "Name must not be null"); - Assert.notNull(cache, "Cache must not be null"); - this.name = name; - this.cache = cache; - this.evictMs = evictMs; - } - - /** - * Create a new DefaultCache with the specified name. - * @param name the name of the cache - */ - public DefaultLoadBalancerCache(String name) { - this(name, new ConcurrentHashMapWithTimedEviction<>(256, new DelayedTaskEvictionScheduler<>()), 0, true); - } - - /** - * Create a new DefaultCache with the specified name. - * @param name the name of the cache - * @param evictMs default time to evict the entries - * {@link ConcurrentMapWithTimedEviction} - * @param allowNullValues whether to accept and convert {@code null} values for this - * cache - */ - public DefaultLoadBalancerCache(String name, long evictMs, boolean allowNullValues) { - this(name, new ConcurrentHashMapWithTimedEviction<>(256, new DelayedTaskEvictionScheduler<>()), evictMs, - allowNullValues); - } - - /** - * Create a new EvictorCache with the specified name. - * @param name the name of the cache - * @param allowNullValues whether to accept and convert {@code null} values for this - * cache - */ - public DefaultLoadBalancerCache(String name, boolean allowNullValues) { - this(name, new ConcurrentHashMapWithTimedEviction<>(256, new DelayedTaskEvictionScheduler<>()), 0, - allowNullValues); - } - - @Override - protected Object lookup(Object key) { - return cache.get(key); - } - - @Override - public String getName() { - return name; - } - - @Override - public ConcurrentMap getNativeCache() { - return cache; - } - - @SuppressWarnings("unchecked") - @Override - @Nullable - public T get(Object key, Callable valueLoader) { - return (T) fromStoreValue(cache.computeIfAbsent(key, k -> { - try { - return toStoreValue(valueLoader.call()); - } - catch (Throwable ex) { - throw new ValueRetrievalException(key, valueLoader, ex); - } - })); - } - - public void put(Object key, @Nullable Object value, long evictMs) { - cache.put(key, toStoreValue(value), evictMs); - } - - @Override - @Nullable - public ValueWrapper putIfAbsent(Object key, @Nullable Object value) { - Object existing = cache.putIfAbsent(key, toStoreValue(value), evictMs); - return toValueWrapper(existing); - } - - @Nullable - public ValueWrapper putIfAbsent(Object key, @Nullable Object value, long evictMs) { - Object existing = cache.putIfAbsent(key, toStoreValue(value), evictMs); - return toValueWrapper(existing); - } - - @Override - public void put(Object key, @Nullable Object value) { - cache.put(key, toStoreValue(value), evictMs); - } - - @Override - public void evict(Object key) { - cache.remove(key); - } - - @Override - public boolean evictIfPresent(Object key) { - return (cache.remove(key) != null); - } - - @Override - public void clear() { - cache.clear(); - } - - @Override - public boolean invalidate() { - boolean notEmpty = !cache.isEmpty(); - cache.clear(); - return notEmpty; - } - - // Visible for tests - long getEvictMs() { - return evictMs; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManager.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManager.java deleted file mode 100644 index 79333918..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManager.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.cache; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.stream.Collectors; - -import com.stoyanr.evictor.map.ConcurrentHashMapWithTimedEviction; -import com.stoyanr.evictor.scheduler.DelayedTaskEvictionScheduler; - -import org.springframework.cache.Cache; -import org.springframework.lang.Nullable; - -import static org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME; - -/** - * An {@link DefaultLoadBalancerCache}-based {@link LoadBalancerCacheManager} - * implementation. - * - * NOTE: This is a very basic implementation as required for the LoadBalancer caching - * mechanism at the moment. The underlying implementation can be modified in future to - * allow for passing different properties per cache name. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - * @see Evictor - * @see ConcurrentHashMapWithTimedEviction - */ -public class DefaultLoadBalancerCacheManager implements LoadBalancerCacheManager { - - private final ConcurrentMap cacheMap = new ConcurrentHashMap<>(16); - - public DefaultLoadBalancerCacheManager(LoadBalancerCacheProperties loadBalancerCacheProperties, - String... cacheNames) { - cacheMap.putAll(createCaches(cacheNames, loadBalancerCacheProperties).stream() - .collect(Collectors.toMap(DefaultLoadBalancerCache::getName, cache -> cache))); - } - - public DefaultLoadBalancerCacheManager(LoadBalancerCacheProperties loadBalancerCacheProperties) { - this(loadBalancerCacheProperties, SERVICE_INSTANCE_CACHE_NAME); - } - - private Set createCaches(String[] cacheNames, - LoadBalancerCacheProperties loadBalancerCacheProperties) { - return Arrays.stream(cacheNames).distinct() - .map(name -> new DefaultLoadBalancerCache(name, - new ConcurrentHashMapWithTimedEviction<>(loadBalancerCacheProperties.getCapacity(), - new DelayedTaskEvictionScheduler<>(aScheduledDaemonThreadExecutor())), - loadBalancerCacheProperties.getTtl().toMillis(), false)) - .collect(Collectors.toSet()); - } - - private ScheduledExecutorService aScheduledDaemonThreadExecutor() { - return Executors.newSingleThreadScheduledExecutor(runnable -> { - Thread thread = Executors.defaultThreadFactory().newThread(runnable); - thread.setDaemon(true); - return thread; - }); - } - - @Override - @Nullable - public Cache getCache(String name) { - return cacheMap.get(name); - } - - @Override - public Collection getCacheNames() { - return Collections.unmodifiableSet(cacheMap.keySet()); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheManager.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheManager.java deleted file mode 100644 index 12b5c807..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheManager.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.cache; - -import org.springframework.cache.CacheManager; - -/** - * A marker interface for Spring Cloud LoadBalancer-specific {@link CacheManager} beans. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -public interface LoadBalancerCacheManager extends CacheManager { - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheProperties.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheProperties.java deleted file mode 100644 index 426c9382..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/cache/LoadBalancerCacheProperties.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.cache; - -import java.time.Duration; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Spring Cloud LoadBalancer cache properties. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -@ConfigurationProperties("spring.cloud.loadbalancer.cache") -public class LoadBalancerCacheProperties { - - private Caffeine caffeine = new Caffeine(); - - /** - * Time To Live - time counted from writing of the record, after which cache entries - * are expired, expressed as a {@link Duration}. The property {@link String} has to be - * in keeping with the appropriate syntax as specified in Spring Boot - * StringToDurationConverter. - * @see StringToDurationConverter.java - */ - private Duration ttl = Duration.ofSeconds(35); - - /** - * Initial cache capacity expressed as int. - */ - private int capacity = 256; - - public Caffeine getCaffeine() { - return caffeine; - } - - public void setCaffeine(Caffeine caffeine) { - this.caffeine = caffeine; - } - - public Duration getTtl() { - return ttl; - } - - public void setTtl(Duration ttl) { - this.ttl = ttl; - } - - public int getCapacity() { - return capacity; - } - - public void setCapacity(int capacity) { - this.capacity = capacity; - } - - /** - * Caffeine-specific LoadBalancer cache properties. NOTE: Passing your own Caffeine - * specification will override any other LoadBalancerCache settings, including TTL. - */ - public static class Caffeine { - - /** - * The spec to use to create caches. See CaffeineSpec for more details on the spec - * format. - */ - private String spec = ""; - - public String getSpec() { - return spec; - } - - public void setSpec(String spec) { - this.spec = spec; - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java deleted file mode 100644 index bf7fe4ad..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfiguration.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.config; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -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.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; -import org.springframework.cloud.loadbalancer.blocking.XForwardedHeadersTransformer; -import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; -import org.springframework.cloud.loadbalancer.blocking.retry.BlockingLoadBalancedRetryFactory; -import org.springframework.cloud.loadbalancer.core.LoadBalancerServiceInstanceCookieTransformer; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.client.RestTemplate; - -/** - * An autoconfiguration for {@link BlockingLoadBalancerClient}. - * - * @author Olga Maciaszek-Sharma - * @author Gandhimathi Velusamy - * @since 2.1.3 - */ -@Configuration(proxyBeanMethods = false) -@LoadBalancerClients -@AutoConfigureAfter(LoadBalancerAutoConfiguration.class) -@AutoConfigureBefore({ org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration.class }) -@ConditionalOnClass(RestTemplate.class) -@ConditionalOnProperty(value = "spring.cloud.loadbalancer.enabled", havingValue = "true", matchIfMissing = true) -public class BlockingLoadBalancerClientAutoConfiguration { - - @Bean - @ConditionalOnBean(LoadBalancerClientFactory.class) - @ConditionalOnMissingBean - public LoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory) { - return new BlockingLoadBalancerClient(loadBalancerClientFactory); - } - - @Bean - @ConditionalOnBean(LoadBalancerClientFactory.class) - @ConditionalOnMissingBean(LoadBalancerServiceInstanceCookieTransformer.class) - public LoadBalancerServiceInstanceCookieTransformer loadBalancerServiceInstanceCookieTransformer( - LoadBalancerClientFactory loadBalancerClientFactory) { - return new LoadBalancerServiceInstanceCookieTransformer(loadBalancerClientFactory); - } - - @Bean - @ConditionalOnMissingBean(XForwardedHeadersTransformer.class) - @ConditionalOnBean(LoadBalancerClientFactory.class) - public XForwardedHeadersTransformer xForwarderHeadersTransformer( - LoadBalancerClientFactory loadBalancerClientFactory) { - return new XForwardedHeadersTransformer(loadBalancerClientFactory); - } - - @Configuration - @ConditionalOnClass(RetryTemplate.class) - @EnableConfigurationProperties(LoadBalancerClientsProperties.class) - protected static class BlockingLoadBalancerRetryConfig { - - @Bean - @ConditionalOnMissingBean - LoadBalancedRetryFactory loadBalancedRetryFactory( - ReactiveLoadBalancer.Factory loadBalancerFactory) { - return new BlockingLoadBalancedRetryFactory(loadBalancerFactory); - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerAutoConfiguration.java deleted file mode 100644 index 5d0bab62..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerAutoConfiguration.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.config; - -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -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.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerEagerLoadProperties; -import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerBeanPostProcessorAutoConfiguration; -import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerClientAutoConfiguration; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientSpecification; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; -import org.springframework.cloud.loadbalancer.aot.LoadBalancerChildContextInitializer; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.cloud.loadbalancer.support.LoadBalancerEagerContextInitializer; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; - -/** - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -@Configuration(proxyBeanMethods = false) -@LoadBalancerClients -@EnableConfigurationProperties({ LoadBalancerClientsProperties.class, LoadBalancerEagerLoadProperties.class }) -@AutoConfigureBefore({ ReactorLoadBalancerClientAutoConfiguration.class, - LoadBalancerBeanPostProcessorAutoConfiguration.class }) -@ConditionalOnProperty(value = "spring.cloud.loadbalancer.enabled", havingValue = "true", matchIfMissing = true) -public class LoadBalancerAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public LoadBalancerZoneConfig zoneConfig(Environment environment) { - return new LoadBalancerZoneConfig(environment.getProperty("spring.cloud.loadbalancer.zone")); - } - - @ConditionalOnMissingBean - @Bean - public LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties, - ObjectProvider> configurations) { - LoadBalancerClientFactory clientFactory = new LoadBalancerClientFactory(properties); - clientFactory.setConfigurations(configurations.getIfAvailable(Collections::emptyList)); - return clientFactory; - } - - @Bean - public LoadBalancerEagerContextInitializer loadBalancerEagerContextInitializer( - LoadBalancerClientFactory clientFactory, LoadBalancerEagerLoadProperties properties) { - return new LoadBalancerEagerContextInitializer(clientFactory, properties.getClients()); - } - - @Bean - static LoadBalancerChildContextInitializer loadBalancerChildContextInitializer( - LoadBalancerClientFactory loadBalancerClientFactory, ApplicationContext parentContext) { - return new LoadBalancerChildContextInitializer(loadBalancerClientFactory, parentContext); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java deleted file mode 100644 index 639ec345..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfiguration.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.config; - -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - -import com.github.benmanes.caffeine.cache.Caffeine; -import com.stoyanr.evictor.ConcurrentMapWithTimedEviction; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; -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.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cache.CacheManager; -import org.springframework.cache.caffeine.CaffeineCacheManager; -import org.springframework.cache.interceptor.CacheAspectSupport; -import org.springframework.cloud.loadbalancer.cache.CaffeineBasedLoadBalancerCacheManager; -import org.springframework.cloud.loadbalancer.cache.DefaultLoadBalancerCacheManager; -import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; -import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.filter.AssignableTypeFilter; -import org.springframework.util.ClassUtils; - -/** - * An AutoConfiguration that automatically enables caching when Spring Boot, and Spring - * Framework Cache support are present. If Caffeine is present in the classpath, it will - * be used for loadbalancer caching. If not, a default cache will be used. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - * @see CacheManager - * @see CacheAutoConfiguration - * @see CacheAspectSupport - * @see hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, - MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .registerType(TypeReference.of("com.github.benmanes.caffeine.cache.BoundedLocalCache"), - hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, - MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .registerType(TypeReference.of("com.github.benmanes.caffeine.cache.LocalCacheFactory"), - hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, - MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)) - .registerType(TypeReference.of("com.github.benmanes.caffeine.cache.Node"), - hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, - MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS)); - getCaffeineSubtypes().forEach(cacheType -> hints.reflection().registerType(TypeReference.of(cacheType), - hint -> hint.withMembers(MemberCategory.INVOKE_DECLARED_METHODS, - MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.DECLARED_FIELDS))); - } - - private Set getCaffeineSubtypes() { - ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); - try { - provider.addIncludeFilter(new AssignableTypeFilter(Class.forName(CAFFEINE_BOUNDED_LOCAL_CACHE_CLASS_NAME))); - provider.addIncludeFilter(new AssignableTypeFilter(Class.forName(CAFFEINE_NODE_CLASS_NAME))); - } - catch (ClassNotFoundException e) { - LOG.warn("Could not get class for name: " + CAFFEINE_BOUNDED_LOCAL_CACHE_CLASS_NAME); - } - return provider.findCandidateComponents(CAFFEINE_CACHE_BASE_PACKAGE).stream().filter(Objects::nonNull) - .map(BeanDefinition::getBeanClassName).filter(Objects::nonNull).collect(Collectors.toSet()); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java deleted file mode 100644 index 1e609284..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.config; - -import io.micrometer.core.instrument.MeterRegistry; - -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.loadbalancer.stats.MicrometerStatsLoadBalancerLifecycle; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Autoconfiguration that provides a {@link MicrometerStatsLoadBalancerLifecycle} bean. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(MeterRegistry.class) -@ConditionalOnProperty(value = "spring.cloud.loadbalancer.stats.micrometer.enabled", havingValue = "true") -public class LoadBalancerStatsAutoConfiguration { - - @Bean - @ConditionalOnBean(MeterRegistry.class) - public MicrometerStatsLoadBalancerLifecycle micrometerStatsLifecycle(MeterRegistry meterRegistry) { - return new MicrometerStatsLoadBalancerLifecycle(meterRegistry); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerZoneConfig.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerZoneConfig.java deleted file mode 100644 index 9809b4d1..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerZoneConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.config; - -/** - * @author Olga Maciaszek-Sharma - */ -public class LoadBalancerZoneConfig { - - /** - * A {@link String} representation of the zone used for filtering - * instances by zoned load-balancing implementations. - */ - private String zone; - - public LoadBalancerZoneConfig(String zone) { - this.zone = zone; - } - - public String getZone() { - return zone; - } - - public void setZone(String zone) { - this.zone = zone; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplier.java deleted file mode 100644 index 2554f766..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplier.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.cache.CacheFlux; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.cache.Cache; -import org.springframework.cache.CacheManager; -import org.springframework.cloud.client.ServiceInstance; - -/** - * A {@link ServiceInstanceListSupplier} implementation that tries retrieving - * {@link ServiceInstance} objects from cache; if none found, retrieves instances using - * {@link DiscoveryClientServiceInstanceListSupplier}. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -public class CachingServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier { - - private static final Log log = LogFactory.getLog(CachingServiceInstanceListSupplier.class); - - /** - * Name of the service cache instance. - */ - public static final String SERVICE_INSTANCE_CACHE_NAME = CachingServiceInstanceListSupplier.class.getSimpleName() - + "Cache"; - - private final Flux> serviceInstances; - - @SuppressWarnings("unchecked") - public CachingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, CacheManager cacheManager) { - super(delegate); - this.serviceInstances = CacheFlux.lookup(key -> { - // TODO: configurable cache name - Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME); - if (cache == null) { - if (log.isErrorEnabled()) { - log.error("Unable to find cache: " + SERVICE_INSTANCE_CACHE_NAME); - } - return Mono.empty(); - } - List list = cache.get(key, List.class); - if (list == null || list.isEmpty()) { - return Mono.empty(); - } - return Flux.just(list).materialize().collectList(); - }, delegate.getServiceId()).onCacheMissResume(delegate.get().take(1)) - .andWriteWith((key, signals) -> Flux.fromIterable(signals).dematerialize().doOnNext(instances -> { - Cache cache = cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME); - if (cache == null) { - if (log.isErrorEnabled()) { - log.error("Unable to find cache for writing: " + SERVICE_INSTANCE_CACHE_NAME); - } - } - else { - cache.put(key, instances); - } - }).then()); - } - - @Override - public Flux> get() { - return serviceInstances; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DelegatingServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DelegatingServiceInstanceListSupplier.java deleted file mode 100644 index 42bf25fb..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DelegatingServiceInstanceListSupplier.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.util.Assert; - -/** - * Represents a {@link ServiceInstanceListSupplier} that uses a delegate - * {@link ServiceInstanceListSupplier} instance underneath. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Jürgen Kreitler - */ -public abstract class DelegatingServiceInstanceListSupplier - implements ServiceInstanceListSupplier, SelectedInstanceCallback, InitializingBean, DisposableBean { - - protected final ServiceInstanceListSupplier delegate; - - public DelegatingServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) { - Assert.notNull(delegate, "delegate may not be null"); - this.delegate = delegate; - } - - public ServiceInstanceListSupplier getDelegate() { - return delegate; - } - - @Override - public String getServiceId() { - return delegate.getServiceId(); - } - - @Override - public void selectedServiceInstance(ServiceInstance serviceInstance) { - if (delegate instanceof SelectedInstanceCallback selectedInstanceCallbackDelegate) { - selectedInstanceCallbackDelegate.selectedServiceInstance(serviceInstance); - } - } - - @Override - public void afterPropertiesSet() throws Exception { - if (delegate instanceof InitializingBean) { - ((InitializingBean) delegate).afterPropertiesSet(); - } - } - - @Override - public void destroy() throws Exception { - if (delegate instanceof DisposableBean) { - ((DisposableBean) delegate).destroy(); - } - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplier.java deleted file mode 100644 index e1f33998..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplier.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; - -import org.springframework.boot.convert.DurationStyle; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.core.env.Environment; - -import static org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory.PROPERTY_NAME; - -/** - * A discovery-client-based {@link ServiceInstanceListSupplier} implementation. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Tim Ysewyn - * @author Rod Catter - * @since 2.2.0 - */ -public class DiscoveryClientServiceInstanceListSupplier implements ServiceInstanceListSupplier { - - /** - * Property that establishes the timeout for calls to service discovery. - */ - public static final String SERVICE_DISCOVERY_TIMEOUT = "spring.cloud.loadbalancer.service-discovery.timeout"; - - private static final Log LOG = LogFactory.getLog(DiscoveryClientServiceInstanceListSupplier.class); - - private Duration timeout = Duration.ofSeconds(30); - - private final String serviceId; - - private final Flux> serviceInstances; - - public DiscoveryClientServiceInstanceListSupplier(DiscoveryClient delegate, Environment environment) { - this.serviceId = environment.getProperty(PROPERTY_NAME); - resolveTimeout(environment); - this.serviceInstances = Flux.defer(() -> Mono.fromCallable(() -> delegate.getInstances(serviceId))) - .timeout(timeout, Flux.defer(() -> { - logTimeout(); - return Flux.just(new ArrayList<>()); - }), Schedulers.boundedElastic()).onErrorResume(error -> { - logException(error); - return Flux.just(new ArrayList<>()); - }); - } - - public DiscoveryClientServiceInstanceListSupplier(ReactiveDiscoveryClient delegate, Environment environment) { - this.serviceId = environment.getProperty(PROPERTY_NAME); - resolveTimeout(environment); - this.serviceInstances = Flux - .defer(() -> delegate.getInstances(serviceId).collectList().flux().timeout(timeout, Flux.defer(() -> { - logTimeout(); - return Flux.just(new ArrayList<>()); - })).onErrorResume(error -> { - logException(error); - return Flux.just(new ArrayList<>()); - })); - } - - @Override - public String getServiceId() { - return serviceId; - } - - @Override - public Flux> get() { - return serviceInstances; - } - - private void resolveTimeout(Environment environment) { - String providedTimeout = environment.getProperty(SERVICE_DISCOVERY_TIMEOUT); - if (providedTimeout != null) { - timeout = DurationStyle.detectAndParse(providedTimeout); - } - } - - private void logTimeout() { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Timeout occurred while retrieving instances for service %s." - + "The instances could not be retrieved during %s", serviceId, timeout)); - } - } - - private void logException(Throwable error) { - if (LOG.isErrorEnabled()) { - LOG.error(String.format("Exception occurred while retrieving instances for service %s", serviceId), error); - } - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java deleted file mode 100644 index a3e57c00..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplier.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.retry.Repeat; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.util.StringUtils; - -/** - * A {@link ServiceInstanceListSupplier} implementation that verifies whether the - * instances are alive and only returns the healthy one, unless there are none. Uses a - * user-provided function to ping the health endpoint of the instances. - * - * @author Olga Maciaszek-Sharma - * @author Roman Matiushchenko - * @author Roman Chigvintsev - * @since 2.2.0 - */ -public class HealthCheckServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier - implements InitializingBean, DisposableBean { - - private static final Log LOG = LogFactory.getLog(HealthCheckServiceInstanceListSupplier.class); - - private final LoadBalancerProperties.HealthCheck healthCheck; - - private final String defaultHealthCheckPath; - - private final Flux> aliveInstancesReplay; - - private Disposable healthCheckDisposable; - - private final BiFunction> aliveFunction; - - public HealthCheckServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - ReactiveLoadBalancer.Factory loadBalancerClientFactory, - BiFunction> aliveFunction) { - super(delegate); - this.healthCheck = loadBalancerClientFactory.getProperties(getServiceId()).getHealthCheck(); - defaultHealthCheckPath = healthCheck.getPath().getOrDefault("default", "/actuator/health"); - this.aliveFunction = aliveFunction; - Repeat aliveInstancesReplayRepeat = Repeat - .onlyIf(repeatContext -> this.healthCheck.getRefetchInstances()) - .fixedBackoff(healthCheck.getRefetchInstancesInterval()); - Flux> aliveInstancesFlux = Flux.defer(delegate).repeatWhen(aliveInstancesReplayRepeat) - .switchMap(serviceInstances -> healthCheckFlux(serviceInstances).map(alive -> List.copyOf(alive))); - aliveInstancesReplay = aliveInstancesFlux.delaySubscription(healthCheck.getInitialDelay()).replay(1) - .refCount(1); - } - - @Override - public void afterPropertiesSet() { - Disposable healthCheckDisposable = this.healthCheckDisposable; - if (healthCheckDisposable != null) { - healthCheckDisposable.dispose(); - } - this.healthCheckDisposable = aliveInstancesReplay.subscribe(); - } - - protected Flux> healthCheckFlux(List instances) { - Repeat healthCheckFluxRepeat = Repeat.onlyIf(repeatContext -> healthCheck.getRepeatHealthCheck()) - .fixedBackoff(healthCheck.getInterval()); - return Flux.defer(() -> { - List> checks = new ArrayList<>(instances.size()); - for (ServiceInstance instance : instances) { - Mono alive = isAlive(instance).onErrorResume(error -> { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format( - "Exception occurred during health check of the instance for service %s: %s", - instance.getServiceId(), instance.getUri()), error); - } - return Mono.empty(); - }).timeout(healthCheck.getInterval(), Mono.defer(() -> { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format( - "The instance for service %s: %s did not respond for %s during health check", - instance.getServiceId(), instance.getUri(), healthCheck.getInterval())); - } - return Mono.empty(); - })).handle((isHealthy, sink) -> { - if (isHealthy) { - sink.next(instance); - } - }); - - checks.add(alive); - } - List result = new ArrayList<>(); - if (healthCheck.isUpdateResultsList()) { - return Flux.merge(checks).map(alive -> { - result.add(alive); - return result; - }).defaultIfEmpty(result); - } - return Flux.merge(checks).collectList(); - }).repeatWhen(healthCheckFluxRepeat); - } - - @Override - public Flux> get() { - return aliveInstancesReplay; - } - - protected Mono isAlive(ServiceInstance serviceInstance) { - boolean containsService = healthCheck.getPath().containsKey(serviceInstance.getServiceId()); - String healthCheckPropertyValue = healthCheck.getPath().get(serviceInstance.getServiceId()); - if (containsService && !StringUtils.hasText(healthCheckPropertyValue)) { - return Mono.just(true); - } - String healthCheckPath = healthCheckPropertyValue != null ? healthCheckPropertyValue : defaultHealthCheckPath; - return aliveFunction.apply(updatedServiceInstance(serviceInstance), healthCheckPath); - } - - @Override - public void destroy() { - Disposable healthCheckDisposable = this.healthCheckDisposable; - if (healthCheckDisposable != null) { - healthCheckDisposable.dispose(); - } - } - - private ServiceInstance updatedServiceInstance(ServiceInstance serviceInstance) { - Integer healthCheckPort = healthCheck.getPort(); - if (serviceInstance instanceof DefaultServiceInstance && healthCheckPort != null) { - return new DefaultServiceInstance(serviceInstance.getInstanceId(), serviceInstance.getServiceId(), - serviceInstance.getHost(), healthCheckPort, serviceInstance.isSecure(), - serviceInstance.getMetadata()); - } - return serviceInstance; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplier.java deleted file mode 100644 index c8a8ab2b..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplier.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.ArrayList; -import java.util.List; - -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.HintRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpHeaders; -import org.springframework.util.StringUtils; - -/** - * A {@link ServiceInstanceListSupplier} implementation that uses hints to filter service - * instances provided by the delegate. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.2 - */ -public class HintBasedServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier { - - private final LoadBalancerProperties properties; - - public HintBasedServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - ReactiveLoadBalancer.Factory factory) { - super(delegate); - this.properties = factory.getProperties(getServiceId()); - } - - @Override - public Flux> get() { - return delegate.get(); - } - - @Override - public Flux> get(Request request) { - return delegate.get(request).map(instances -> filteredByHint(instances, getHint(request.getContext()))); - } - - private String getHint(Object requestContext) { - if (requestContext == null) { - return null; - } - String hint = null; - if (requestContext instanceof RequestDataContext) { - hint = getHintFromHeader((RequestDataContext) requestContext); - } - if (!StringUtils.hasText(hint) && requestContext instanceof HintRequestContext) { - hint = ((HintRequestContext) requestContext).getHint(); - } - return hint; - } - - private String getHintFromHeader(RequestDataContext context) { - if (context.getClientRequest() != null) { - HttpHeaders headers = context.getClientRequest().getHeaders(); - if (headers != null) { - return headers.getFirst(properties.getHintHeaderName()); - } - } - return null; - } - - private List filteredByHint(List instances, String hint) { - if (!StringUtils.hasText(hint)) { - return instances; - } - List filteredInstances = new ArrayList<>(); - for (ServiceInstance serviceInstance : instances) { - if (serviceInstance.getMetadata().getOrDefault("hint", "").equals(hint)) { - filteredInstances.add(serviceInstance); - } - } - if (filteredInstances.size() > 0) { - return filteredInstances; - } - - // If instances cannot be found based on hint, - // we return all instances retrieved for given service id. - return instances; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceList.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceList.java deleted file mode 100644 index 6a21b856..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceList.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.AbstractList; -import java.util.ArrayDeque; -import java.util.List; -import java.util.Queue; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * A {@link List} implementation that lazily fills weighted {@link ServiceInstance} - * objects. - * - * @author Zhuozhi Ji - * @see WeightedServiceInstanceListSupplier - */ -class LazyWeightedServiceInstanceList extends AbstractList { - - /* for testing */ final ServiceInstance[] expanded; - - private final Object expandingLock = new Object(); - - private WeightedServiceInstanceSelector selector; - - private volatile int position = 0; - - LazyWeightedServiceInstanceList(List instances, int[] weights) { - // Calculate the greatest common divisor (GCD) of weights, and the - // total number of elements after expansion. - int greatestCommonDivisor = 0; - int total = 0; - for (int weight : weights) { - greatestCommonDivisor = greatestCommonDivisor(greatestCommonDivisor, weight); - total += weight; - } - expanded = new ServiceInstance[total / greatestCommonDivisor]; - selector = new WeightedServiceInstanceSelector(instances, weights, greatestCommonDivisor); - } - - @Override - public ServiceInstance get(int index) { - if (index >= position) { - synchronized (expandingLock) { - for (; position <= index && position < expanded.length; position++) { - expanded[position] = selector.next(); - } - if (position == expanded.length) { - selector = null; // for gc - } - } - } - return expanded[index]; - } - - @Override - public int size() { - return expanded.length; - } - - static int greatestCommonDivisor(int a, int b) { - int r; - while (b != 0) { - r = a % b; - a = b; - b = r; - } - return a; - } - - static class WeightedServiceInstanceSelector { - - Queue active; - - Queue expired; - - WeightedServiceInstanceSelector(List instances, int[] weights, int greatestCommonDivisor) { - active = new ArrayDeque<>(instances.size()); - expired = new ArrayDeque<>(instances.size()); - // Use iterator for some implementation of the List that not supports - // RandomAccess, but `weights` is supported, so use a local variable `i` - // to get the current position. - int i = 0; - for (ServiceInstance instance : instances) { - active.offer(new Entry(instance, weights[i] / greatestCommonDivisor)); - i++; - } - } - - ServiceInstance next() { - if (active.isEmpty()) { - Queue temp = active; - active = expired; - expired = temp; - } - - Entry entry = active.poll(); - if (entry == null) { - // Suppress warnings, never touched! - return null; - } - - entry.remainder--; - if (entry.remainder == 0) { - entry.remainder = entry.weight; - expired.offer(entry); - } - else { - active.offer(entry); - } - return entry.instance; - } - - static class Entry { - - final ServiceInstance instance; - - final int weight; - - int remainder; - - Entry(ServiceInstance instance, int weight) { - this.instance = instance; - this.weight = weight; - remainder = weight; - } - - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformer.java deleted file mode 100644 index 0582089a..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformer.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.ArrayList; -import java.util.List; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequestTransformer; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpCookie; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; -import org.springframework.util.StringUtils; - -/** - * A {@link LoadBalancerRequestTransformer} that allows passing the {@code} instanceId) of - * the {@link ServiceInstance} selected by the {@link LoadBalancerClient} in a cookie. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.2 - */ -public class LoadBalancerServiceInstanceCookieTransformer implements LoadBalancerRequestTransformer { - - private ReactiveLoadBalancer.Factory factory; - - public LoadBalancerServiceInstanceCookieTransformer(ReactiveLoadBalancer.Factory factory) { - this.factory = factory; - } - - @Override - public HttpRequest transformRequest(HttpRequest request, ServiceInstance instance) { - if (instance == null) { - return request; - } - LoadBalancerProperties.StickySession stickySession = factory != null - ? factory.getProperties(instance.getServiceId()).getStickySession() - : new LoadBalancerProperties.StickySession(); - if (!stickySession.isAddServiceInstanceCookie()) { - return request; - } - String instanceIdCookieName = stickySession.getInstanceIdCookieName(); - if (!StringUtils.hasText(instanceIdCookieName)) { - return request; - } - HttpHeaders headers = request.getHeaders(); - List cookieHeaders = new ArrayList<>(request.getHeaders().getOrEmpty(HttpHeaders.COOKIE)); - String serviceInstanceCookie = new HttpCookie(instanceIdCookieName, instance.getInstanceId()).toString(); - cookieHeaders.add(serviceInstanceCookie); - headers.put(HttpHeaders.COOKIE, cookieHeaders); - return request; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/NoopServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/NoopServiceInstanceListSupplier.java deleted file mode 100644 index fd69bede..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/NoopServiceInstanceListSupplier.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Collections; -import java.util.List; - -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Request; - -/** - * A no-op implementation of {@link ServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - */ -public class NoopServiceInstanceListSupplier implements ServiceInstanceListSupplier { - - @Override - public String getServiceId() { - return ""; - } - - @Override - public Flux> get() { - return Flux.defer(() -> Flux.just(Collections.emptyList())); - } - - @Override - public Flux> get(Request request) { - return Flux.defer(() -> Flux.just(Collections.emptyList())); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancer.java deleted file mode 100644 index 325fb17b..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancer.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.List; -import java.util.concurrent.ThreadLocalRandom; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; - -/** - * A random-based implementation of {@link ReactorServiceInstanceLoadBalancer}. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.7 - */ -public class RandomLoadBalancer implements ReactorServiceInstanceLoadBalancer { - - private static final Log log = LogFactory.getLog(RandomLoadBalancer.class); - - private final String serviceId; - - private ObjectProvider serviceInstanceListSupplierProvider; - - /** - * @param serviceInstanceListSupplierProvider a provider of - * {@link ServiceInstanceListSupplier} that will be used to get available instances - * @param serviceId id of the service for which to choose an instance - */ - public RandomLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider, - String serviceId) { - this.serviceId = serviceId; - this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider; - } - - @SuppressWarnings("rawtypes") - @Override - public Mono> choose(Request request) { - ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider - .getIfAvailable(NoopServiceInstanceListSupplier::new); - return supplier.get(request).next() - .map(serviceInstances -> processInstanceResponse(supplier, serviceInstances)); - } - - private Response processInstanceResponse(ServiceInstanceListSupplier supplier, - List serviceInstances) { - Response serviceInstanceResponse = getInstanceResponse(serviceInstances); - if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) { - ((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer()); - } - return serviceInstanceResponse; - } - - private Response getInstanceResponse(List instances) { - if (instances.isEmpty()) { - if (log.isWarnEnabled()) { - log.warn("No servers available for service: " + serviceId); - } - return new EmptyResponse(); - } - int index = ThreadLocalRandom.current().nextInt(instances.size()); - - ServiceInstance instance = instances.get(index); - - return new DefaultResponse(instance); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorLoadBalancer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorLoadBalancer.java deleted file mode 100644 index 6a54e07f..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorLoadBalancer.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; - -/** - * A Reactor based implementation of {@link ReactiveLoadBalancer}. - * - * @param - type of the response - * @author Spencer Gibb - */ -public interface ReactorLoadBalancer extends ReactiveLoadBalancer { - - /** - * Choose the next server based on the load balancing algorithm. - * @param request - an input request - * @return - mono of response - */ - @SuppressWarnings("rawtypes") - Mono> choose(Request request); - - default Mono> choose() { - return choose(REQUEST); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorServiceInstanceLoadBalancer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorServiceInstanceLoadBalancer.java deleted file mode 100644 index 08373531..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ReactorServiceInstanceLoadBalancer.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * A marker interface for {@link ReactorLoadBalancer} that allows selecting - * {@link ServiceInstance} objects. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -public interface ReactorServiceInstanceLoadBalancer extends ReactorLoadBalancer { - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplier.java deleted file mode 100644 index bcd1cd92..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplier.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Collections; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.util.MultiValueMap; - -/** - * A session cookie based implementation of {@link ServiceInstanceListSupplier} that gives - * preference to the instance with an id specified in a request cookie. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class RequestBasedStickySessionServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier { - - private static final Log LOG = LogFactory.getLog(RequestBasedStickySessionServiceInstanceListSupplier.class); - - private final LoadBalancerProperties properties; - - public RequestBasedStickySessionServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - super(delegate); - this.properties = loadBalancerClientFactory.getProperties(getServiceId()); - } - - @Override - public Flux> get() { - return delegate.get(); - } - - @SuppressWarnings("rawtypes") - @Override - public Flux> get(Request request) { - String instanceIdCookieName = properties.getStickySession().getInstanceIdCookieName(); - Object context = request.getContext(); - if ((context instanceof RequestDataContext)) { - MultiValueMap cookies = ((RequestDataContext) context).getClientRequest().getCookies(); - if (cookies == null) { - return delegate.get(request); - } - // We expect there to be one value in this cookie - String cookie = cookies.getFirst(instanceIdCookieName); - if (cookie != null) { - return delegate.get(request).map(serviceInstances -> selectInstance(serviceInstances, cookie)); - } - if (LOG.isDebugEnabled()) { - LOG.debug("Cookie not found. Returning all instances returned by delegate."); - } - return delegate.get(request); - } - // If the object type is not RequestData, we return all the instances provided by - // the delegate. - return delegate.get(request); - } - - private List selectInstance(List serviceInstances, String cookie) { - for (ServiceInstance serviceInstance : serviceInstances) { - if (cookie.equals(serviceInstance.getInstanceId())) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Returning the service instance: %s. Found for cookie: %s", serviceInstance, - cookie)); - } - return Collections.singletonList(serviceInstance); - } - } - // If the instances cannot be found based on the cookie, - // we return all the instances provided by the delegate. - if (LOG.isDebugEnabled()) { - LOG.debug(String.format( - "Service instance for cookie: %s not found. Returning all instances returned by delegate.", - cookie)); - } - return serviceInstances; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplier.java deleted file mode 100644 index 9991ebfe..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplier.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RetryableRequestContext; - -/** - * A {@link ServiceInstanceListSupplier} implementation that avoids picking the same - * service instance while retrying requests. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class RetryAwareServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier { - - private final Log LOG = LogFactory.getLog(RetryAwareServiceInstanceListSupplier.class); - - public RetryAwareServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) { - super(delegate); - } - - @Override - public String getServiceId() { - return delegate.getServiceId(); - } - - @Override - public Flux> get(Request request) { - if (!(request.getContext() instanceof RetryableRequestContext context)) { - return delegate.get(request); - } - ServiceInstance previousServiceInstance = context.getPreviousServiceInstance(); - if (previousServiceInstance == null) { - return delegate.get(request); - } - return delegate.get(request).map(instances -> filteredByPreviousInstance(instances, previousServiceInstance)); - } - - private List filteredByPreviousInstance(List instances, - ServiceInstance previousServiceInstance) { - List filteredInstances = new ArrayList<>(instances); - if (previousServiceInstance != null) { - filteredInstances.remove(previousServiceInstance); - } - if (filteredInstances.size() > 0) { - return filteredInstances; - } - if (LOG.isWarnEnabled()) { - LOG.warn(String.format( - "No instances found after removing previously used service instance from the search (%s). Returning all found instances.", - previousServiceInstance)); - } - return instances; - } - - @Override - public Flux> get() { - return delegate.get(); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancer.java deleted file mode 100644 index bc6cd5da..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancer.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; - -/** - * A Round-Robin-based implementation of {@link ReactorServiceInstanceLoadBalancer}. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Zhuozhi JI - */ -public class RoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer { - - private static final Log log = LogFactory.getLog(RoundRobinLoadBalancer.class); - - final AtomicInteger position; - - final String serviceId; - - ObjectProvider serviceInstanceListSupplierProvider; - - /** - * @param serviceInstanceListSupplierProvider a provider of - * {@link ServiceInstanceListSupplier} that will be used to get available instances - * @param serviceId id of the service for which to choose an instance - */ - public RoundRobinLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider, - String serviceId) { - this(serviceInstanceListSupplierProvider, serviceId, new Random().nextInt(1000)); - } - - /** - * @param serviceInstanceListSupplierProvider a provider of - * {@link ServiceInstanceListSupplier} that will be used to get available instances - * @param serviceId id of the service for which to choose an instance - * @param seedPosition Round Robin element position marker - */ - public RoundRobinLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider, - String serviceId, int seedPosition) { - this.serviceId = serviceId; - this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider; - this.position = new AtomicInteger(seedPosition); - } - - @SuppressWarnings("rawtypes") - @Override - // see original - // https://github.com/Netflix/ocelli/blob/master/ocelli-core/ - // src/main/java/netflix/ocelli/loadbalancer/RoundRobinLoadBalancer.java - public Mono> choose(Request request) { - ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider - .getIfAvailable(NoopServiceInstanceListSupplier::new); - return supplier.get(request).next() - .map(serviceInstances -> processInstanceResponse(supplier, serviceInstances)); - } - - private Response processInstanceResponse(ServiceInstanceListSupplier supplier, - List serviceInstances) { - Response serviceInstanceResponse = getInstanceResponse(serviceInstances); - if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) { - ((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer()); - } - return serviceInstanceResponse; - } - - private Response getInstanceResponse(List instances) { - if (instances.isEmpty()) { - if (log.isWarnEnabled()) { - log.warn("No servers available for service: " + serviceId); - } - return new EmptyResponse(); - } - - // Do not move position when there is only 1 instance, especially some suppliers - // have already filtered instances - if (instances.size() == 1) { - return new DefaultResponse(instances.get(0)); - } - - // Ignore the sign bit, this allows pos to loop sequentially from 0 to - // Integer.MAX_VALUE - int pos = this.position.incrementAndGet() & Integer.MAX_VALUE; - - ServiceInstance instance = instances.get(pos % instances.size()); - - return new DefaultResponse(instance); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplier.java deleted file mode 100644 index bd63ecbc..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplier.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Collections; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; - -/** - * An implementation of {@link ServiceInstanceListSupplier} that selects the previously - * chosen instance if it's available. - * - * @author Olga Maciaszek-Sharma - * @author Jürgen Kreitler - * @since 2.2.7 - */ -public class SameInstancePreferenceServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier - implements SelectedInstanceCallback { - - private static final Log LOG = LogFactory.getLog(SameInstancePreferenceServiceInstanceListSupplier.class); - - private ServiceInstance previouslyReturnedInstance; - - private boolean callGetWithRequestOnDelegates; - - public SameInstancePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) { - super(delegate); - } - - public SameInstancePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - super(delegate); - callGetWithRequestOnDelegates = loadBalancerClientFactory.getProperties(getServiceId()) - .isCallGetWithRequestOnDelegates(); - } - - @Override - public String getServiceId() { - return delegate.getServiceId(); - } - - @Override - public Flux> get() { - return delegate.get().map(this::filteredBySameInstancePreference); - } - - @Override - public Flux> get(Request request) { - if (callGetWithRequestOnDelegates) { - return delegate.get(request).map(this::filteredBySameInstancePreference); - } - return get(); - } - - private List filteredBySameInstancePreference(List serviceInstances) { - if (previouslyReturnedInstance != null && serviceInstances.contains(previouslyReturnedInstance)) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Returning previously selected service instance: %s", - previouslyReturnedInstance)); - } - return Collections.singletonList(previouslyReturnedInstance); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format( - "Previously selected service instance %s was not available. Returning all the instances returned by delegate.", - previouslyReturnedInstance)); - } - previouslyReturnedInstance = null; - return serviceInstances; - } - - @Override - public void selectedServiceInstance(ServiceInstance serviceInstance) { - super.selectedServiceInstance(serviceInstance); - if (previouslyReturnedInstance == null || !previouslyReturnedInstance.equals(serviceInstance)) { - previouslyReturnedInstance = serviceInstance; - } - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SelectedInstanceCallback.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SelectedInstanceCallback.java deleted file mode 100644 index c19f7d74..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/SelectedInstanceCallback.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * A callback interface that allows to pass the selected service instance data from the - * LoadBalancer. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.7 - */ -public interface SelectedInstanceCallback { - - /** - * Passes the selected {@link ServiceInstance} as an argument. - * @param serviceInstance that has been selected - */ - void selectedServiceInstance(ServiceInstance serviceInstance); - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java deleted file mode 100644 index b63df843..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplier.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.List; -import java.util.function.Supplier; - -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Request; - -/** - * A {@link Supplier} of lists of {@link ServiceInstance} objects. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.0 - */ -public interface ServiceInstanceListSupplier extends Supplier>> { - - String getServiceId(); - - default Flux> get(Request request) { - return get(); - } - - static ServiceInstanceListSupplierBuilder builder() { - return new ServiceInstanceListSupplierBuilder(); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java deleted file mode 100644 index 74ee2e38..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilder.java +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright 2013-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; -import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpStatus; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * A Builder for creating a {@link ServiceInstanceListSupplier} hierarchy to be used in - * {@link ReactorLoadBalancer} configuration. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Zhiguo Chen - * @author Sabyasachi Bhattacharya - * @author Zhuozhi Ji - */ -public final class ServiceInstanceListSupplierBuilder { - - private static final Log LOG = LogFactory.getLog(ServiceInstanceListSupplierBuilder.class); - - private Creator baseCreator; - - private final List creators = new ArrayList<>(); - - ServiceInstanceListSupplierBuilder() { - } - - /** - * Sets a blocking {@link DiscoveryClient}-based - * {@link DiscoveryClientServiceInstanceListSupplier} as a base - * {@link ServiceInstanceListSupplier} in the hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withBlockingDiscoveryClient() { - if (baseCreator != null && LOG.isWarnEnabled()) { - LOG.warn("Overriding a previously set baseCreator with a blocking DiscoveryClient baseCreator."); - } - this.baseCreator = context -> { - DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class); - - return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment()); - }; - return this; - } - - /** - * Sets a {@link ReactiveDiscoveryClient}-based - * {@link DiscoveryClientServiceInstanceListSupplier} as a base - * {@link ServiceInstanceListSupplier} in the hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withDiscoveryClient() { - if (baseCreator != null && LOG.isWarnEnabled()) { - LOG.warn("Overriding a previously set baseCreator with a ReactiveDiscoveryClient baseCreator."); - } - this.baseCreator = context -> { - ReactiveDiscoveryClient discoveryClient = context.getBean(ReactiveDiscoveryClient.class); - - return new DiscoveryClientServiceInstanceListSupplier(discoveryClient, context.getEnvironment()); - }; - return this; - } - - /** - * Sets a user-provided {@link ServiceInstanceListSupplier} as a base - * {@link ServiceInstanceListSupplier} in the hierarchy. - * @param supplier a user-provided {@link ServiceInstanceListSupplier} instance - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withBase(ServiceInstanceListSupplier supplier) { - this.baseCreator = context -> supplier; - return this; - } - - /** - * Adds a {@link WeightedServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withWeighted() { - DelegateCreator creator = (context, delegate) -> { - ReactiveLoadBalancer.Factory loadBalancerClientFactory = context - .getBean(LoadBalancerClientFactory.class); - return new WeightedServiceInstanceListSupplier(delegate, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link WeightedServiceInstanceListSupplier} that uses user-provided - * {@link WeightFunction} instance to the {@link ServiceInstanceListSupplier} - * hierarchy. - * @param weightFunction a user-provided {@link WeightFunction} instance - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withWeighted(WeightFunction weightFunction) { - DelegateCreator creator = (context, delegate) -> { - ReactiveLoadBalancer.Factory loadBalancerClientFactory = context - .getBean(LoadBalancerClientFactory.class); - return new WeightedServiceInstanceListSupplier(delegate, weightFunction, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link HealthCheckServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withHealthChecks() { - DelegateCreator creator = (context, delegate) -> { - ReactiveLoadBalancer.Factory loadBalancerClientFactory = context - .getBean(LoadBalancerClientFactory.class); - WebClient.Builder webClient = context.getBean(WebClient.Builder.class); - return healthCheckServiceInstanceListSupplier(webClient.build(), delegate, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link HealthCheckServiceInstanceListSupplier} that uses user-provided - * {@link WebClient} instance to the {@link ServiceInstanceListSupplier} hierarchy. - * @param webClient a user-provided {@link WebClient} instance - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withHealthChecks(WebClient webClient) { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class); - return healthCheckServiceInstanceListSupplier(webClient, delegate, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link SameInstancePreferenceServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withSameInstancePreference() { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class); - return new SameInstancePreferenceServiceInstanceListSupplier(delegate, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link HealthCheckServiceInstanceListSupplier} that uses user-provided - * {@link RestTemplate} instance to the {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withBlockingHealthChecks() { - DelegateCreator creator = (context, delegate) -> { - RestTemplate restTemplate = context.getBean(RestTemplate.class); - LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class); - return blockingHealthCheckServiceInstanceListSupplier(restTemplate, delegate, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link HealthCheckServiceInstanceListSupplier} that uses user-provided - * {@link RestTemplate} instance to the {@link ServiceInstanceListSupplier} hierarchy. - * @param restTemplate a user-provided {@link RestTemplate} instance - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withBlockingHealthChecks(RestTemplate restTemplate) { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class); - return blockingHealthCheckServiceInstanceListSupplier(restTemplate, delegate, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link ZonePreferenceServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withZonePreference() { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class); - LoadBalancerZoneConfig zoneConfig = context.getBean(LoadBalancerZoneConfig.class); - return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link ZonePreferenceServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @param zoneName desired zone for zone preference - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withZonePreference(String zoneName) { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class); - LoadBalancerZoneConfig zoneConfig = new LoadBalancerZoneConfig(zoneName); - return new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * Adds a {@link RequestBasedStickySessionServiceInstanceListSupplier} to the - * {@link ServiceInstanceListSupplier} hierarchy. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withRequestBasedStickySession() { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerClientFactory loadBalancerClientFactory = context.getBean(LoadBalancerClientFactory.class); - return new RequestBasedStickySessionServiceInstanceListSupplier(delegate, loadBalancerClientFactory); - }; - this.creators.add(creator); - return this; - } - - /** - * If {@link LoadBalancerCacheManager} is available in the context, adds a - * {@link CachingServiceInstanceListSupplier} instance to the - * {@link ServiceInstanceListSupplier} hierarchy to provide a caching mechanism for - * service instances. Uses {@link ObjectProvider} to lazily resolve - * {@link LoadBalancerCacheManager}. - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder withCaching() { - DelegateCreator creator = (context, delegate) -> { - ObjectProvider cacheManagerProvider = context - .getBeanProvider(LoadBalancerCacheManager.class); - if (cacheManagerProvider.getIfAvailable() != null) { - return new CachingServiceInstanceListSupplier(delegate, cacheManagerProvider.getIfAvailable()); - } - if (LOG.isWarnEnabled()) { - LOG.warn("LoadBalancerCacheManager not available, returning delegate without caching."); - } - return delegate; - }; - creators.add(creator); - return this; - } - - public ServiceInstanceListSupplierBuilder withRetryAwareness() { - DelegateCreator creator = (context, delegate) -> new RetryAwareServiceInstanceListSupplier(delegate); - creators.add(creator); - return this; - } - - public ServiceInstanceListSupplierBuilder withHints() { - DelegateCreator creator = (context, delegate) -> { - LoadBalancerClientFactory factory = context.getBean(LoadBalancerClientFactory.class); - return new HintBasedServiceInstanceListSupplier(delegate, factory); - }; - creators.add(creator); - return this; - } - - /** - * Support {@link ServiceInstanceListSupplierBuilder} can be added to the expansion - * implementation of {@link ServiceInstanceListSupplier} by this method. - * @param delegateCreator a {@link DelegateCreator} object - * @return the {@link ServiceInstanceListSupplierBuilder} object - */ - public ServiceInstanceListSupplierBuilder with(DelegateCreator delegateCreator) { - if (delegateCreator != null) { - creators.add(delegateCreator); - } - return this; - } - - /** - * Builds the {@link ServiceInstanceListSupplier} hierarchy. - * @param context application context - * @return a {@link ServiceInstanceListSupplier} instance on top of the delegate - * hierarchy - */ - public ServiceInstanceListSupplier build(ConfigurableApplicationContext context) { - Assert.notNull(baseCreator, "A baseCreator must not be null"); - - ServiceInstanceListSupplier supplier = baseCreator.apply(context); - - for (DelegateCreator creator : creators) { - supplier = creator.apply(context, supplier); - } - - return supplier; - } - - private ServiceInstanceListSupplier healthCheckServiceInstanceListSupplier(WebClient webClient, - ServiceInstanceListSupplier delegate, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - return new HealthCheckServiceInstanceListSupplier(delegate, loadBalancerClientFactory, - (serviceInstance, healthCheckPath) -> webClient.get() - .uri(UriComponentsBuilder.fromUriString(getUri(serviceInstance, healthCheckPath)).build() - .toUri()) - .exchange().flatMap(clientResponse -> clientResponse.releaseBody() - .thenReturn(HttpStatus.OK.equals(clientResponse.statusCode())))); - } - - private ServiceInstanceListSupplier blockingHealthCheckServiceInstanceListSupplier(RestTemplate restTemplate, - ServiceInstanceListSupplier delegate, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - return new HealthCheckServiceInstanceListSupplier(delegate, loadBalancerClientFactory, - (serviceInstance, healthCheckPath) -> Mono.defer(() -> { - URI uri = UriComponentsBuilder.fromUriString(getUri(serviceInstance, healthCheckPath)).build() - .toUri(); - try { - return Mono - .just(HttpStatus.OK.equals(restTemplate.getForEntity(uri, Void.class).getStatusCode())); - } - catch (Exception ignored) { - return Mono.just(false); - } - })); - } - - static String getUri(ServiceInstance serviceInstance, String healthCheckPath) { - if (StringUtils.hasText(healthCheckPath)) { - String path = healthCheckPath.startsWith("/") ? healthCheckPath : "/" + healthCheckPath; - return serviceInstance.getUri().toString() + path; - } - return serviceInstance.getUri().toString(); - } - - /** - * Allows creating a {@link ServiceInstanceListSupplier} instance based on provided - * {@link ConfigurableApplicationContext}. - */ - public interface Creator extends Function { - - } - - /** - * Allows creating a {@link ServiceInstanceListSupplier} instance based on provided - * {@link ConfigurableApplicationContext} and another - * {@link ServiceInstanceListSupplier} instance that will be used as a delegate. - */ - public interface DelegateCreator extends - BiFunction { - - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightFunction.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightFunction.java deleted file mode 100644 index 7e08a6a7..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightFunction.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * Represents a function that calculate the weight of the given service instance. - * - *

- * This is a functional interface whose functional method is - * {@link #apply(ServiceInstance)}. - * - * @author Zhuozhi Ji - * @see java.util.function.ToIntFunction - */ -@FunctionalInterface -public interface WeightFunction { - - /** - * Applies this function to the given service instance. - * @param instance the service instance - * @return the weight of service instance - */ - int apply(ServiceInstance instance); - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplier.java deleted file mode 100644 index 172038b5..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplier.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; - -/** - * A {@link ServiceInstanceListSupplier} implementation that uses weights to expand the - * instances provided by delegate. - * - * @author Zhuozhi Ji - * @author Olga Maciaszek-Sharma - */ -public class WeightedServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier { - - private static final Log LOG = LogFactory.getLog(WeightedServiceInstanceListSupplier.class); - - static final String METADATA_WEIGHT_KEY = "weight"; - - static final int DEFAULT_WEIGHT = 1; - - private final WeightFunction weightFunction; - - private boolean callGetWithRequestOnDelegates; - - public WeightedServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) { - this(delegate, WeightedServiceInstanceListSupplier::metadataWeightFunction); - } - - public WeightedServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, WeightFunction weightFunction) { - super(delegate); - this.weightFunction = weightFunction; - } - - public WeightedServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - this(delegate, WeightedServiceInstanceListSupplier::metadataWeightFunction, loadBalancerClientFactory); - } - - public WeightedServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, WeightFunction weightFunction, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - super(delegate); - this.weightFunction = weightFunction; - callGetWithRequestOnDelegates = loadBalancerClientFactory.getProperties(getServiceId()) - .isCallGetWithRequestOnDelegates(); - } - - @Override - public Flux> get() { - return delegate.get().map(this::expandByWeight); - } - - @Override - public Flux> get(Request request) { - if (callGetWithRequestOnDelegates) { - return delegate.get(request).map(this::expandByWeight); - } - return get(); - } - - private List expandByWeight(List instances) { - if (instances.size() == 0) { - return instances; - } - - int[] weights = instances.stream().mapToInt(instance -> { - try { - int weight = weightFunction.apply(instance); - if (weight <= 0) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format( - "The weight of the instance %s should be a positive integer, but it got %d, using %d as default", - instance.getInstanceId(), weight, DEFAULT_WEIGHT)); - } - return DEFAULT_WEIGHT; - } - return weight; - } - catch (Exception e) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format( - "Exception occurred during apply weight function to instance %s, using %d as default", - instance.getInstanceId(), DEFAULT_WEIGHT), e); - } - return DEFAULT_WEIGHT; - } - }).toArray(); - - return new LazyWeightedServiceInstanceList(instances, weights); - } - - static int metadataWeightFunction(ServiceInstance serviceInstance) { - Map metadata = serviceInstance.getMetadata(); - if (metadata != null) { - String weightValue = metadata.get(METADATA_WEIGHT_KEY); - if (weightValue != null) { - return Integer.parseInt(weightValue); - } - } - // using default weight when metadata is missing or - // weight is not specified - return DEFAULT_WEIGHT; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java deleted file mode 100644 index 0a41701b..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformer.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.reactive.LoadBalancerClientRequestTransformer; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.http.HttpHeaders; -import org.springframework.web.reactive.function.client.ClientRequest; - -/** - * To add X-Forwarded-Host and X-Forwarded-Proto Headers. - * - * @author Gandhimathi Velusamy - * @author Olga Maciaszek-Sharma - * @since 3.1.0 - */ - -public class XForwardedHeadersTransformer implements LoadBalancerClientRequestTransformer { - - private final ReactiveLoadBalancer.Factory clientFactory; - - public XForwardedHeadersTransformer(ReactiveLoadBalancer.Factory clientFactory) { - this.clientFactory = clientFactory; - } - - @Override - public ClientRequest transformRequest(ClientRequest request, ServiceInstance instance) { - if (instance == null) { - return request; - } - LoadBalancerProperties.XForwarded xForwarded = clientFactory.getProperties(instance.getServiceId()) - .getXForwarded(); - if (xForwarded.isEnabled()) { - HttpHeaders headers = request.headers(); - String xForwardedHost = request.url().getHost(); - String xForwardedProto = request.url().getScheme(); - headers.add("X-Forwarded-Host", xForwardedHost); - headers.add("X-Forwarded-Proto", xForwardedProto); - } - return request; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplier.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplier.java deleted file mode 100644 index dafbbad7..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplier.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig; - -/** - * An implementation of {@link ServiceInstanceListSupplier} that filters instances - * retrieved by the delegate by zone. The zone is retrieved from the - * spring.cloud.loadbalancer.zone property. If the zone is not set or no - * instances are found for the requested zone, all instances retrieved by the delegate are - * returned. - * - * @author Olga Maciaszek-Sharma - * @since 2.2.1 - */ -public class ZonePreferenceServiceInstanceListSupplier extends DelegatingServiceInstanceListSupplier { - - private final String ZONE = "zone"; - - private final LoadBalancerZoneConfig zoneConfig; - - private String zone; - - private boolean callGetWithRequestOnDelegates; - - public ZonePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - LoadBalancerZoneConfig zoneConfig) { - super(delegate); - this.zoneConfig = zoneConfig; - } - - public ZonePreferenceServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - LoadBalancerZoneConfig zoneConfig, - ReactiveLoadBalancer.Factory loadBalancerClientFactory) { - super(delegate); - this.zoneConfig = zoneConfig; - callGetWithRequestOnDelegates = loadBalancerClientFactory.getProperties(getServiceId()) - .isCallGetWithRequestOnDelegates(); - } - - @Override - public Flux> get() { - return getDelegate().get().map(this::filteredByZone); - } - - @Override - public Flux> get(Request request) { - if (callGetWithRequestOnDelegates) { - return getDelegate().get(request).map(this::filteredByZone); - } - return get(); - } - - private List filteredByZone(List serviceInstances) { - if (zone == null) { - zone = zoneConfig.getZone(); - } - if (zone != null) { - List filteredInstances = new ArrayList<>(); - for (ServiceInstance serviceInstance : serviceInstances) { - String instanceZone = getZone(serviceInstance); - if (zone.equalsIgnoreCase(instanceZone)) { - filteredInstances.add(serviceInstance); - } - } - if (filteredInstances.size() > 0) { - return filteredInstances; - } - } - // If the zone is not set or there are no zone-specific instances available, - // we return all instances retrieved for given service id. - return serviceInstances; - } - - private String getZone(ServiceInstance serviceInstance) { - Map metadata = serviceInstance.getMetadata(); - if (metadata != null) { - return metadata.get(ZONE); - } - return null; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfiguration.java deleted file mode 100644 index 17d6ddfc..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfiguration.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2015-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.loadbalancer.security; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor; -import org.springframework.cloud.client.loadbalancer.RetryLoadBalancerInterceptor; -import org.springframework.context.annotation.Configuration; - -/** - * @author Dave Syer - * - */ -@Configuration(proxyBeanMethods = false) -// @ConditionalOnClass(OAuth2RestTemplate.class) -@ConditionalOnProperty("spring.cloud.oauth2.load-balanced.enabled") -// @AutoConfigureAfter(OAuth2AutoConfiguration.class) -public class OAuth2LoadBalancerClientAutoConfiguration { - - @Configuration(proxyBeanMethods = false) - @ConditionalOnBean(LoadBalancerInterceptor.class) - protected static class UserInfoLoadBalancerConfig { - - /* - * @Bean public UserInfoRestTemplateCustomizer - * loadBalancedUserInfoRestTemplateCustomizer( final LoadBalancerInterceptor - * loadBalancerInterceptor) { return restTemplate -> { - * List interceptors = new - * ArrayList<>(restTemplate.getInterceptors()); - * interceptors.add(loadBalancerInterceptor); - * restTemplate.setInterceptors(interceptors); }; } - */ - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnBean(RetryLoadBalancerInterceptor.class) - protected static class UserInfoRetryLoadBalancerConfig { - - /* - * @Bean public UserInfoRestTemplateCustomizer - * retryLoadBalancedUserInfoRestTemplateCustomizer( final - * RetryLoadBalancerInterceptor loadBalancerInterceptor) { return new - * UserInfoRestTemplateCustomizer() { - * - * @Override public void customize(OAuth2RestTemplate restTemplate) { - * List interceptors = new - * ArrayList<>(restTemplate.getInterceptors()); - * interceptors.add(loadBalancerInterceptor); - * restTemplate.setInterceptors(interceptors); } }; } - */ - - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java deleted file mode 100644 index d21672ce..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.stats; - -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.Tags; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.util.StringUtils; - -/** - * Utility class for building metrics tags for load-balanced calls. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -final class LoadBalancerTags { - - static final String UNKNOWN = "UNKNOWN"; - - private LoadBalancerTags() { - throw new UnsupportedOperationException("Cannot instantiate utility class"); - } - - static Iterable buildSuccessRequestTags(CompletionContext completionContext) { - ServiceInstance serviceInstance = completionContext.getLoadBalancerResponse().getServer(); - Tags tags = Tags.of(buildServiceInstanceTags(serviceInstance)); - Object clientResponse = completionContext.getClientResponse(); - if (clientResponse instanceof ResponseData responseData) { - RequestData requestData = responseData.getRequestData(); - if (requestData != null) { - tags = tags.and(valueOrUnknown("method", requestData.getHttpMethod()), - valueOrUnknown("uri", getPath(requestData))); - } - else { - tags = tags.and(Tag.of("method", UNKNOWN), Tag.of("uri", UNKNOWN)); - } - - tags = tags.and(Tag.of("outcome", forStatus(statusValue(responseData))), - valueOrUnknown("status", statusValue(responseData))); - } - else { - tags = tags.and(Tag.of("method", UNKNOWN), Tag.of("uri", UNKNOWN), Tag.of("outcome", UNKNOWN), - Tag.of("status", UNKNOWN)); - } - return tags; - } - - // In keeping with the way null HttpStatus is handled in Actuator - private static int statusValue(ResponseData responseData) { - return responseData.getHttpStatus() != null ? responseData.getHttpStatus().value() : 200; - } - - private static String getPath(RequestData requestData) { - return requestData.getUrl() != null ? requestData.getUrl().getPath() : UNKNOWN; - } - - static Iterable buildDiscardedRequestTags( - CompletionContext completionContext) { - if (completionContext.getLoadBalancerRequest().getContext() instanceof RequestDataContext) { - RequestData requestData = ((RequestDataContext) completionContext.getLoadBalancerRequest().getContext()) - .getClientRequest(); - if (requestData != null) { - return Tags.of(valueOrUnknown("method", requestData.getHttpMethod()), - valueOrUnknown("uri", getPath(requestData)), valueOrUnknown("serviceId", getHost(requestData))); - } - } - return Tags.of(valueOrUnknown("method", UNKNOWN), valueOrUnknown("uri", UNKNOWN), - valueOrUnknown("serviceId", UNKNOWN)); - - } - - private static String getHost(RequestData requestData) { - return requestData.getUrl() != null ? requestData.getUrl().getHost() : UNKNOWN; - } - - static Iterable buildFailedRequestTags(CompletionContext completionContext) { - ServiceInstance serviceInstance = completionContext.getLoadBalancerResponse().getServer(); - Tags tags = Tags.of(buildServiceInstanceTags(serviceInstance)).and(exception(completionContext.getThrowable())); - if (completionContext.getLoadBalancerRequest().getContext() instanceof RequestDataContext) { - RequestData requestData = ((RequestDataContext) completionContext.getLoadBalancerRequest().getContext()) - .getClientRequest(); - if (requestData != null) { - return tags.and(Tags.of(valueOrUnknown("method", requestData.getHttpMethod()), - valueOrUnknown("uri", getPath(requestData)))); - } - } - return tags.and(Tags.of(valueOrUnknown("method", UNKNOWN), valueOrUnknown("uri", UNKNOWN))); - } - - static Iterable buildServiceInstanceTags(ServiceInstance serviceInstance) { - return Tags.of(valueOrUnknown("serviceId", serviceInstance.getServiceId()), - valueOrUnknown("serviceInstance.instanceId", serviceInstance.getInstanceId()), - valueOrUnknown("serviceInstance.host", serviceInstance.getHost()), - valueOrUnknown("serviceInstance.port", String.valueOf(serviceInstance.getPort()))); - } - - private static Tag valueOrUnknown(String key, String value) { - if (value != null) { - return Tag.of(key, value); - } - return Tag.of(key, UNKNOWN); - } - - private static Tag valueOrUnknown(String key, Object value) { - if (value != null) { - return Tag.of(key, String.valueOf(value)); - } - return Tag.of(key, UNKNOWN); - } - - private static Tag exception(Throwable exception) { - if (exception != null) { - String simpleName = exception.getClass().getSimpleName(); - return Tag.of("exception", StringUtils.hasText(simpleName) ? simpleName : exception.getClass().getName()); - } - return Tag.of("exception", "None"); - } - - // Logic from Actuator's `Outcome` class. Copied in here to avoid adding Actuator - // dependency. - public static String forStatus(int status) { - if (status >= 100 && status < 200) { - return "INFORMATIONAL"; - } - else if (status >= 200 && status < 300) { - return "SUCCESS"; - } - else if (status >= 300 && status < 400) { - return "REDIRECTION"; - } - else if (status >= 400 && status < 500) { - return "CLIENT_ERROR"; - } - else if (status >= 500 && status < 600) { - return "SERVER_ERROR"; - } - return UNKNOWN; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycle.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycle.java deleted file mode 100644 index fe7daf0e..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycle.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.stats; - -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; - -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.Gauge; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Timer; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.TimedRequestContext; - -import static org.springframework.cloud.loadbalancer.stats.LoadBalancerTags.buildDiscardedRequestTags; -import static org.springframework.cloud.loadbalancer.stats.LoadBalancerTags.buildFailedRequestTags; -import static org.springframework.cloud.loadbalancer.stats.LoadBalancerTags.buildServiceInstanceTags; -import static org.springframework.cloud.loadbalancer.stats.LoadBalancerTags.buildSuccessRequestTags; - -/** - * An implementation of {@link LoadBalancerLifecycle} that records metrics for - * load-balanced calls. - * - * @author Olga Maciaszek-Sharma - * @since 3.0.0 - */ -public class MicrometerStatsLoadBalancerLifecycle implements LoadBalancerLifecycle { - - private final MeterRegistry meterRegistry; - - private final ConcurrentHashMap activeRequestsPerInstance = new ConcurrentHashMap<>(); - - public MicrometerStatsLoadBalancerLifecycle(MeterRegistry meterRegistry) { - this.meterRegistry = meterRegistry; - } - - @Override - public boolean supports(Class requestContextClass, Class responseClass, Class serverTypeClass) { - return ServiceInstance.class.isAssignableFrom(serverTypeClass); - } - - @Override - public void onStart(Request request) { - // do nothing - } - - @Override - public void onStartRequest(Request request, Response lbResponse) { - if (request.getContext() instanceof TimedRequestContext) { - ((TimedRequestContext) request.getContext()).setRequestStartTime(System.nanoTime()); - } - if (!lbResponse.hasServer()) { - return; - } - ServiceInstance serviceInstance = lbResponse.getServer(); - AtomicLong activeRequestsCounter = activeRequestsPerInstance.computeIfAbsent(serviceInstance, instance -> { - AtomicLong createdCounter = new AtomicLong(); - Gauge.builder("loadbalancer.requests.active", () -> createdCounter) - .tags(buildServiceInstanceTags(serviceInstance)).register(meterRegistry); - return createdCounter; - }); - activeRequestsCounter.incrementAndGet(); - } - - @Override - public void onComplete(CompletionContext completionContext) { - long requestFinishedTimestamp = System.nanoTime(); - if (CompletionContext.Status.DISCARD.equals(completionContext.status())) { - Counter.builder("loadbalancer.requests.discard").tags(buildDiscardedRequestTags(completionContext)) - .register(meterRegistry).increment(); - return; - } - ServiceInstance serviceInstance = completionContext.getLoadBalancerResponse().getServer(); - AtomicLong activeRequestsCounter = activeRequestsPerInstance.get(serviceInstance); - if (activeRequestsCounter != null) { - activeRequestsCounter.decrementAndGet(); - } - Object loadBalancerRequestContext = completionContext.getLoadBalancerRequest().getContext(); - if (requestHasBeenTimed(loadBalancerRequestContext)) { - if (CompletionContext.Status.FAILED.equals(completionContext.status())) { - Timer.builder("loadbalancer.requests.failed").tags(buildFailedRequestTags(completionContext)) - .register(meterRegistry) - .record(requestFinishedTimestamp - - ((TimedRequestContext) loadBalancerRequestContext).getRequestStartTime(), - TimeUnit.NANOSECONDS); - return; - } - Timer.builder("loadbalancer.requests.success").tags(buildSuccessRequestTags(completionContext)) - .register(meterRegistry) - .record(requestFinishedTimestamp - - ((TimedRequestContext) loadBalancerRequestContext).getRequestStartTime(), - TimeUnit.NANOSECONDS); - } - } - - private boolean requestHasBeenTimed(Object loadBalancerRequestContext) { - return loadBalancerRequestContext instanceof TimedRequestContext - && (((TimedRequestContext) loadBalancerRequestContext).getRequestStartTime() != 0L); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerClientFactory.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerClientFactory.java deleted file mode 100644 index f871cee3..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerClientFactory.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.support; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.cloud.context.named.NamedContextFactory; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientSpecification; -import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.env.Environment; - -/** - * 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 - * @author Olga Maciaszek-Sharma - */ -public class LoadBalancerClientFactory extends NamedContextFactory - implements ReactiveLoadBalancer.Factory { - - private static final Log log = LogFactory.getLog(LoadBalancerClientFactory.class); - - /** - * Property source name for load balancer. - */ - public static final String NAMESPACE = "loadbalancer"; - - /** - * Property for client name within the load balancer namespace. - */ - public static final String PROPERTY_NAME = NAMESPACE + ".client.name"; - - private final LoadBalancerClientsProperties properties; - - public LoadBalancerClientFactory(LoadBalancerClientsProperties properties) { - super(LoadBalancerClientConfiguration.class, NAMESPACE, PROPERTY_NAME, new HashMap<>()); - this.properties = properties; - } - - public LoadBalancerClientFactory(LoadBalancerClientsProperties properties, - Map> applicationContextInitializers) { - super(LoadBalancerClientConfiguration.class, NAMESPACE, PROPERTY_NAME, applicationContextInitializers); - this.properties = properties; - } - - public static String getName(Environment environment) { - return environment.getProperty(PROPERTY_NAME); - } - - @Override - public ReactiveLoadBalancer getInstance(String serviceId) { - return getInstance(serviceId, ReactorServiceInstanceLoadBalancer.class); - } - - @Override - public LoadBalancerProperties getProperties(String serviceId) { - if (properties == null) { - if (log.isWarnEnabled()) { - log.warn("LoadBalancerClientsProperties is null. Please use the new constructor."); - } - return null; - } - if (serviceId == null || !properties.getClients().containsKey(serviceId)) { - // no specific client properties, return default - return properties; - } - // because specifics are overlayed on top of defaults, everything in `properties`, - // unless overridden, is in `clientsProperties` - return properties.getClients().get(serviceId); - } - - @SuppressWarnings("unchecked") - public LoadBalancerClientFactory withApplicationContextInitializers( - Map applicationContextInitializers) { - Map> convertedInitializers = new HashMap<>(); - applicationContextInitializers.keySet() - .forEach(contextId -> convertedInitializers.put(contextId, - (ApplicationContextInitializer) applicationContextInitializers - .get(contextId))); - return new LoadBalancerClientFactory(properties, convertedInitializers); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializer.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializer.java deleted file mode 100644 index 7a72cb68..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.support; - -import java.util.List; - -import org.springframework.boot.context.event.ApplicationReadyEvent; -import org.springframework.context.ApplicationListener; - -/** - * @author Andrii Bohutskyi - */ -public class LoadBalancerEagerContextInitializer implements ApplicationListener { - - private final LoadBalancerClientFactory factory; - - private final List serviceNames; - - public LoadBalancerEagerContextInitializer(LoadBalancerClientFactory factory, List serviceNames) { - this.factory = factory; - this.serviceNames = serviceNames; - } - - @Override - public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { - serviceNames.forEach(factory::getInstance); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtils.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtils.java deleted file mode 100644 index 3856dc67..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtils.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.support; - -import org.springframework.core.env.Environment; - -/** - * @author Olga Maciaszek-Sharma - */ -public final class LoadBalancerEnvironmentPropertyUtils { - - private LoadBalancerEnvironmentPropertyUtils() { - throw new IllegalStateException("Should not instantiate a utility class"); - } - - public static boolean trueForClientOrDefault(Environment environment, String propertySuffix) { - return equalToForClientOrDefault(environment, propertySuffix, Boolean.TRUE.toString()); - } - - public static boolean equalToForClientOrDefault(Environment environment, String propertySuffix, - String expectedPropertyValue) { - String defaultValue = getDefaultPropertyValue(environment, propertySuffix); - String clientValue = getClientPropertyValue(environment, propertySuffix); - if (clientValue != null && clientValue.equalsIgnoreCase(expectedPropertyValue)) { - return true; - } - return clientValue == null && defaultValue != null && defaultValue.equalsIgnoreCase(expectedPropertyValue); - } - - public static boolean equalToOrMissingForClientOrDefault(Environment environment, String propertySuffix, - String expectedPropertyValue) { - String defaultValue = getDefaultPropertyValue(environment, propertySuffix); - String clientValue = getClientPropertyValue(environment, propertySuffix); - if (clientValue != null && clientValue.equalsIgnoreCase(expectedPropertyValue)) { - return true; - } - if (clientValue == null && defaultValue != null && defaultValue.equalsIgnoreCase(expectedPropertyValue)) { - return true; - } - return clientValue == null && defaultValue == null; - } - - public static boolean trueOrMissingForClientOrDefault(Environment environment, String propertySuffix) { - return equalToOrMissingForClientOrDefault(environment, propertySuffix, Boolean.TRUE.toString()); - } - - private static String getClientPropertyValue(Environment environment, String propertySuffix) { - return environment.getProperty("spring.cloud.loadbalancer.clients." - + LoadBalancerClientFactory.getName(environment) + "." + propertySuffix); - } - - private static String getDefaultPropertyValue(Environment environment, String propertySuffix) { - return environment.getProperty("spring.cloud.loadbalancer." + propertySuffix); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/ServiceInstanceListSuppliers.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/ServiceInstanceListSuppliers.java deleted file mode 100644 index 5ac588fc..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/ServiceInstanceListSuppliers.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.support; - -import java.util.Arrays; -import java.util.List; - -import reactor.core.publisher.Flux; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; - -/** - * Utility class for service instance list suppliers. - * - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - */ -public final class ServiceInstanceListSuppliers { - - private ServiceInstanceListSuppliers() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - public static ServiceInstanceListSupplier from(String serviceId, ServiceInstance... instances) { - return new ServiceInstanceListSupplier() { - @Override - public Flux> get() { - return Flux.just(Arrays.asList(instances)); - } - - @Override - public String getServiceId() { - return serviceId; - } - }; - } - - public static ObjectProvider toProvider(String serviceId, - ServiceInstance... instances) { - return new SimpleObjectProvider<>(from(serviceId, instances)); - } - -} diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/SimpleObjectProvider.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/SimpleObjectProvider.java deleted file mode 100644 index c80ef000..00000000 --- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/support/SimpleObjectProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.support; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.ObjectProvider; - -/** - * Wrapper for {@link ObjectProvider}. - * - * @param type of the object to fetch - * @author Spencer Gibb - */ -public class SimpleObjectProvider implements ObjectProvider { - - private final T object; - - public SimpleObjectProvider(T object) { - this.object = object; - } - - @Override - public T getObject(Object... args) throws BeansException { - return this.object; - } - - @Override - public T getIfAvailable() throws BeansException { - return this.object; - } - - @Override - public T getIfUnique() throws BeansException { - return this.object; - } - - @Override - public T getObject() throws BeansException { - return this.object; - } - -} diff --git a/spring-cloud-loadbalancer/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/spring-cloud-loadbalancer/src/main/resources/META-INF/additional-spring-configuration-metadata.json deleted file mode 100644 index d3a57e68..00000000 --- a/spring-cloud-loadbalancer/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "properties": [ - { - "name": "spring.cloud.loadbalancer.zone", - "type": "java.lang.String", - "description": "Spring Cloud LoadBalancer zone." - }, - { - "name": "spring.cloud.loadbalancer.service-discovery.timeout", - "description": "String representation of Duration of the timeout for calls to service discovery.", - "type": "java.lang.String" - }, - { - "defaultValue": true, - "name": "spring.cloud.loadbalancer.cache.enabled", - "description": "Enables Spring Cloud LoadBalancer caching mechanism.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": true, - "name": "spring.cloud.loadbalancer.retry.avoid-previous-instance", - "description": "Enables wrapping ServiceInstanceListSupplier beans with `RetryAwareServiceInstanceListSupplier` if Spring-Retry is in the classpath.", - "type": "java.lang.Boolean" - }, - { - "defaultValue": "default", - "name": "spring.cloud.loadbalancer.configurations", - "description": "Enables a predefined LoadBalancer configuration.", - "type": "java.lang.String" - }, - { - "defaultValue": "true", - "name": "spring.cloud.loadbalancer.enabled", - "description": "Enables Spring Cloud LoadBalancer.", - "type": "java.lang.Boolean" - }, - { - "name": "spring.cloud.loadbalancer.eager-load.clients", - "description": "Names of the clients.", - "type": "java.util.List" - }, - { - "defaultValue": "false", - "name": "spring.cloud.loadbalancer.stats.micrometer.enabled", - "description": "Enables Spring Cloud LoadBalancer Micrometer stats.", - "type": "java.lang.Boolean" - } - ] -} diff --git a/spring-cloud-loadbalancer/src/main/resources/META-INF/spring/aot.factories b/spring-cloud-loadbalancer/src/main/resources/META-INF/spring/aot.factories deleted file mode 100644 index 70ab7722..00000000 --- a/spring-cloud-loadbalancer/src/main/resources/META-INF/spring/aot.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.aot.hint.RuntimeHintsRegistrar=\ -org.springframework.cloud.loadbalancer.config.CaffeineHints \ No newline at end of file diff --git a/spring-cloud-loadbalancer/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-loadbalancer/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 90372340..00000000 --- a/spring-cloud-loadbalancer/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,5 +0,0 @@ -org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration -org.springframework.cloud.loadbalancer.config.BlockingLoadBalancerClientAutoConfiguration -org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration -org.springframework.cloud.loadbalancer.security.OAuth2LoadBalancerClientAutoConfiguration -org.springframework.cloud.loadbalancer.config.LoadBalancerStatsAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java deleted file mode 100644 index eda9dc1c..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/annotation/LoadBalancerClientConfigurationTests.java +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.annotation; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration; -import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration; -import org.springframework.cloud.client.loadbalancer.LoadBalanced; -import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration; -import org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration; -import org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.DelegatingServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.HealthCheckServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.RequestBasedStickySessionServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.RetryAwareServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.WeightedServiceInstanceListSupplier; -import org.springframework.cloud.loadbalancer.core.ZonePreferenceServiceInstanceListSupplier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.retry.support.RetryTemplate; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * Tests for {@link LoadBalancerClientConfiguration}. - * - * @author Olga Maciaszek-Sharma - * @author Zhuozhi Ji - */ -class LoadBalancerClientConfigurationTests { - - ApplicationContextRunner reactiveDiscoveryClientRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(ReactiveCompositeDiscoveryClientAutoConfiguration.class, - LoadBalancerCacheAutoConfiguration.class, LoadBalancerAutoConfiguration.class, - LoadBalancerClientConfiguration.class)); - - ApplicationContextRunner blockingDiscoveryClientRunner = new ApplicationContextRunner() - .withClassLoader(new FilteredClassLoader(RetryTemplate.class)) - .withConfiguration(AutoConfigurations.of(CompositeDiscoveryClientAutoConfiguration.class, - LoadBalancerCacheAutoConfiguration.class, LoadBalancerAutoConfiguration.class, - LoadBalancerClientConfiguration.class)); - - ApplicationContextRunner blockingDiscoveryClientRunnerWithRetry = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(CompositeDiscoveryClientAutoConfiguration.class, - LoadBalancerCacheAutoConfiguration.class, LoadBalancerAutoConfiguration.class, - LoadBalancerClientConfiguration.class)); - - @Test - void shouldInstantiateDefaultServiceInstanceListSupplierWhenConfigurationsPropertyNotSet() { - reactiveDiscoveryClientRunner.run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) - .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateDefaultServiceInstanceListSupplier() { - reactiveDiscoveryClientRunner.withPropertyValues("spring.cloud.loadbalancer.configurations=default") - .run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) - .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateZonePreferenceServiceInstanceListSupplier() { - reactiveDiscoveryClientRunner.withPropertyValues("spring.cloud.loadbalancer.configurations=zone-preference") - .run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(ZonePreferenceServiceInstanceListSupplier.class); - ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier) - .getDelegate(); - then(delegate).isInstanceOf(CachingServiceInstanceListSupplier.class); - ServiceInstanceListSupplier secondDelegate = ((DelegatingServiceInstanceListSupplier) delegate) - .getDelegate(); - then(secondDelegate).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateHealthCheckServiceInstanceListSupplier() { - reactiveDiscoveryClientRunner.withUserConfiguration(TestConfig.class) - .withPropertyValues("spring.cloud.loadbalancer.configurations=health-check").run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(HealthCheckServiceInstanceListSupplier.class); - ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier) - .getDelegate(); - then(delegate).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateWeightedServiceInstanceListSupplier() { - reactiveDiscoveryClientRunner.withUserConfiguration(TestConfig.class) - .withPropertyValues("spring.cloud.loadbalancer.configurations=weighted").run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(WeightedServiceInstanceListSupplier.class); - ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier) - .getDelegate(); - then(delegate).isInstanceOf(CachingServiceInstanceListSupplier.class); - ServiceInstanceListSupplier secondDelegate = ((DelegatingServiceInstanceListSupplier) delegate) - .getDelegate(); - then(secondDelegate).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateRequestBasedStickySessionServiceInstanceListSupplierTests() { - reactiveDiscoveryClientRunner.withUserConfiguration(TestConfig.class) - .withPropertyValues("spring.cloud.loadbalancer.configurations=request-based-sticky-session") - .run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(RequestBasedStickySessionServiceInstanceListSupplier.class); - ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier) - .getDelegate(); - then(delegate).isInstanceOf(CachingServiceInstanceListSupplier.class); - ServiceInstanceListSupplier secondDelegate = ((DelegatingServiceInstanceListSupplier) delegate) - .getDelegate(); - then(secondDelegate).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateDefaultBlockingServiceInstanceListSupplierWhenConfigurationsPropertyNotSet() { - blockingDiscoveryClientRunner.run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) - .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateDefaultBlockingServiceInstanceListSupplier() { - blockingDiscoveryClientRunner.withPropertyValues("spring.cloud.loadbalancer.configurations=default") - .run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) - .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldWrapWithRetryAwareSupplierWhenRetryTemplateOnClasspath() { - blockingDiscoveryClientRunnerWithRetry.run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(RetryAwareServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) - .isInstanceOf(CachingServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) ((DelegatingServiceInstanceListSupplier) supplier) - .getDelegate()).getDelegate()).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldNotWrapWithRetryAwareSupplierWhenRetryTemplateOnClasspath() { - blockingDiscoveryClientRunner.withPropertyValues("spring.cloud.loadbalancer.retry.avoidPreviousInstance=false") - .run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(CachingServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) - .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - - } - - @Test - void shouldInstantiateBlockingHealthCheckServiceInstanceListSupplier() { - blockingDiscoveryClientRunner.withUserConfiguration(RestTemplateTestConfig.class) - .withPropertyValues("spring.cloud.loadbalancer.configurations=health-check").run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(HealthCheckServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) supplier).getDelegate()) - .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - void shouldInstantiateBlockingWeightedServiceInstanceListSupplier() { - blockingDiscoveryClientRunner.withUserConfiguration(RestTemplateTestConfig.class) - .withPropertyValues("spring.cloud.loadbalancer.configurations=weighted").run(context -> { - ServiceInstanceListSupplier supplier = context.getBean(ServiceInstanceListSupplier.class); - then(supplier).isInstanceOf(WeightedServiceInstanceListSupplier.class); - ServiceInstanceListSupplier delegate = ((DelegatingServiceInstanceListSupplier) supplier) - .getDelegate(); - then(delegate).isInstanceOf(CachingServiceInstanceListSupplier.class); - then(((DelegatingServiceInstanceListSupplier) delegate).getDelegate()) - .isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Configuration - protected static class TestConfig { - - @Bean - @LoadBalanced - WebClient.Builder webClientBuilder() { - return WebClient.builder(); - } - - } - - @Configuration - protected static class RestTemplateTestConfig { - - @Bean - RestTemplate restTemplate() { - return new RestTemplate(); - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java deleted file mode 100644 index 8c944ffd..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/aot/LoadBalancerChildContextInitializerTests.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.aot; - -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; - -import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import org.springframework.aot.AotDetector; -import org.springframework.aot.test.generate.TestGenerationContext; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration; -import org.springframework.boot.context.annotation.UserConfigurations; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext; -import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext; -import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; -import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.aot.ApplicationContextAotGenerator; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.test.tools.CompileWithForkedClassLoader; -import org.springframework.core.test.tools.TestCompiler; -import org.springframework.javapoet.ClassName; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LoadBalancerChildContextInitializer}. - * - * @author Olga Maciaszek-Sharma - */ -@ExtendWith(OutputCaptureExtension.class) -public class LoadBalancerChildContextInitializerTests { - - private static final Log LOG = LogFactory.getLog(LoadBalancerChildContextInitializerTests.class); - - @BeforeEach - @AfterEach - void reset() { - ReflectionTestUtils.setField(TomcatURLStreamHandlerFactory.class, "instance", null); - ReflectionTestUtils.setField(URL.class, "factory", null); - } - - @Test - @CompileWithForkedClassLoader - @SuppressWarnings("unchecked") - void shouldStartLBChildContextsFromAotContributions(CapturedOutput output) { - WebApplicationContextRunner contextRunner = new WebApplicationContextRunner( - AnnotationConfigServletWebApplicationContext::new) - .withConfiguration(AutoConfigurations.of(ServletWebServerFactoryAutoConfiguration.class, - LoadBalancerAutoConfiguration.class)) - .withConfiguration(UserConfigurations.of(TestLoadBalancerConfiguration.class)); - contextRunner.withPropertyValues("spring.cloud.loadbalancer.eager-load.clients[0]=test1").prepare(context -> { - TestGenerationContext generationContext = new TestGenerationContext(TestTarget.class); - ClassName className = new ApplicationContextAotGenerator().processAheadOfTime( - (GenericApplicationContext) context.getSourceApplicationContext(), generationContext); - generationContext.writeGeneratedContent(); - TestCompiler compiler = TestCompiler.forSystem(); - compiler.with(generationContext).compile(compiled -> { - ServletWebServerApplicationContext freshApplicationContext = new ServletWebServerApplicationContext(); - ApplicationContextInitializer initializer = compiled - .getInstance(ApplicationContextInitializer.class, className.toString()); - initializer.initialize(freshApplicationContext); - assertThat(output).contains("Refreshing LoadBalancerClientFactory-test1", - "Refreshing LoadBalancerClientFactory-test-2", "Refreshing LoadBalancerClientFactory-test_3"); - assertThat(output).doesNotContain("Instantiating bean from Test 2 custom config", - "Instantiating bean from default custom config"); - TestPropertyValues.of(AotDetector.AOT_ENABLED + "=true") - .applyToSystemProperties(freshApplicationContext::refresh); - WebClient webClient = freshApplicationContext.getBean(WebClient.class); - webClient.get().uri(URI.create("http://test-2/")).retrieve().bodyToMono(String.class).subscribe(); - assertThat(output).contains("Instantiating bean from Test 2 custom config", - "Instantiating bean from default custom config"); - }); - }); - - } - - static class TestTarget { - - } - - @Configuration(proxyBeanMethods = false) - @LoadBalancerClients(value = { @LoadBalancerClient(value = "test-2", configuration = Test2Configuration.class), - @LoadBalancerClient("test_3") }, defaultConfiguration = DefaultConfiguration.class) - public static class TestLoadBalancerConfiguration { - - @Bean - ReactorLoadBalancerExchangeFilterFunction exchangeFilterFunction( - LoadBalancerClientFactory loadBalancerClientFactory) { - return new ReactorLoadBalancerExchangeFilterFunction(loadBalancerClientFactory, new ArrayList<>()); - } - - @Bean - WebClient webClient(ReactorLoadBalancerExchangeFilterFunction lbFunction) { - return WebClient.builder().filter(lbFunction).build(); - } - - } - - public static class Test2Configuration { - - @Bean - TestBean testBean() { - LOG.debug("Instantiating bean from Test 2 custom config"); - return new TestBean(); - } - - } - - public static class DefaultConfiguration { - - @Bean - TestBean defaultTestBean() { - LOG.debug("Instantiating bean from default custom config"); - return new TestBean(); - } - - } - - public static class TestBean { - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java deleted file mode 100644 index 6899772b..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/XForwardedHeadersTransformerTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.blocking; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; - -import static java.net.URI.create; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link XForwardedHeadersTransformer}. - * - * @author Gandhimathi Velusamy - * @author Olga Maciaszek-Sharma - */ - -class XForwardedHeadersTransformerTests { - - private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - - private final LoadBalancerProperties loadBalancerProperties = new LoadBalancerProperties(); - - private final ServiceInstance serviceInstance = new DefaultServiceInstance("test1", "test", "test.org", 8080, - false); - - private final HttpRequest request = mock(HttpRequest.class); - - @BeforeEach - void setUp() { - when(request.getMethod()).thenReturn(HttpMethod.GET); - when(request.getURI()).thenReturn(create("https://google.com")); - when(request.getHeaders()).thenReturn(new HttpHeaders()); - } - - @Test - void shouldAppendXForwardedHeadersIfEnabled() { - loadBalancerProperties.getXForwarded().setEnabled(true); - when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); - - HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); - - assertThat(newRequest.getHeaders()).containsKey("X-Forwarded-Host"); - assertThat(newRequest.getHeaders().getFirst("X-Forwarded-Host")).isEqualTo("google.com"); - assertThat(newRequest.getHeaders()).containsKey("X-Forwarded-Proto"); - assertThat(newRequest.getHeaders().getFirst("X-Forwarded-Proto")).isEqualTo("https"); - } - - @Test - void shouldNotAppendXForwardedHeadersIfDefault() { - when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); - - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); - - HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); - assertThat(newRequest.getHeaders()).doesNotContainKey("X-Forwarded-Host"); - assertThat(newRequest.getHeaders()).doesNotContainKey("X-Forwarded-Proto"); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClientTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClientTests.java deleted file mode 100644 index 8d0e623c..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/client/BlockingLoadBalancerClientTests.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.blocking.client; - -import java.io.IOException; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -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.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.LoadBalancerLifecycle; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; -import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer; -import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.fail; - -/** - * Tests for {@link BlockingLoadBalancerClient}. - * - * @author Olga Maciaszek-Sharma - * @author Charu Covindane - */ -@SpringBootTest -class BlockingLoadBalancerClientTests { - - @Autowired - private BlockingLoadBalancerClient loadBalancerClient; - - @Autowired - private SimpleDiscoveryProperties properties; - - @Autowired - ReactiveLoadBalancer.Factory factory; - - @Autowired - LoadBalancerProperties loadBalancerProperties; - - @BeforeEach - void setUp() { - DefaultServiceInstance serviceInstance = new DefaultServiceInstance(null, null, "test.example", 9999, true); - properties.getInstances().put("myservice", Collections.singletonList(serviceInstance)); - } - - @Test - void correctServiceInstanceChosen() { - ServiceInstance serviceInstance = loadBalancerClient.choose("myservice"); - assertThat(serviceInstance.getHost()).isEqualTo("test.example"); - } - - @Test - void nullReturnedIfInstanceMissing() { - ServiceInstance serviceInstance = loadBalancerClient.choose("unknownservice"); - assertThat(serviceInstance).isNull(); - } - - @Test - void requestExecutedAgainstCorrectInstance() throws IOException { - final String result = "result"; - Object actualResult = loadBalancerClient.execute("myservice", (LoadBalancerRequest) instance -> { - assertThat(instance.getHost()).isEqualTo("test.example"); - return result; - }); - assertThat(actualResult).isEqualTo(result); - } - - @Test - void exceptionThrownIfInstanceNotAvailableForRequestExecution() { - try { - final String result = "result"; - Object actualResult = loadBalancerClient.execute("unknownservice", - (LoadBalancerRequest) instance -> result); - assertThat(actualResult).isEqualTo(result); - fail("Should have thrown exception."); - } - catch (Exception exception) { - assertThat(exception).isNotNull(); - assertThat(exception).isInstanceOf(IllegalStateException.class); - assertThat(exception).hasMessage("No instances available for unknownservice"); - } - } - - @Test - void exceptionRethrownAsRuntime() { - try { - loadBalancerClient.execute("myservice", instance -> { - assertThat(instance.getHost()).isEqualTo("test.example"); - throw new Exception("Should throw exception."); - }); - fail("Should have thrown exception."); - } - catch (Exception exception) { - assertThat(exception).isNotNull(); - assertThat(exception).isInstanceOf(RuntimeException.class); - } - } - - @Test - void IOExceptionRethrown() { - try { - loadBalancerClient.execute("myservice", instance -> { - assertThat(instance.getHost()).isEqualTo("test.example"); - throw new IOException("Should throw IO exception."); - }); - fail("Should have thrown exception."); - } - catch (Exception exception) { - assertThat(exception).isNotNull(); - assertThat(exception).isInstanceOf(IOException.class); - } - } - - @Test - void exceptionNotThrownWhenFactoryReturnsNullLifecycleProcessorsMap() { - assertThatCode(() -> loadBalancerClient.execute("serviceWithNoLifecycleProcessors", - (LoadBalancerRequest) instance -> { - assertThat(instance.getHost()).isEqualTo("test.example"); - return "result"; - })).doesNotThrowAnyException(); - } - - @Test - void loadBalancerLifecycleCallbacksExecuted() throws IOException { - String callbackTestHint = "callbackTestHint"; - loadBalancerProperties.getHint().put("myservice", "callbackTestHint"); - final String result = "callbackTestResult"; - Object actualResult = loadBalancerClient.execute("myservice", (LoadBalancerRequest) instance -> { - assertThat(instance.getHost()).isEqualTo("test.example"); - return result; - }); - - Collection> lifecycleLogRequests = ((TestLoadBalancerLifecycle) factory - .getInstances("myservice", LoadBalancerLifecycle.class).get("loadBalancerLifecycle")).getStartLog() - .values(); - Collection> lifecycleLogStartedRequests = ((TestLoadBalancerLifecycle) factory - .getInstances("myservice", LoadBalancerLifecycle.class).get("loadBalancerLifecycle")) - .getStartRequestLog().values(); - Collection> anotherLifecycleLogRequests = ((AnotherLoadBalancerLifecycle) factory - .getInstances("myservice", LoadBalancerLifecycle.class).get("anotherLoadBalancerLifecycle")) - .getCompleteLog().values(); - assertThat(actualResult).isEqualTo(result); - assertThat(lifecycleLogRequests).extracting(request -> ((DefaultRequestContext) request.getContext()).getHint()) - .contains(callbackTestHint); - assertThat(lifecycleLogStartedRequests) - .extracting(request -> ((DefaultRequestContext) request.getContext()).getHint()) - .contains(callbackTestHint); - assertThat(anotherLifecycleLogRequests).extracting(CompletionContext::getClientResponse).contains(result); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @LoadBalancerClients({ @LoadBalancerClient(name = "myservice", configuration = MyServiceConfig.class), - @LoadBalancerClient(name = "unknownservice", configuration = UnknownServiceConfig.class), - @LoadBalancerClient(name = "serviceWithNoLifecycleProcessors", - configuration = NoLifecycleProcessorsConfig.class) }) - protected static class Config { - - } - - protected static class NoLifecycleProcessorsConfig { - - @Bean - ReactorLoadBalancer reactiveLoadBalancer(DiscoveryClient discoveryClient) { - return new DiscoveryClientBasedReactiveLoadBalancer("myservice", discoveryClient); - } - - } - - protected static class MyServiceConfig { - - @Bean - ReactorLoadBalancer reactiveLoadBalancer(DiscoveryClient discoveryClient) { - return new DiscoveryClientBasedReactiveLoadBalancer("myservice", discoveryClient); - } - - @Bean - LoadBalancerLifecycle loadBalancerLifecycle() { - return new TestLoadBalancerLifecycle(); - } - - @Bean - LoadBalancerLifecycle anotherLoadBalancerLifecycle() { - return new AnotherLoadBalancerLifecycle(); - } - - } - - protected static class UnknownServiceConfig { - - @Bean - ReactorLoadBalancer reactiveLoadBalancer(DiscoveryClient discoveryClient) { - return new DiscoveryClientBasedReactiveLoadBalancer("unknownservice", discoveryClient); - } - - } - - protected static class TestLoadBalancerLifecycle implements LoadBalancerLifecycle { - - final Map> startLog = new ConcurrentHashMap<>(); - - final Map> startRequestLog = new ConcurrentHashMap<>(); - - final Map> completeLog = new ConcurrentHashMap<>(); - - @Override - public void onStart(Request request) { - startLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onStartRequest(Request request, Response lbResponse) { - startRequestLog.put(getName() + UUID.randomUUID(), request); - } - - @Override - public void onComplete(CompletionContext completionContext) { - completeLog.put(getName() + UUID.randomUUID(), completionContext); - } - - Map> getStartLog() { - return startLog; - } - - Map> getCompleteLog() { - return completeLog; - } - - Map> getStartRequestLog() { - return startRequestLog; - } - - protected String getName() { - return this.getClass().getSimpleName(); - } - - } - - protected static class AnotherLoadBalancerLifecycle extends TestLoadBalancerLifecycle { - - @Override - protected String getName() { - return this.getClass().getSimpleName(); - } - - } - -} - -@SuppressWarnings("rawtypes") -class DiscoveryClientBasedReactiveLoadBalancer implements ReactorServiceInstanceLoadBalancer { - - private final Random random = new Random(); - - private final String serviceId; - - private final DiscoveryClient discoveryClient; - - DiscoveryClientBasedReactiveLoadBalancer(String serviceId, DiscoveryClient discoveryClient) { - this.serviceId = serviceId; - this.discoveryClient = discoveryClient; - } - - @Override - public Mono> choose() { - List instances = discoveryClient.getInstances(serviceId); - if (instances.size() == 0) { - return Mono.just(new EmptyResponse()); - } - int instanceIdx = this.random.nextInt(instances.size()); - return Mono.just(new DefaultResponse(instances.get(instanceIdx))); - } - - @Override - public Mono> choose(Request request) { - return choose(); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicyTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicyTests.java deleted file mode 100644 index 64eaaa21..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/blocking/retry/BlockingLoadBalancedRetryPolicyTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.blocking.retry; - -import java.util.Arrays; -import java.util.HashSet; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; -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.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link BlockingLoadBalancedRetryPolicy}. - * - * @author Olga Maciaszek-Sharma - */ -class BlockingLoadBalancedRetryPolicyTests { - - private final BlockingLoadBalancerClient loadBalancerClient = mock(BlockingLoadBalancerClient.class); - - private final HttpRequest httpRequest = mock(HttpRequest.class); - - private final LoadBalancedRetryContext context = mock(LoadBalancedRetryContext.class); - - private final LoadBalancerProperties properties = new LoadBalancerProperties(); - - private final UnsupportedOperationException exception = new UnsupportedOperationException(); - - @BeforeEach - void setUp() { - when(httpRequest.getMethod()).thenReturn(HttpMethod.GET); - when(context.getRequest()).thenReturn(httpRequest); - } - - @Test - void shouldExecuteIndicatedNumberOfSameAndNextInstanceRetriesAndCloseRetryContext() { - properties.getRetry().setMaxRetriesOnSameServiceInstance(1); - BlockingLoadBalancedRetryPolicy retryPolicy = getRetryPolicy(properties); - - assertThat(retryPolicy.canRetrySameServer(context)).isTrue(); - assertThat(retryPolicy.canRetryNextServer(context)).isTrue(); - - retryPolicy.registerThrowable(context, exception); - assertThat(retryPolicy.canRetrySameServer(context)).isFalse(); - assertThat(retryPolicy.canRetryNextServer(context)).isTrue(); - - retryPolicy.registerThrowable(context, exception); - assertThat(retryPolicy.canRetrySameServer(context)).isTrue(); - assertThat(retryPolicy.canRetryNextServer(context)).isTrue(); - - retryPolicy.registerThrowable(context, exception); - assertThat(retryPolicy.canRetrySameServer(context)).isFalse(); - assertThat(retryPolicy.canRetryNextServer(context)).isTrue(); - - retryPolicy.registerThrowable(context, exception); - verify(context).setExhaustedOnly(); - verify(context).setServiceInstance(any()); - assertThat(retryPolicy.canRetrySameServer(context)).isTrue(); - assertThat(retryPolicy.canRetryNextServer(context)).isFalse(); - } - - @Test - void shouldNotRetryWhenMethodNotGet() { - when(httpRequest.getMethod()).thenReturn(HttpMethod.POST); - when(context.getRequest()).thenReturn(httpRequest); - BlockingLoadBalancedRetryPolicy retryPolicy = getRetryPolicy(properties); - - boolean canRetry = retryPolicy.canRetry(context); - - assertThat(canRetry).isFalse(); - } - - @Test - void shouldRetryOnPostWhenEnabled() { - when(httpRequest.getMethod()).thenReturn(HttpMethod.POST); - when(context.getRequest()).thenReturn(httpRequest); - properties.getRetry().setRetryOnAllOperations(true); - BlockingLoadBalancedRetryPolicy retryPolicy = getRetryPolicy(properties); - - boolean canRetry = retryPolicy.canRetry(context); - - assertThat(canRetry).isTrue(); - } - - @Test - void shouldResolveRetryableStatusCode() { - properties.getRetry().setRetryableStatusCodes(new HashSet<>(Arrays.asList(404, 502))); - BlockingLoadBalancedRetryPolicy retryPolicy = getRetryPolicy(properties); - - boolean retryableStatusCode = retryPolicy.retryableStatusCode(404); - - assertThat(retryableStatusCode).isTrue(); - } - - private BlockingLoadBalancedRetryPolicy getRetryPolicy(LoadBalancerProperties properties) { - return new BlockingLoadBalancedRetryPolicy(properties); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManagerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManagerTests.java deleted file mode 100644 index c852f764..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheManagerTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.cache; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.cache.CacheManager; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.springframework.cloud.loadbalancer.core.CachingServiceInstanceListSupplier.SERVICE_INSTANCE_CACHE_NAME; - -/** - * Tests for {@link DefaultLoadBalancerCacheManager}. - * - * @author Olga Maciaszek-Sharma - */ -class DefaultLoadBalancerCacheManagerTests { - - @SuppressWarnings("ConstantConditions") - @Test - void shouldCreateLoadBalancerCacheFromProperties() { - LoadBalancerCacheProperties properties = new LoadBalancerCacheProperties(); - properties.setTtl(Duration.ofMinutes(5)); - properties.setCapacity(128); - - DefaultLoadBalancerCacheManager cacheManager = new DefaultLoadBalancerCacheManager(properties); - - assertThat(cacheManager.getCacheNames()).hasSize(1); - assertThat(cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME)).isInstanceOf(DefaultLoadBalancerCache.class); - assertThat(((DefaultLoadBalancerCache) cacheManager.getCache(SERVICE_INSTANCE_CACHE_NAME)).getEvictMs()) - .isEqualTo(300000); - } - - @Test - void shouldNotThrowExceptionOnDuplicateCacheName() { - LoadBalancerCacheProperties properties = new LoadBalancerCacheProperties(); - - assertThatCode(() -> new DefaultLoadBalancerCacheManager(properties, "test", "test")) - .doesNotThrowAnyException(); - } - - @Test - void shouldOnlyCreateOneCacheWithGivenName() { - LoadBalancerCacheProperties properties = new LoadBalancerCacheProperties(); - - CacheManager cacheManager = new DefaultLoadBalancerCacheManager(properties, "test", "test"); - - assertThat(cacheManager.getCacheNames()).hasSize(1); - assertThat(cacheManager.getCache("test")).isInstanceOf(DefaultLoadBalancerCache.class); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheTests.java deleted file mode 100644 index 5f844c4c..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/cache/DefaultLoadBalancerCacheTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.cache; - -import com.stoyanr.evictor.map.ConcurrentHashMapWithTimedEviction; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.junit.jupiter.MockitoExtension; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * Tests for {@link DefaultLoadBalancerCache}. - * - * @author Olga Maciaszek-Sharma - */ -@ExtendWith(MockitoExtension.class) -class DefaultLoadBalancerCacheTests { - - @Test - void shouldAllowNullValuesByDefault() { - DefaultLoadBalancerCache cache = new DefaultLoadBalancerCache("test"); - - assertThatCode(() -> cache.put("testKey", null)).doesNotThrowAnyException(); - } - - @Test - void shouldThrowExceptionIfNullPutWithNonNullSetup() { - DefaultLoadBalancerCache cache = new DefaultLoadBalancerCache("test", false); - - assertThatIllegalArgumentException().isThrownBy(() -> cache.put("testKey", null)) - .withMessageContaining("Cache 'test' is configured to not allow null values but null was provided"); - } - - @Test - void shouldNotEvictEntriesByDefault() { - DefaultLoadBalancerCache cache = new DefaultLoadBalancerCache("test"); - - assertThat(cache.getEvictMs()).isEqualTo(0); - } - - @SuppressWarnings("unchecked") - @Test - void assertThatTtlApplied() { - ConcurrentHashMapWithTimedEviction nativeCache = mock(ConcurrentHashMapWithTimedEviction.class); - DefaultLoadBalancerCache cache = new DefaultLoadBalancerCache("test", nativeCache, 50, true); - - cache.put("testKey", "testValue"); - - verify(nativeCache, times(1)).put("testKey", "testValue", 50); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java deleted file mode 100644 index 9558d56d..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/BlockingLoadBalancerClientAutoConfigurationTests.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.config; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryFactory; -import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Spencer Gibb - * @author Olga Maciaszek-Sharma - * @author Tim Ysewyn - */ -class BlockingLoadBalancerClientAutoConfigurationTests { - - private ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(LoadBalancerAutoConfiguration.class, - BlockingLoadBalancerClientAutoConfiguration.class)); - - @Test - void beansCreatedNormally() { - applicationContextRunner.run(ctxt -> { - assertThat(ctxt).hasSingleBean(BlockingLoadBalancerClient.class); - assertThat(ctxt).hasSingleBean(LoadBalancedRetryFactory.class); - }); - } - - @Test - public void worksWithoutSpringWeb() { - applicationContextRunner.withClassLoader(new FilteredClassLoader(RestTemplate.class)) - .run(context -> assertThat(context).doesNotHaveBean(BlockingLoadBalancerClient.class)); - } - - @Test - void shouldNotFailOnRetryFactoryWhenLoadBalancingDisabled() { - applicationContextRunner.withPropertyValues("spring.cloud.loadbalancer.enabled=false").run(context -> { - assertThat(context).doesNotHaveBean(BlockingLoadBalancerClient.class); - assertThat(context).doesNotHaveBean(LoadBalancedRetryFactory.class); - }); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java deleted file mode 100644 index 981af732..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/config/LoadBalancerCacheAutoConfigurationTests.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.config; - -import com.github.benmanes.caffeine.cache.Caffeine; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cache.CacheManager; -import org.springframework.cache.annotation.EnableCaching; -import org.springframework.cache.caffeine.CaffeineCacheManager; -import org.springframework.cache.concurrent.ConcurrentMapCacheManager; -import org.springframework.cache.support.NoOpCacheManager; -import org.springframework.cloud.loadbalancer.cache.DefaultLoadBalancerCacheManager; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LoadBalancerCacheAutoConfiguration}. - * - * @author Olga Maciaszek-Sharma - */ -class LoadBalancerCacheAutoConfigurationTests { - - @Test - void shouldAutoEnableCaching() { - ApplicationContextRunner contextRunner = baseApplicationRunner(); - - contextRunner.run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); - assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()).hasSize(1); - assertThat(context.getBean("caffeineLoadBalancerCacheManager")).isInstanceOf(CaffeineCacheManager.class); - assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()) - .contains("CachingServiceInstanceListSupplierCache"); - }); - } - - @Test - void caffeineLoadBalancerCacheShouldNotOverrideCacheTypeSetting() { - ApplicationContextRunner contextRunner = baseApplicationRunner().withUserConfiguration(TestConfiguration.class) - .withPropertyValues("spring.cache.type=none"); - - contextRunner.run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); - assertThat(context.getBean("caffeineLoadBalancerCacheManager")).isInstanceOf(CaffeineCacheManager.class); - assertThat(context.getBeansOfType(CacheManager.class).get("cacheManager")) - .isInstanceOf(NoOpCacheManager.class); - - }); - } - - @Test - void loadBalancerCacheShouldNotOverrideExistingCaffeineCacheManager() { - ApplicationContextRunner contextRunner = baseApplicationRunner().withUserConfiguration(TestConfiguration.class); - - contextRunner.run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); - assertThat(context.getBean("cacheManager")).isInstanceOf(CaffeineCacheManager.class); - assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); - assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()).hasSize(1); - assertThat(((CacheManager) context.getBean("caffeineLoadBalancerCacheManager")).getCacheNames()) - .contains("CachingServiceInstanceListSupplierCache"); - }); - - } - - @Test - void shouldNotInstantiateCaffeineLoadBalancerCacheIfDisabled() { - ApplicationContextRunner contextRunner = baseApplicationRunner() - .withPropertyValues("spring.cloud.loadbalancer.cache.enabled=false") - .withUserConfiguration(TestConfiguration.class); - - contextRunner.run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); - assertThat(context.getBean("cacheManager")).isInstanceOf(CaffeineCacheManager.class); - assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); - }); - } - - @Test - void shouldUseDefaultCacheIfCaffeineNotInClasspath() { - ApplicationContextRunner contextRunner = noCaffeineRunner(); - - contextRunner.run(context -> { - assertThat(context.getBean(LoadBalancerCacheAutoConfiguration.LoadBalancerCaffeineWarnLogger.class)) - .isNotNull(); - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); - assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()).hasSize(1); - assertThat(context.getBean("defaultLoadBalancerCacheManager")) - .isInstanceOf(DefaultLoadBalancerCacheManager.class); - assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()) - .contains("CachingServiceInstanceListSupplierCache"); - }); - } - - @Test - void shouldUseDefaultCacheIfCaffeineCacheManagerNotInClasspath() { - ApplicationContextRunner contextRunner = noCaffeineCacheManagerRunner(); - - contextRunner.run(context -> { - assertThat(context.getBean(LoadBalancerCacheAutoConfiguration.LoadBalancerCaffeineWarnLogger.class)) - .isNotNull(); - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); - assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()).hasSize(1); - assertThat(context.getBean("defaultLoadBalancerCacheManager")) - .isInstanceOf(DefaultLoadBalancerCacheManager.class); - assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()) - .contains("CachingServiceInstanceListSupplierCache"); - }); - } - - @Test - void defaultLoadBalancerCacheShouldNotOverrideCacheTypeSetting() { - ApplicationContextRunner contextRunner = noCaffeineRunner().withUserConfiguration(TestConfiguration.class) - .withPropertyValues("spring.cache.type=none"); - - contextRunner.run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); - assertThat(context.getBean("defaultLoadBalancerCacheManager")) - .isInstanceOf(DefaultLoadBalancerCacheManager.class); - assertThat(context.getBeansOfType(CacheManager.class).get("cacheManager")) - .isInstanceOf(NoOpCacheManager.class); - - }); - } - - @Test - void defaultLoadBalancerCacheShouldNotOverrideExistingCacheManager() { - ApplicationContextRunner contextRunner = noCaffeineRunner().withUserConfiguration(TestConfiguration.class); - - contextRunner.run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(2); - assertThat(context.getBean("cacheManager")).isInstanceOf(ConcurrentMapCacheManager.class); - assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); - assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()).hasSize(1); - assertThat(((CacheManager) context.getBean("defaultLoadBalancerCacheManager")).getCacheNames()) - .contains("CachingServiceInstanceListSupplierCache"); - }); - - } - - @Test - void shouldNotInstantiateDefaultLoadBalancerCacheIfDisabled() { - ApplicationContextRunner contextRunner = noCaffeineRunner() - .withPropertyValues("spring.cloud.loadbalancer.cache.enabled=false") - .withUserConfiguration(TestConfiguration.class); - - contextRunner.run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); - assertThat(context.getBean("cacheManager")).isInstanceOf(ConcurrentMapCacheManager.class); - assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); - }); - } - - @Test - void shouldNotInstantiateDefaultLoadBalancerCacheIfLoadBalancingDisabled() { - noCaffeineRunner().withPropertyValues("spring.cloud.loadbalancer.enabled=false") - .withUserConfiguration(TestConfiguration.class).run(context -> { - assertThat(context.getBeansOfType(CacheManager.class)).hasSize(1); - assertThat(context.getBean("cacheManager")).isInstanceOf(ConcurrentMapCacheManager.class); - assertThat(((CacheManager) context.getBean("cacheManager")).getCacheNames()).isEmpty(); - }); - } - - private ApplicationContextRunner baseApplicationRunner() { - return new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(CacheAutoConfiguration.class, LoadBalancerCacheAutoConfiguration.class)); - } - - private ApplicationContextRunner noCaffeineRunner() { - return baseApplicationRunner().withClassLoader(new FilteredClassLoader(Caffeine.class)); - } - - private ApplicationContextRunner noCaffeineCacheManagerRunner() { - return baseApplicationRunner().withClassLoader(new FilteredClassLoader(CaffeineCacheManager.class)); - } - - @Configuration(proxyBeanMethods = false) - @EnableCaching - static class TestConfiguration { - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java deleted file mode 100644 index e2fde345..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/CachingServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient; -import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; -import org.springframework.cloud.loadbalancer.config.LoadBalancerCacheAutoConfiguration; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.web.reactive.function.client.WebClient; - -import static java.time.Duration.ofMillis; -import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; -import static org.springframework.cloud.loadbalancer.core.LoadBalancerTestUtils.buildLoadBalancerClientFactory; -import static org.springframework.cloud.loadbalancer.core.ServiceInstanceListSuppliersTestUtils.healthCheckFunction; - -/** - * Tests for {@link CachingServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - */ -@SpringBootTest(classes = CachingServiceInstanceListSupplierTests.TestConfig.class) -class CachingServiceInstanceListSupplierTests { - - public static final String SERVICE_ID = "test"; - - static { - System.setProperty("loadbalancer.client.name", SERVICE_ID); - } - - @Autowired - BlockingLoadBalancerClient blockingLoadBalancerClient; - - private static DefaultServiceInstance instance(String host, boolean secure) { - return new DefaultServiceInstance(SERVICE_ID, SERVICE_ID, host, 80, secure); - } - - @Test - void shouldNotHangOnCachingWhenDelegateReturnsInfiniteStream() { - assertTimeoutPreemptively(ofMillis(1000), () -> { - blockingLoadBalancerClient.choose(SERVICE_ID); - }); - - } - - @Configuration(proxyBeanMethods = false) - @Import(LoadBalancerCacheAutoConfiguration.class) - protected static class TestConfig { - - @Bean - public ReactiveDiscoveryClient reactiveDiscoveryClient() { - return new ReactiveDiscoveryClient() { - @Override - public String description() { - return SERVICE_ID; - } - - @Override - public Flux getInstances(String serviceId) { - return Flux.just(instance("1host", false), instance("2host-secure", true)); - } - - @Override - public Flux getServices() { - return Flux.just(SERVICE_ID); - } - }; - } - - @Bean - ReactorLoadBalancer reactorLoadBalancer(ObjectProvider provider) { - return new RoundRobinLoadBalancer(provider, SERVICE_ID); - } - - @Bean - LoadBalancerClientFactory loadBalancerClientFactory(LoadBalancerClientsProperties properties) { - return new LoadBalancerClientFactory(properties); - } - - @Bean - BlockingLoadBalancerClient blockingLoadBalancerClient(LoadBalancerClientFactory loadBalancerClientFactory, - LoadBalancerProperties properties) { - return new BlockingLoadBalancerClient(loadBalancerClientFactory); - } - - @Bean - public LoadBalancerClientsProperties loadBalancerClientsProperties() { - return new LoadBalancerClientsProperties(); - } - - @Bean - public WebClient.Builder webClientBuilder() { - return WebClient.builder(); - } - - @Bean - ServiceInstanceListSupplier supplier(ConfigurableApplicationContext context, - ReactiveDiscoveryClient discoveryClient, LoadBalancerProperties loadBalancerProperties, - WebClient.Builder webClientBuilder) { - DiscoveryClientServiceInstanceListSupplier firstDelegate = new DiscoveryClientServiceInstanceListSupplier( - discoveryClient, context.getEnvironment()); - HealthCheckServiceInstanceListSupplier delegate = new TestHealthCheckServiceInstanceListSupplier( - firstDelegate, loadBalancerProperties, webClientBuilder.build()); - delegate.afterPropertiesSet(); - ObjectProvider cacheManagerProvider = context - .getBeanProvider(LoadBalancerCacheManager.class); - return new CachingServiceInstanceListSupplier(delegate, cacheManagerProvider.getIfAvailable()); - } - - private static class TestHealthCheckServiceInstanceListSupplier extends HealthCheckServiceInstanceListSupplier { - - TestHealthCheckServiceInstanceListSupplier(ServiceInstanceListSupplier delegate, - LoadBalancerProperties properties, WebClient webClient) { - super(delegate, buildLoadBalancerClientFactory(delegate.getServiceId(), properties), - healthCheckFunction(webClient)); - } - - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return Mono.just(true); - } - - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplierTests.java deleted file mode 100644 index 6fb2287c..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/DiscoveryClientServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.time.Duration; -import java.util.Collections; - -import org.assertj.core.util.Lists; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.mockito.internal.stubbing.answers.AnswersWithDelay; -import org.mockito.internal.stubbing.answers.Returns; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.mock.env.MockEnvironment; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.loadbalancer.core.DiscoveryClientServiceInstanceListSupplier.SERVICE_DISCOVERY_TIMEOUT; - -/** - * Tests for {@link DiscoveryClientServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - * @author Rod Catter - */ -class DiscoveryClientServiceInstanceListSupplierTests { - - private static final String SERVICE_ID = "test"; - - private static final Duration VERIFICATION_TIMEOUT = Duration.ofSeconds(10); - - private final MockEnvironment environment = new MockEnvironment(); - - private final ReactiveDiscoveryClient reactiveDiscoveryClient = mock(ReactiveDiscoveryClient.class); - - private final DiscoveryClient discoveryClient = mock(DiscoveryClient.class); - - private DiscoveryClientServiceInstanceListSupplier supplier; - - private static DefaultServiceInstance instance(String host, boolean secure) { - return new DefaultServiceInstance(SERVICE_ID, SERVICE_ID, host, 80, secure); - } - - @BeforeEach - void setUp() { - environment.setProperty("loadbalancer.client.name", SERVICE_ID); - } - - @Test - void shouldReturnRetrievedInstances() { - when(reactiveDiscoveryClient.getInstances(SERVICE_ID)) - .thenReturn(Flux.just(instance("1host", false), instance("2host-secure", true))); - - StepVerifier.withVirtualTime(() -> { - supplier = new DiscoveryClientServiceInstanceListSupplier(reactiveDiscoveryClient, environment); - return supplier.get(); - }).expectSubscription().expectNext(Lists.list(instance("1host", false), instance("2host-secure", true))) - .thenCancel().verify(VERIFICATION_TIMEOUT); - } - - @Test - void shouldUpdateReturnRetrievedInstances() { - when(reactiveDiscoveryClient.getInstances(SERVICE_ID)) - .thenReturn(Flux.just(instance("1host", false), instance("2host-secure", true))); - supplier = new DiscoveryClientServiceInstanceListSupplier(reactiveDiscoveryClient, environment); - - StepVerifier.withVirtualTime(() -> supplier.get()).expectSubscription() - .expectNext(Lists.list(instance("1host", false), instance("2host-secure", true))).thenCancel() - .verify(VERIFICATION_TIMEOUT); - - when(reactiveDiscoveryClient.getInstances(SERVICE_ID)).thenReturn( - Flux.just(instance("1host", false), instance("2host-secure", true), instance("3host", false))); - - StepVerifier.withVirtualTime(() -> supplier.get()).expectSubscription() - .expectNext( - Lists.list(instance("1host", false), instance("2host-secure", true), instance("3host", false))) - .thenCancel().verify(VERIFICATION_TIMEOUT); - } - - @Test - void shouldReturnEmptyInstancesListOnException() { - when(reactiveDiscoveryClient.getInstances(SERVICE_ID)) - .thenReturn(Flux.error(new RuntimeException("Exception"))); - - StepVerifier.withVirtualTime(() -> { - supplier = new DiscoveryClientServiceInstanceListSupplier(reactiveDiscoveryClient, environment); - return supplier.get(); - }).expectSubscription().expectNext(Collections.emptyList()).thenCancel().verify(VERIFICATION_TIMEOUT); - } - - @Test - void shouldReturnEmptyInstancesListOnTimeout() { - environment.setProperty(SERVICE_DISCOVERY_TIMEOUT, "100ms"); - when(reactiveDiscoveryClient.getInstances(SERVICE_ID)).thenReturn(Flux.never()); - StepVerifier.create(new DiscoveryClientServiceInstanceListSupplier(reactiveDiscoveryClient, environment).get()) - .expectSubscription().expectNext(Collections.emptyList()).thenCancel().verify(VERIFICATION_TIMEOUT); - } - - @Test - void shouldReturnRetrievedInstancesBlockingClient() { - StepVerifier.withVirtualTime(() -> { - when(discoveryClient.getInstances(SERVICE_ID)) - .thenReturn(Lists.list(instance("1host", false), instance("2host-secure", true))); - - supplier = new DiscoveryClientServiceInstanceListSupplier(discoveryClient, environment); - return supplier.get(); - }).expectSubscription().expectNext(Lists.list(instance("1host", false), instance("2host-secure", true))) - .thenCancel().verify(VERIFICATION_TIMEOUT); - } - - @Test - void shouldUpdateReturnRetrievedInstancesBlockingClient() { - StepVerifier.withVirtualTime(() -> { - when(discoveryClient.getInstances(SERVICE_ID)) - .thenReturn(Lists.list(instance("1host", false), instance("2host-secure", true))); - supplier = new DiscoveryClientServiceInstanceListSupplier(discoveryClient, environment); - supplier.get(); - - when(discoveryClient.getInstances(SERVICE_ID)).thenReturn( - Lists.list(instance("1host", false), instance("2host-secure", true), instance("3host", false))); - return supplier.get(); - }).expectSubscription() - .expectNext( - Lists.list(instance("1host", false), instance("2host-secure", true), instance("3host", false))) - .thenCancel().verify(VERIFICATION_TIMEOUT); - } - - @Test - void shouldReturnEmptyInstancesListOnExceptionBlockingClient() { - when(discoveryClient.getInstances(SERVICE_ID)).thenThrow(new RuntimeException("Exception")); - - StepVerifier.withVirtualTime(() -> { - supplier = new DiscoveryClientServiceInstanceListSupplier(discoveryClient, environment); - return supplier.get(); - }).expectSubscription().expectNext(Collections.emptyList()).thenCancel().verify(VERIFICATION_TIMEOUT); - } - - @Test - @Disabled // FIXME 3.0.0 - void shouldReturnEmptyInstancesListOnTimeoutBlockingClient() { - environment.setProperty(SERVICE_DISCOVERY_TIMEOUT, "100ms"); - when(discoveryClient.getInstances(SERVICE_ID)).thenAnswer(new AnswersWithDelay(200, new Returns( - Lists.list(instance("1host", false), instance("2host-secure", true), instance("3host", false))))); - StepVerifier.create(new DiscoveryClientServiceInstanceListSupplier(discoveryClient, environment).get()) - .expectSubscription().expectNext(Collections.emptyList()).thenCancel().verify(VERIFICATION_TIMEOUT); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java deleted file mode 100644 index d2bb0eea..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HealthCheckServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.time.Duration; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiFunction; - -import org.assertj.core.api.Assertions; -import org.assertj.core.util.Lists; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.server.LocalServerPort; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.loadbalancer.core.LoadBalancerTestUtils.buildLoadBalancerClientFactory; -import static org.springframework.cloud.loadbalancer.core.ServiceInstanceListSuppliersTestUtils.healthCheckFunction; - -/** - * Tests for {@link HealthCheckServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - * @author Roman Matiushchenko - * @author Roman Chigvintsev - * @author Sabyasachi Bhattacharya - */ -@SpringBootTest(classes = HealthCheckServiceInstanceListSupplierTests.TestApplication.class, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class HealthCheckServiceInstanceListSupplierTests { - - private static final String SERVICE_ID = "ignored-service"; - - private static final Duration VERIFY_TIMEOUT = Duration.ofSeconds(10); - - @LocalServerPort - private int port; - - private final WebClient webClient = WebClient.create(); - - private final RestTemplate restTemplate = new RestTemplate(); - - private LoadBalancerProperties properties; - - private HealthCheckServiceInstanceListSupplier listSupplier; - - @BeforeEach - void setUp() { - properties = new LoadBalancerProperties(); - } - - @AfterEach - void tearDown() { - if (listSupplier != null) { - listSupplier.destroy(); - listSupplier = null; - } - } - - @SuppressWarnings("ConstantConditions") - @Test - void shouldCheckInstanceWithProvidedHealthCheckPath() { - String serviceId = "ignored-service"; - properties.getHealthCheck().getPath().put("ignored-service", "/health"); - ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", serviceId, "127.0.0.1", port, - false); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(serviceId, properties), healthCheckFunction(webClient)); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - assertThat(alive).isTrue(); - } - - @Test - void shouldNotCheckInstanceWithNullHealthCheckPath() { - BiFunction> mockAliveFunction = mock(BiFunction.class); - String serviceId = "no-health-check-service"; - properties.getHealthCheck().getPath().put("no-health-check-service", null); - ServiceInstance serviceInstance = new DefaultServiceInstance("no-health-check-service-1", serviceId, - "127.0.0.1", port, false); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(serviceId, properties), mockAliveFunction); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - verify(mockAliveFunction, never()).apply(any(), any()); - assertThat(alive).isTrue(); - } - - @Test - void shouldNotCheckInstanceWithEmptyHealthCheckPath() { - BiFunction> mockAliveFunction = mock(BiFunction.class); - String serviceId = "no-health-check-service"; - properties.getHealthCheck().getPath().put("no-health-check-service", ""); - ServiceInstance serviceInstance = new DefaultServiceInstance("no-health-check-service-1", serviceId, - "127.0.0.1", port, false); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(serviceId, properties), mockAliveFunction); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - verify(mockAliveFunction, never()).apply(any(), any()); - assertThat(alive).isTrue(); - } - - @SuppressWarnings("ConstantConditions") - @Test - void shouldCheckInstanceWithProvidedHealthCheckPathWithRestTemplate() { - String serviceId = "ignored-service"; - properties.getHealthCheck().getPath().put("ignored-service", "/health"); - ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", serviceId, "127.0.0.1", port, - false); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(serviceId, properties), healthCheckFunction(restTemplate)); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - assertThat(alive).isTrue(); - } - - @SuppressWarnings("ConstantConditions") - @Test - void shouldCheckInstanceWithDefaultHealthCheckPath() { - String serviceId = "ignored-service"; - ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", serviceId, "127.0.0.1", port, - false); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(serviceId, properties), healthCheckFunction(webClient)); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - assertThat(alive).isTrue(); - } - - @SuppressWarnings("ConstantConditions") - @Test - void shouldReturnFalseIfEndpointNotFound() { - String serviceId = "ignored-service"; - ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", serviceId, "127.0.0.1", port, - false); - properties.getHealthCheck().getPath().put(serviceId, "/test"); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(serviceId, properties), healthCheckFunction(webClient)); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - assertThat(alive).isFalse(); - } - - @SuppressWarnings("ConstantConditions") - @Test - void shouldReturnFalseIfEndpointNotFoundWithRestTemplate() { - String serviceId = "ignored-service"; - ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", serviceId, "127.0.0.1", port, - false); - properties.getHealthCheck().getPath().put(serviceId, "/test"); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(serviceId, properties), healthCheckFunction(restTemplate)); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - assertThat(alive).isFalse(); - } - - @Test - void shouldReturnOnlyAliveService() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1, serviceInstance2))); - - HealthCheckServiceInstanceListSupplier mock = mock(HealthCheckServiceInstanceListSupplier.class); - Mockito.doReturn(Mono.just(true)).when(mock).isAlive(serviceInstance1); - Mockito.doReturn(Mono.just(false)).when(mock).isAlive(serviceInstance2); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return mock.isAlive(serviceInstance); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)).expectNoEvent(properties.getHealthCheck().getInterval()) - .thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldEmitOnEachAliveServiceInBatch() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1, serviceInstance2))); - - HealthCheckServiceInstanceListSupplier mock = mock(HealthCheckServiceInstanceListSupplier.class); - Mockito.doReturn(Mono.just(true)).when(mock).isAlive(serviceInstance1); - Mockito.doReturn(Mono.just(true)).when(mock).isAlive(serviceInstance2); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return mock.isAlive(serviceInstance); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)).expectNext(Lists.list(serviceInstance1, serviceInstance2)) - .expectNoEvent(properties.getHealthCheck().getInterval()).thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldEmitOnEntireBatchOfInstancesWhenUpdateDisabled() { - LoadBalancerProperties.HealthCheck healthCheck = properties.getHealthCheck(); - healthCheck.setInitialDelay(Duration.ofSeconds(1)); - healthCheck.setUpdateResultsList(false); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1, serviceInstance2))); - - HealthCheckServiceInstanceListSupplier mock = mock(HealthCheckServiceInstanceListSupplier.class); - Mockito.doReturn(Mono.just(true)).when(mock).isAlive(serviceInstance1); - Mockito.doReturn(Mono.just(true)).when(mock).isAlive(serviceInstance2); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return mock.isAlive(serviceInstance); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1, serviceInstance2)) - .expectNoEvent(properties.getHealthCheck().getInterval()).thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldNotFailIfIsAliveReturnsError() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1, serviceInstance2))); - - HealthCheckServiceInstanceListSupplier mock = mock(HealthCheckServiceInstanceListSupplier.class); - Mockito.doReturn(Mono.just(true)).when(mock).isAlive(serviceInstance1); - Mockito.doReturn(Mono.error(new RuntimeException("boom"))).when(mock).isAlive(serviceInstance2); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return mock.isAlive(serviceInstance); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)).expectNoEvent(properties.getHealthCheck().getInterval()) - .thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldEmitAllInstancesIfAllIsAliveChecksFailed() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1, serviceInstance2))); - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - if (serviceInstance == serviceInstance1) { - return Mono.just(false); - } - else { - return Mono.error(new RuntimeException("boom")); - } - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()).expectNext(Lists.list()) - .expectNoEvent(properties.getHealthCheck().getInterval()).thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldMakeInitialDaleyAfterPropertiesSet() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1))); - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return Mono.just(true); - } - }; - - listSupplier.afterPropertiesSet(); - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)).expectNoEvent(properties.getHealthCheck().getInterval()) - .thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldRepeatIsAliveChecksIndefinitely() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1, serviceInstance2))); - - HealthCheckServiceInstanceListSupplier mock = mock(HealthCheckServiceInstanceListSupplier.class); - Mockito.doReturn(Mono.just(false), Mono.just(true)).when(mock).isAlive(serviceInstance1); - Mockito.doReturn(Mono.error(new RuntimeException("boom"))).when(mock).isAlive(serviceInstance2); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return mock.isAlive(serviceInstance); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()).expectNext(Lists.list()) - .expectNoEvent(properties.getHealthCheck().getInterval()).expectNext(Lists.list(serviceInstance1)) - .expectNoEvent(properties.getHealthCheck().getInterval()).expectNext(Lists.list(serviceInstance1)) - .thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldTimeoutIsAliveCheck() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1))); - - HealthCheckServiceInstanceListSupplier mock = mock(HealthCheckServiceInstanceListSupplier.class); - Mockito.when(mock.isAlive(serviceInstance1)).thenReturn(Mono.never(), Mono.just(true)); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return mock.isAlive(serviceInstance); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNoEvent(properties.getHealthCheck().getInterval()).expectNext(Lists.list()) - .expectNoEvent(properties.getHealthCheck().getInterval()).expectNext(Lists.list(serviceInstance1)) - .expectNoEvent(properties.getHealthCheck().getInterval()).expectNext(Lists.list(serviceInstance1)) - .thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldUpdateInstances() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Flux> instances = Flux.just(Lists.list(serviceInstance1)) - .concatWith(Flux.just(Lists.list(serviceInstance1, serviceInstance2)) - .delayElements(properties.getHealthCheck().getInterval().dividedBy(2))); - Mockito.when(delegate.get()).thenReturn(instances); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return Mono.just(true); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)) - .thenAwait(properties.getHealthCheck().getInterval().dividedBy(2)) - .expectNext(Lists.list(serviceInstance1)).expectNext(Lists.list(serviceInstance1, serviceInstance2)) - .expectNoEvent(properties.getHealthCheck().getInterval()).expectNext(Lists.list(serviceInstance1)) - .expectNext(Lists.list(serviceInstance1, serviceInstance2)).thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldReturnAllInstancesWhenUpdateDisabled() { - LoadBalancerProperties.HealthCheck healthCheck = properties.getHealthCheck(); - healthCheck.setInitialDelay(Duration.ofSeconds(1)); - healthCheck.setUpdateResultsList(false); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Flux> instances = Flux.just(Lists.list(serviceInstance1)) - .concatWith(Flux.just(Lists.list(serviceInstance1, serviceInstance2)) - .delayElements(properties.getHealthCheck().getInterval().dividedBy(2))); - Mockito.when(delegate.get()).thenReturn(instances); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return Mono.just(true); - } - }; - - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)) - .thenAwait(properties.getHealthCheck().getInterval().dividedBy(2)) - .expectNext(Lists.list(serviceInstance1, serviceInstance2)) - .expectNoEvent(properties.getHealthCheck().getInterval()) - .expectNext(Lists.list(serviceInstance1, serviceInstance2)).thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldRefetchInstances() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - properties.getHealthCheck().setRepeatHealthCheck(false); - properties.getHealthCheck().setRefetchInstancesInterval(Duration.ofSeconds(1)); - properties.getHealthCheck().setRefetchInstances(true); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - when(delegate.getServiceId()).thenReturn(SERVICE_ID); - when(delegate.get()).thenReturn(Flux.just(Collections.singletonList(serviceInstance1))) - .thenReturn(Flux.just(Collections.singletonList(serviceInstance2))); - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return Mono.just(true); - } - }; - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)) - .thenAwait(properties.getHealthCheck().getRefetchInstancesInterval()) - .expectNext(Lists.list(serviceInstance2)).thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldRefetchInstancesWithRepeatingHealthCheck() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - properties.getHealthCheck().setRepeatHealthCheck(true); - properties.getHealthCheck().setRefetchInstancesInterval(Duration.ofSeconds(1)); - properties.getHealthCheck().setRefetchInstances(true); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - ServiceInstance serviceInstance2 = new DefaultServiceInstance("ignored-service-2", SERVICE_ID, "127.0.0.2", - port, false); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - when(delegate.getServiceId()).thenReturn(SERVICE_ID); - when(delegate.get()).thenReturn(Flux.just(Collections.singletonList(serviceInstance1))) - .thenReturn(Flux.just(Collections.singletonList(serviceInstance2))); - BiFunction> healthCheckFunc = healthCheckFunction(webClient); - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunc) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return Mono.just(true); - } - }; - return listSupplier.get(); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)) - .thenAwait(properties.getHealthCheck().getRefetchInstancesInterval()) - .expectNext(Lists.list(serviceInstance2)).thenCancel().verify(VERIFY_TIMEOUT); - } - - @Test - void shouldCacheResultIfAfterPropertiesSetInvoked() { - properties.getHealthCheck().setInitialDelay(Duration.ofSeconds(1)); - ServiceInstance serviceInstance1 = new DefaultServiceInstance("ignored-service-1", SERVICE_ID, "127.0.0.1", - port, false); - - AtomicInteger emitCounter = new AtomicInteger(); - - StepVerifier.withVirtualTime(() -> { - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.getServiceId()).thenReturn(SERVICE_ID); - Mockito.when(delegate.get()).thenReturn(Flux.just(Lists.list(serviceInstance1))); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)) { - @Override - protected Mono isAlive(ServiceInstance serviceInstance) { - return Mono.just(true); - } - - @Override - protected Flux> healthCheckFlux(List instances) { - return super.healthCheckFlux(instances).doOnNext(it -> emitCounter.incrementAndGet()); - } - }; - - listSupplier.afterPropertiesSet(); - - return listSupplier.get().take(1).concatWith(listSupplier.get().take(1)); - }).expectSubscription().expectNoEvent(properties.getHealthCheck().getInitialDelay()) - .expectNext(Lists.list(serviceInstance1)).expectNext(Lists.list(serviceInstance1)).thenCancel() - .verify(VERIFY_TIMEOUT); - - Assertions.assertThat(emitCounter).hasValue(1); - } - - @Test - void shouldCancelSubscription() { - - final AtomicInteger instancesCanceled = new AtomicInteger(); - final AtomicBoolean subscribed = new AtomicBoolean(); - ServiceInstanceListSupplier delegate = mock(ServiceInstanceListSupplier.class); - Mockito.when(delegate.get()).thenReturn(Flux.>never() - .doOnSubscribe(subscription -> subscribed.set(true)).doOnCancel(instancesCanceled::incrementAndGet)); - - listSupplier = new HealthCheckServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)); - - listSupplier.afterPropertiesSet(); - - Awaitility.await("delegate subscription").pollDelay(Duration.ofMillis(50)).atMost(VERIFY_TIMEOUT) - .untilTrue(subscribed); - - Assertions.assertThat(instancesCanceled).hasValue(0); - - listSupplier.destroy(); - Awaitility.await("delegate cancellation").pollDelay(Duration.ofMillis(100)).atMost(VERIFY_TIMEOUT) - .untilAsserted(() -> Assertions.assertThat(instancesCanceled).hasValue(1)); - } - - @SuppressWarnings("ConstantConditions") - @Test - void shouldCheckInstanceWithProvidedHealthCheckPathWithQueryParams() { - String serviceId = "ignored-service"; - properties.getHealthCheck().getPath().put("ignored-service", "/health?someparam=somevalue"); - ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", serviceId, "127.0.0.1", port, - false); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), - buildLoadBalancerClientFactory(SERVICE_ID, properties), healthCheckFunction(webClient)); - - boolean alive = listSupplier.isAlive(serviceInstance).block(); - - assertThat(alive).isTrue(); - } - - @Test - void shouldCheckUseProvidedPortForHealthCheckRequest() { - Throwable exception = catchThrowable(() -> { - String serviceId = "ignored-service"; - properties.getHealthCheck().setPort(8888); - LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - when(loadBalancerClientFactory.getProperties(serviceId)).thenReturn(properties); - ServiceInstance serviceInstance = new DefaultServiceInstance("ignored-service-1", serviceId, "127.0.0.1", - port, false); - listSupplier = new HealthCheckServiceInstanceListSupplier( - ServiceInstanceListSuppliers.from(serviceId, serviceInstance), loadBalancerClientFactory, - healthCheckFunction(webClient)); - - listSupplier.isAlive(serviceInstance).block(); - }); - - assertThat(exception).hasMessageContaining("Connection refused: /127.0.0.1:888"); - } - - @Configuration(proxyBeanMethods = false) - @EnableAutoConfiguration - @RestController - static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(HealthCheckServiceInstanceListSupplierTests.TestApplication.class, args); - } - - @GetMapping("/health") - void healthCheck(@RequestParam(value = "someparam", required = false) String param) { - - } - - @GetMapping("/actuator/health") - void defaultHealthCheck() { - - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplierTests.java deleted file mode 100644 index e53a65bc..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/HintBasedServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.mock.http.client.MockClientHttpRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.loadbalancer.core.LoadBalancerTestUtils.buildLoadBalancerClientFactory; - -/** - * Tests for {@link HintBasedServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - */ -class HintBasedServiceInstanceListSupplierTests { - - private static final String SERVICE_ID = "test"; - - private final DiscoveryClientServiceInstanceListSupplier delegate = mock( - DiscoveryClientServiceInstanceListSupplier.class); - - private final LoadBalancerProperties properties = new LoadBalancerProperties(); - - private final RequestDataContext requestContext = new RequestDataContext( - new RequestData(new MockClientHttpRequest())); - - private HintBasedServiceInstanceListSupplier supplier; - - private final ServiceInstance first = serviceInstance("test-1", buildHintMetadata("test1")); - - private final ServiceInstance second = serviceInstance("test-2", buildHintMetadata("test2")); - - private final ServiceInstance third = serviceInstance("test-3", new HashMap<>()); - - @BeforeEach - void setUp() { - properties.setHintHeaderName("X-Test"); - when(delegate.get(any())).thenReturn(Flux.just(Arrays.asList(first, second, third))); - when(delegate.getServiceId()).thenReturn(SERVICE_ID); - supplier = new HintBasedServiceInstanceListSupplier(delegate, - buildLoadBalancerClientFactory(SERVICE_ID, properties)); - } - - @Test - void shouldReturnInstancesForHintFromHeaderWhenAvailable() { - requestContext.setHint("test1"); - requestContext.getClientRequest().getHeaders().add("X-Test", "test2"); - Request request = new DefaultRequest<>(requestContext); - - List filtered = supplier.get(request).blockFirst(); - - assertThat(filtered).hasSize(1); - assertThat(filtered.get(0).getInstanceId()).isEqualTo("test-2"); - } - - @Test - void shouldReturnInstancesForHintFromPropertiesWhenNoHintHeader() { - requestContext.setHint("test1"); - Request request = new DefaultRequest<>(requestContext); - - List filtered = supplier.get(request).blockFirst(); - - assertThat(filtered).hasSize(1); - assertThat(filtered.get(0).getInstanceId()).isEqualTo("test-1"); - } - - @Test - void shouldReturnAllInstancesWhenNoHint() { - Request request = new DefaultRequest<>(requestContext); - - List filtered = supplier.get(request).blockFirst(); - - assertThat(filtered).hasSize(3); - } - - @Test - void shouldReturnAllInstancesWhenHintNotMatched() { - requestContext.getClientRequest().getHeaders().add("X-Test", "testX"); - Request request = new DefaultRequest<>(requestContext); - - List filtered = supplier.get(request).blockFirst(); - - assertThat(filtered).hasSize(3); - } - - @Test - void shouldReturnAllInstancesWhenRequestContextNull() { - Request request = new DefaultRequest<>(null); - - List filtered = supplier.get(request).blockFirst(); - - assertThat(filtered).hasSize(3); - } - - @Test - void shouldReturnAllInstancesWhenClientRequestNull() { - Request request = new DefaultRequest<>(new RequestDataContext(null)); - - List filtered = supplier.get(request).blockFirst(); - - assertThat(filtered).hasSize(3); - } - - private DefaultServiceInstance serviceInstance(String instanceId, Map metadata) { - return new DefaultServiceInstance(instanceId, SERVICE_ID, "http://test.test", 9080, false, metadata); - } - - private Map buildHintMetadata(String zone) { - Map metadata = new HashMap<>(); - metadata.put("hint", zone); - return metadata; - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceListTest.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceListTest.java deleted file mode 100644 index 723bf4bb..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LazyWeightedServiceInstanceListTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; - -import static java.util.stream.Collectors.summingInt; -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LazyWeightedServiceInstanceList}. - * - * @author Zhuozhi Ji - */ -class LazyWeightedServiceInstanceListTest { - - @Test - void shouldCreateListWithSizeEqualToSumOfRatio() { - List serviceInstances = new ArrayList<>(); - int[] weights = new int[10]; - for (int i = 0; i < 10; i++) { - int weight = (1 << i) * 100; - weights[i] = weight; - serviceInstances.add(serviceInstance("test-" + i, buildWeightMetadata(weight))); - } - - int total = Arrays.stream(weights).sum() / 100; - List list = new LazyWeightedServiceInstanceList(serviceInstances, weights); - assertThat(list).hasSize(total); - } - - @Test - void shouldFillListWithAllNullElementsIfNotAccessed() { - List serviceInstances = new ArrayList<>(); - int[] weights = new int[10]; - for (int i = 0; i < 10; i++) { - int weight = (1 << i) * 100; - weights[i] = weight; - serviceInstances.add(serviceInstance("test-" + i, buildWeightMetadata(weight))); - } - - LazyWeightedServiceInstanceList list = new LazyWeightedServiceInstanceList(serviceInstances, weights); - for (int i = 0; i < list.size(); i++) { - assertThat(list.expanded[i]).isNull(); - } - } - - @Test - void shouldFillAllElementsIfGreaterPositionAccessed() { - List serviceInstances = new ArrayList<>(); - int[] weights = new int[10]; - for (int i = 0; i < 10; i++) { - int weight = (1 << i) * 100; - weights[i] = weight; - serviceInstances.add(serviceInstance("test-" + i, buildWeightMetadata(weight))); - } - - LazyWeightedServiceInstanceList list = new LazyWeightedServiceInstanceList(serviceInstances, weights); - list.get(list.size() - 1); - for (int i = 0; i < list.size(); i++) { - assertThat(list.expanded[i]).isNotNull(); - } - } - - @Test - void shouldFillAllElementsCorrectlyIfConcurrentRandomAccess() throws InterruptedException { - List serviceInstances = new ArrayList<>(); - int[] weights = new int[10]; - for (int i = 0; i < 10; i++) { - int weight = 1 << i; - weights[i] = weight; - serviceInstances.add(serviceInstance("test-" + i, buildWeightMetadata(weight))); - } - - Random random = new Random(); - int processors = Runtime.getRuntime().availableProcessors(); - ThreadPoolExecutor executor = new ThreadPoolExecutor(processors, processors, 1, TimeUnit.SECONDS, - new LinkedBlockingQueue<>()); - LazyWeightedServiceInstanceList list = new LazyWeightedServiceInstanceList(serviceInstances, weights); - - CountDownLatch countDownLatch = new CountDownLatch(list.size()); - for (int i = 0; i < list.size(); i++) { - int p = random.nextInt(list.size()); - executor.execute(() -> { - list.get(p); - countDownLatch.countDown(); - }); - } - countDownLatch.await(); - - // make sure all instances are expanded - list.get(list.size() - 1); - - Map counter = Arrays.stream(list.expanded) - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - for (int i = 0; i < 10; i++) { - assertThat(counter).containsEntry(serviceInstances.get(i).getInstanceId(), weights[i]); - } - } - - private ServiceInstance serviceInstance(String instanceId, Map metadata) { - return new DefaultServiceInstance(instanceId, "test", "localhost", 8080, false, metadata); - } - - private Map buildWeightMetadata(Object weight) { - Map metadata = new HashMap<>(); - metadata.put("weight", weight.toString()); - return metadata; - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformerTests.java deleted file mode 100644 index a7d8a376..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerServiceInstanceCookieTransformerTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; -import org.springframework.mock.http.client.MockClientHttpRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.loadbalancer.core.LoadBalancerTestUtils.buildLoadBalancerClientFactory; - -/** - * Tests for {@link LoadBalancerServiceInstanceCookieTransformer}. - * - * @author Olga Maciaszek-Sharma - */ -class LoadBalancerServiceInstanceCookieTransformerTests { - - private static final String SERVICE_ID = "test"; - - LoadBalancerProperties properties = new LoadBalancerProperties(); - - LoadBalancerServiceInstanceCookieTransformer transformer = new LoadBalancerServiceInstanceCookieTransformer( - buildLoadBalancerClientFactory(SERVICE_ID, properties)); - - ServiceInstance serviceInstance = new DefaultServiceInstance("test-01", SERVICE_ID, "host", 8080, false); - - HttpRequest request = new MockClientHttpRequest(); - - @BeforeEach - void setUp() { - properties.getStickySession().setAddServiceInstanceCookie(true); - } - - @Test - void shouldAddServiceInstanceCookieHeader() { - HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); - - assertThat(newRequest.getHeaders().get(HttpHeaders.COOKIE)).hasSize(1); - assertThat(newRequest.getHeaders().get(HttpHeaders.COOKIE)).containsExactly("sc-lb-instance-id=test-01"); - } - - @Test - void shouldAppendServiceInstanceCookieHeaderIfCookiesPresent() { - request.getHeaders().add(HttpHeaders.COOKIE, "testCookieName=testCookieValue"); - - HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); - - assertThat(newRequest.getHeaders().get(HttpHeaders.COOKIE)).containsExactly("testCookieName=testCookieValue", - "sc-lb-instance-id=test-01"); - } - - @Test - void shouldReturnPassedRequestWhenNoServiceInstance() { - HttpRequest newRequest = transformer.transformRequest(request, null); - - assertThat(newRequest.getHeaders()).doesNotContainKey(HttpHeaders.COOKIE); - } - - @Test - void shouldReturnPassedRequestWhenNullServiceInstanceCookieName() { - properties.getStickySession().setInstanceIdCookieName(null); - HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); - - assertThat(newRequest.getHeaders()).doesNotContainKey(HttpHeaders.COOKIE); - } - - @Test - void shouldReturnPassedRequestWhenEmptyServiceInstanceCookieName() { - properties.getStickySession().setInstanceIdCookieName(""); - HttpRequest newRequest = transformer.transformRequest(request, serviceInstance); - - assertThat(newRequest.getHeaders()).doesNotContainKey(HttpHeaders.COOKIE); - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTestUtils.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTestUtils.java deleted file mode 100644 index c3c44d41..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTestUtils.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; - -/** - * @author Olga Maciaszek-Sharma - */ -final class LoadBalancerTestUtils { - - private LoadBalancerTestUtils() { - throw new UnsupportedOperationException("Cannot instantiate utility class."); - } - - static LoadBalancerClientFactory buildLoadBalancerClientFactory(String serviceId, - LoadBalancerProperties properties) { - LoadBalancerClientsProperties clientsProperties = new LoadBalancerClientsProperties(); - clientsProperties.getClients().put(serviceId, properties); - return new LoadBalancerClientFactory(clientsProperties); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java deleted file mode 100644 index 08a3007b..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/LoadBalancerTests.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.beans.factory.ObjectProvider; -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.cache.annotation.EnableCaching; -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers; -import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider; -import org.springframework.context.annotation.Bean; -import org.springframework.core.ResolvableType; -import org.springframework.core.env.Environment; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.BDDAssertions.then; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author Spencer Gibb - */ -@SpringBootTest -class LoadBalancerTests { - - @Autowired - private LoadBalancerClientFactory clientFactory; - - @Test - void roundRobbinLoadbalancerWorks() { - ReactiveLoadBalancer reactiveLoadBalancer = this.clientFactory.getInstance("myservice", - ReactiveLoadBalancer.class, ServiceInstance.class); - - then(reactiveLoadBalancer).isInstanceOf(RoundRobinLoadBalancer.class); - then(reactiveLoadBalancer).isInstanceOf(ReactorLoadBalancer.class); - ReactorLoadBalancer loadBalancer = (ReactorLoadBalancer) reactiveLoadBalancer; - - // order dependent on seedPosition -1 of RoundRobinLoadBalancer - List hosts = Arrays.asList("ahost", "chost", "bhostsecure", "ahost"); - - assertLoadBalancer(loadBalancer, hosts); - } - - private void assertLoadBalancer(ReactorLoadBalancer loadBalancer, List hosts) { - for (String host : hosts) { - Mono> source = loadBalancer.choose(); - StepVerifier.create(source).consumeNextWith(response -> { - then(response).isNotNull(); - then(response.hasServer()).isTrue(); - - ServiceInstance instance = response.getServer(); - then(instance).isNotNull(); - then(instance.getHost()).as("instance host is incorrent %s", host).isEqualTo(host); - - if (host.contains("secure")) { - then(instance.isSecure()).isTrue(); - } - else { - then(instance.isSecure()).isFalse(); - } - }).verifyComplete(); - } - } - - @Test - void emptyHosts() { - ResolvableType type = ResolvableType.forClassWithGenerics(ReactorLoadBalancer.class, ServiceInstance.class); - ReactorLoadBalancer loadBalancer = this.clientFactory.getInstance("unknownservice", type); - - then(loadBalancer).isInstanceOf(RoundRobinLoadBalancer.class); - - Mono> source = loadBalancer.choose(); - StepVerifier.create(source).consumeNextWith(response -> { - then(response).isNotNull(); - then(response.hasServer()).isFalse(); - }).verifyComplete(); - } - - @Test - void staticConfigurationWorks() { - String serviceId = "test1"; - RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(ServiceInstanceListSuppliers - .toProvider(serviceId, instance(serviceId, "1host", false), instance(serviceId, "2host-secure", true)), - serviceId, -1); - assertLoadBalancer(loadBalancer, Arrays.asList("1host", "2host-secure")); - } - - private static DefaultServiceInstance instance(String serviceId, String host, boolean secure) { - return new DefaultServiceInstance(serviceId, serviceId, host, 80, secure); - } - - @SuppressWarnings("ConstantConditions") - @Test - void canPassHintViaRequest() { - String serviceId = "test1"; - RoundRobinLoadBalancer loadBalancer = new TestHintLoadBalancer(ServiceInstanceListSuppliers.toProvider( - serviceId, instance(serviceId, "1host", false), instance(serviceId, "2host-secure", true)), serviceId); - Request request = new DefaultRequest<>(new DefaultRequestContext("test2", "test2")); - - ServiceInstance serviceInstance = loadBalancer.choose(request).block().getServer(); - - assertThat(serviceInstance.getServiceId()).isEqualTo("test2"); - } - - @Test - void selectedInstanceCallback() { - String serviceId = "test1"; - ServiceInstance serviceInstance = instance(serviceId, "1host", false); - SameInstancePreferenceServiceInstanceListSupplier supplier = mock( - SameInstancePreferenceServiceInstanceListSupplier.class); - when(supplier.get(any())).thenReturn(Flux.just(Collections.singletonList(serviceInstance))); - RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(new SimpleObjectProvider<>(supplier), - serviceId); - - loadBalancer.choose().block(); - - verify(supplier).selectedServiceInstance(serviceInstance); - } - - private static class TestHintLoadBalancer extends RoundRobinLoadBalancer { - - TestHintLoadBalancer(ObjectProvider serviceInstanceListSupplierProvider, - String serviceId) { - super(serviceInstanceListSupplierProvider, serviceId); - } - - @SuppressWarnings("rawtypes") - @Override - public Mono> choose(Request request) { - if (request.getContext() instanceof DefaultRequestContext requestContext) { - return Mono.just(new DefaultResponse(instance(requestContext.getHint(), "host", false))); - } - return Mono.empty(); - } - - } - - @EnableAutoConfiguration - @SpringBootConfiguration(proxyBeanMethods = false) - @LoadBalancerClients({ @LoadBalancerClient(name = "myservice", configuration = MyServiceConfig.class), - @LoadBalancerClient(name = "unknownservice", configuration = MyServiceConfig.class) }) - @EnableCaching - protected static class Config { - - } - - protected static class MyServiceConfig { - - @Bean - public RoundRobinLoadBalancer roundRobinContextLoadBalancer(LoadBalancerClientFactory clientFactory, - Environment env) { - String serviceId = LoadBalancerClientFactory.getName(env); - return new RoundRobinLoadBalancer( - clientFactory.getLazyProvider(serviceId, ServiceInstanceListSupplier.class), serviceId, -1); - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancerTests.java deleted file mode 100644 index b57f4f51..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RandomLoadBalancerTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Arrays; -import java.util.Collections; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link RandomLoadBalancer}. - * - * @author Olga Maciaszek-Sharma - */ -class RandomLoadBalancerTests { - - private final ServiceInstance serviceInstance = new DefaultServiceInstance(); - - private RandomLoadBalancer loadBalancer; - - @Test - void shouldReturnOneServiceInstance() { - DiscoveryClientServiceInstanceListSupplier supplier = mock(DiscoveryClientServiceInstanceListSupplier.class); - when(supplier.get(any())).thenReturn(Flux.just(Arrays.asList(serviceInstance, new DefaultServiceInstance()))); - loadBalancer = new RandomLoadBalancer(new SimpleObjectProvider<>(supplier), "test"); - - Response response = loadBalancer.choose().block(); - - assertThat(response.hasServer()).isTrue(); - } - - @Test - void shouldReturnEmptyResponseWhenSupplierNotAvailable() { - loadBalancer = new RandomLoadBalancer(new SimpleObjectProvider<>(null), "test"); - - Response response = loadBalancer.choose().block(); - - assertThat(response.hasServer()).isFalse(); - } - - @Test - void shouldReturnEmptyResponseWhenNoInstancesAvailable() { - DiscoveryClientServiceInstanceListSupplier supplier = mock(DiscoveryClientServiceInstanceListSupplier.class); - when(supplier.get(any())).thenReturn(Flux.just(Collections.emptyList())); - loadBalancer = new RandomLoadBalancer(new SimpleObjectProvider<>(supplier), "test"); - - Response response = loadBalancer.choose().block(); - - assertThat(response.hasServer()).isFalse(); - } - - @Test - void shouldTriggerSelectedInstanceCallback() { - SameInstancePreferenceServiceInstanceListSupplier supplier = mock( - SameInstancePreferenceServiceInstanceListSupplier.class); - when(supplier.get(any())).thenReturn(Flux.just(Collections.singletonList(serviceInstance))); - loadBalancer = new RandomLoadBalancer(new SimpleObjectProvider<>(supplier), "test"); - - Response response = loadBalancer.choose().block(); - - assertThat(response.hasServer()).isTrue(); - assertThat(response.getServer()).isEqualTo(serviceInstance); - verify((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstance); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplierTests.java deleted file mode 100644 index ad2aee6e..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RequestBasedStickySessionServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Arrays; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.http.HttpHeaders; -import org.springframework.web.reactive.function.client.ClientRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.loadbalancer.core.LoadBalancerTestUtils.buildLoadBalancerClientFactory; - -/** - * Tests for {@link RequestBasedStickySessionServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - */ -class RequestBasedStickySessionServiceInstanceListSupplierTests { - - private static final String SERVICE_ID = "test"; - - private final DiscoveryClientServiceInstanceListSupplier delegate = mock( - DiscoveryClientServiceInstanceListSupplier.class); - - private final LoadBalancerProperties properties = new LoadBalancerProperties(); - - private final RequestBasedStickySessionServiceInstanceListSupplier supplier = new RequestBasedStickySessionServiceInstanceListSupplier( - delegate, buildLoadBalancerClientFactory(SERVICE_ID, properties)); - - private final ClientRequest clientRequest = mock(ClientRequest.class); - - private final ServiceInstance first = serviceInstance("test-1"); - - private final ServiceInstance second = serviceInstance("test-2"); - - private final ServiceInstance third = serviceInstance("test-3"); - - @BeforeEach - void setUp() { - when(delegate.get(any())).thenReturn(Flux.just(Arrays.asList(first, second, third))); - } - - @Test - void shouldReturnInstanceBasedOnCookieFromClientRequest() { - HttpHeaders headers = new HttpHeaders(); - headers.add(properties.getStickySession().getInstanceIdCookieName(), "test-1"); - when(clientRequest.cookies()).thenReturn(headers); - Request request = new DefaultRequest<>( - new RequestDataContext(new RequestData(clientRequest))); - - List serviceInstances = supplier.get(request).blockFirst(); - - assertThat(serviceInstances).hasSize(1); - assertThat(serviceInstances.get(0).getInstanceId()).isEqualTo("test-1"); - } - - @Test - void shouldReturnAllDelegateInstancesIfInstanceBasedOnCookieFromClientRequestNotFound() { - HttpHeaders headers = new HttpHeaders(); - headers.add(properties.getStickySession().getInstanceIdCookieName(), "test-4"); - when(clientRequest.cookies()).thenReturn(headers); - Request request = new DefaultRequest<>( - new RequestDataContext(new RequestData(clientRequest))); - - List serviceInstances = supplier.get(request).blockFirst(); - - assertThat(serviceInstances).hasSize(3); - } - - @Test - void shouldReturnAllInstancesFromDelegateIfClientRequestHasNoCookie() { - when(clientRequest.cookies()).thenReturn(new HttpHeaders()); - Request request = new DefaultRequest<>( - new RequestDataContext(new RequestData(clientRequest))); - - List serviceInstances = supplier.get(request).blockFirst(); - - assertThat(serviceInstances).hasSize(3); - } - - @Test - void shouldReturnAllInstancesFromDelegateIfNotSupportedRequestContext() { - Request request = new DefaultRequest<>(new DefaultRequestContext(clientRequest)); - - List serviceInstances = supplier.get(request).blockFirst(); - - assertThat(serviceInstances).hasSize(3); - } - - private DefaultServiceInstance serviceInstance(String instanceId) { - return new DefaultServiceInstance(instanceId, SERVICE_ID, "http://test.test", 9080, false); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplierTests.java deleted file mode 100644 index c8befdab..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RetryAwareServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.List; - -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.RetryableRequestContext; -import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * Tests for {@link RetryAwareServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - * @author Jürgen Kreitler - */ -class RetryAwareServiceInstanceListSupplierTests { - - private final String serviceId = "test"; - - private static DefaultServiceInstance instance(String serviceId, String host, boolean secure) { - return new DefaultServiceInstance(serviceId, serviceId, host, 80, secure); - } - - @Test - void shouldReturnEmptyListIfNoInstances() { - ServiceInstanceListSupplier delegate = ServiceInstanceListSuppliers.from(serviceId); - ServiceInstanceListSupplier supplier = new RetryAwareServiceInstanceListSupplier(delegate); - - List returnedInstances = supplier.get(new DefaultRequest<>(new RetryableRequestContext(null))) - .blockFirst(); - - assertThat(returnedInstances).isEmpty(); - } - - @Test - void shouldReturnFilteredInstances() { - ServiceInstance firstInstance = instance(serviceId, "1host", false); - ServiceInstance secondInstance = instance(serviceId, "2host-secure", true); - ServiceInstanceListSupplier delegate = ServiceInstanceListSuppliers.from(serviceId, firstInstance, - secondInstance); - ServiceInstanceListSupplier supplier = new RetryAwareServiceInstanceListSupplier(delegate); - - List returnedInstances = supplier - .get(new DefaultRequest<>(new RetryableRequestContext(firstInstance))).blockFirst(); - - assertThat(returnedInstances).containsExactly(secondInstance); - } - - @Test - void shouldReturnAllInstancesIfFilteredInstancesEmpty() { - ServiceInstance firstInstance = instance(serviceId, "1host", false); - ServiceInstanceListSupplier delegate = ServiceInstanceListSuppliers.from(serviceId, firstInstance); - ServiceInstanceListSupplier supplier = new RetryAwareServiceInstanceListSupplier(delegate); - - List returnedInstances = supplier - .get(new DefaultRequest<>(new RetryableRequestContext(firstInstance))).blockFirst(); - - assertThat(returnedInstances).containsExactly(firstInstance); - } - - @Test - void shouldCallSelectedServiceInstanceOnItsDelegate() { - ServiceInstance firstInstance = instance(serviceId, "1host", false); - TestSelectedServiceInstanceSupplier delegate = mock(TestSelectedServiceInstanceSupplier.class); - DelegatingServiceInstanceListSupplier supplier = new RetryAwareServiceInstanceListSupplier(delegate); - supplier.selectedServiceInstance(firstInstance); - verify(delegate, times(1)).selectedServiceInstance(any(ServiceInstance.class)); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancerTests.java deleted file mode 100644 index 48d70d08..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/RoundRobinLoadBalancerTests.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.loadbalancer.support.SimpleObjectProvider; - -import static java.lang.Integer.MAX_VALUE; -import static java.lang.Integer.MIN_VALUE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -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 Zhuozhi JI - * @author Jürgen Kreitler - */ -class RoundRobinLoadBalancerTests { - - @Test - void shouldOrderEnforcedWhenPositive() { - assertOrderEnforced(0); - } - - @Test - void shouldOrderEnforcedWhenNegative() { - assertOrderEnforced(MIN_VALUE); - } - - @Test - void shouldOrderEnforcedWhenPositiveOverflow() { - assertOrderEnforced(MAX_VALUE); - } - - @Test - void shouldNotMovePositionIfOnlyOneInstance() { - ServiceInstanceListSupplier supplier = mock(ServiceInstanceListSupplier.class); - when(supplier.get(any())).thenReturn(Flux.just(Collections.singletonList(new DefaultServiceInstance()))); - RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(new SimpleObjectProvider<>(supplier), - "shouldNotMovePositionIfOnlyOneInstance", 0); - - loadBalancer.choose().block(); - assertThat(loadBalancer.position).hasValue(0); - - loadBalancer.choose().block(); - assertThat(loadBalancer.position).hasValue(0); - } - - @Test - void shouldCallSelectedServiceInstanceIfSupplierOrItsDelegateIsInstanceOf() { - TestSelectedServiceInstanceSupplier delegate = mock(TestSelectedServiceInstanceSupplier.class); - DelegatingServiceInstanceListSupplier supplier = new RetryAwareServiceInstanceListSupplier(delegate); - when(delegate.get(any())).thenReturn(Flux.just(Collections.singletonList(new DefaultServiceInstance()))); - RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(new SimpleObjectProvider<>(supplier), - "shouldNotMovePositionIfOnlyOneInstance", 0); - - loadBalancer.choose().block(); - verify(delegate, times(1)).selectedServiceInstance(any(ServiceInstance.class)); - } - - @SuppressWarnings("all") - void assertOrderEnforced(int seed) { - List instances = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - ServiceInstance instance = mock(ServiceInstance.class); - when(instance.getInstanceId()).thenReturn(i + ""); - instances.add(instance); - } - SameInstancePreferenceServiceInstanceListSupplier supplier = mock( - SameInstancePreferenceServiceInstanceListSupplier.class); - when(supplier.get(any())).thenReturn(Flux.just(instances)); - - RoundRobinLoadBalancer loadBalancer = new RoundRobinLoadBalancer(new SimpleObjectProvider<>(supplier), - "shouldStartFromZeroWhenPositiveOverflow", seed); - - for (int i = 0; i < 10; i++) { - int instanceId = ((seed + 1 + i) & MAX_VALUE) % instances.size(); - ServiceInstance chosen = loadBalancer.choose().block().getServer(); - assertThat(chosen.getInstanceId()).isEqualTo(instanceId + ""); - } - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplierTests.java deleted file mode 100644 index cb29c871..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/SameInstancePreferenceServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Arrays; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link SameInstancePreferenceServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - * @author Jürgen Kreitler - */ -class SameInstancePreferenceServiceInstanceListSupplierTests { - - private final DiscoveryClientServiceInstanceListSupplier delegate = mock( - DiscoveryClientServiceInstanceListSupplier.class); - - private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - - private SameInstancePreferenceServiceInstanceListSupplier supplier; - - private final ServiceInstance first = serviceInstance("test-1"); - - private final ServiceInstance second = serviceInstance("test-2"); - - private final ServiceInstance third = serviceInstance("test-3"); - - @BeforeEach - void setUp() { - LoadBalancerProperties properties = new LoadBalancerProperties(); - when(loadBalancerClientFactory.getProperties(any())).thenReturn(properties); - supplier = new SameInstancePreferenceServiceInstanceListSupplier(delegate, loadBalancerClientFactory); - } - - @Test - void shouldReturnPreviouslySelectedInstanceIfAvailable() { - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(first, second, third))); - supplier.selectedServiceInstance(first); - - List instances = supplier.get().blockFirst(); - - assertThat(instances).hasSize(1); - assertThat(instances.get(0)).isEqualTo(first); - } - - @Test - void shouldReturnAllInstancesFromDelegateIfNoPreviouslySelectedInstance() { - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(first, second, third))); - - List instances = supplier.get().blockFirst(); - - assertThat(instances).hasSize(3); - } - - @Test - void shouldReturnAllInstancesFromDelegateIfPreviouslySelectedInstanceIsNotAvailable() { - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(second, third))); - supplier.selectedServiceInstance(first); - - List instances = supplier.get().blockFirst(); - - assertThat(instances).hasSize(2); - } - - @Test - void shouldCallGetRequestOnDelegate() { - Request request = new DefaultRequest<>(new DefaultRequestContext()); - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(first, second, third))); - when(delegate.get(request)).thenReturn(Flux.just(Arrays.asList(first, second))); - - List instances = supplier.get(request).blockFirst(); - - assertThat(instances).hasSize(2); - } - - @Test - void shouldCallSelectedServiceInstanceOnItsDelegate() { - ServiceInstance firstInstance = serviceInstance("test-4"); - TestSelectedServiceInstanceSupplier delegate = mock(TestSelectedServiceInstanceSupplier.class); - DelegatingServiceInstanceListSupplier supplier = new SameInstancePreferenceServiceInstanceListSupplier( - delegate); - supplier.selectedServiceInstance(firstInstance); - verify(delegate, times(1)).selectedServiceInstance(any(ServiceInstance.class)); - } - - private DefaultServiceInstance serviceInstance(String instanceId) { - return new DefaultServiceInstance(instanceId, "test", "http://test.test", 9080, false); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java deleted file mode 100644 index 9bfb0f38..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSupplierBuilderTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2013-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.client.loadbalancer.LoadBalancerClientsProperties; -import org.springframework.cloud.loadbalancer.cache.LoadBalancerCacheManager; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Import; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.fail; -import static org.mockito.Mockito.mock; - -public class ServiceInstanceListSupplierBuilderTests { - - @Test - public void testBuilder() { - new ApplicationContextRunner().withUserConfiguration(CacheTestConfig.class).run(context -> { - ServiceInstanceListSupplier supplier = ServiceInstanceListSupplier.builder().withDiscoveryClient() - .withHealthChecks().withWeighted().build(context); - assertThat(supplier).isInstanceOf(WeightedServiceInstanceListSupplier.class); - DelegatingServiceInstanceListSupplier delegating = (DelegatingServiceInstanceListSupplier) supplier; - assertThat(delegating.getDelegate()).isInstanceOf(HealthCheckServiceInstanceListSupplier.class); - delegating = (DelegatingServiceInstanceListSupplier) delegating.getDelegate(); - assertThat(delegating.getDelegate()).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Test - public void testIllegalArgumentExceptionThrownWhenBaseBuilderNull() { - new ApplicationContextRunner().withUserConfiguration(CacheTestConfig.class).run(context -> { - try { - ServiceInstanceListSupplier.builder().withHealthChecks().build(context); - fail("Should have thrown exception."); - } - catch (Exception exception) { - assertThat(exception).isInstanceOf(IllegalArgumentException.class); - } - - }); - } - - @Test - public void testDelegateReturnedIfLoadBalancerCacheManagerNotAvailable() { - new ApplicationContextRunner().withUserConfiguration(BaseTestConfig.class).run(context -> { - ServiceInstanceListSupplier supplier = ServiceInstanceListSupplier.builder().withDiscoveryClient() - .withHealthChecks().withCaching().build(context); - assertThat(supplier).isNotInstanceOf(CachingServiceInstanceListSupplier.class); - assertThat(supplier).isInstanceOf(HealthCheckServiceInstanceListSupplier.class); - DelegatingServiceInstanceListSupplier delegating = (DelegatingServiceInstanceListSupplier) supplier; - assertThat(delegating.getDelegate()).isInstanceOf(DiscoveryClientServiceInstanceListSupplier.class); - }); - } - - @Import(BaseTestConfig.class) - private static class CacheTestConfig { - - @Bean - public LoadBalancerCacheManager cacheManager() { - return mock(LoadBalancerCacheManager.class); - } - - } - - private static class BaseTestConfig { - - @Bean - public ReactiveDiscoveryClient reactiveDiscoveryClient() { - return mock(ReactiveDiscoveryClient.class); - } - - @Bean - public LoadBalancerClientFactory loadBalancerClientFactory() { - return new LoadBalancerClientFactory(new LoadBalancerClientsProperties()); - } - - @Bean - public WebClient.Builder webClientBuilder() { - return WebClient.builder(); - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliersTestUtils.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliersTestUtils.java deleted file mode 100644 index 63ef3f77..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ServiceInstanceListSuppliersTestUtils.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.net.URI; -import java.util.function.BiFunction; - -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.http.HttpStatus; -import org.springframework.web.client.RestTemplate; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.util.UriComponentsBuilder; - -import static org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplierBuilder.getUri; - -/** - * A utility class for {@link ServiceInstanceListSupplier} tests. - * - * @author Olga Maciaszek-Sharma - * @author Sabyasachi Bhattacharya - * @since 3.0.0 - */ -final class ServiceInstanceListSuppliersTestUtils { - - private ServiceInstanceListSuppliersTestUtils() { - throw new UnsupportedOperationException("Cannot instantiate utility class"); - } - - static BiFunction> healthCheckFunction(WebClient webClient) { - return (serviceInstance, healthCheckPath) -> webClient.get() - .uri(UriComponentsBuilder.fromUriString(getUri(serviceInstance, healthCheckPath)).build().toUri()) - .exchange().flatMap(clientResponse -> clientResponse.releaseBody() - .thenReturn(HttpStatus.OK.equals(clientResponse.statusCode()))); - } - - static BiFunction> healthCheckFunction(RestTemplate restTemplate) { - return (serviceInstance, healthCheckPath) -> Mono.defer(() -> { - URI uri = UriComponentsBuilder.fromUriString(getUri(serviceInstance, healthCheckPath)).build().toUri(); - try { - return Mono.just(HttpStatus.OK.equals(restTemplate.getForEntity(uri, Void.class).getStatusCode())); - } - catch (Exception ignored) { - return Mono.just(false); - } - }); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/TestSelectedServiceInstanceSupplier.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/TestSelectedServiceInstanceSupplier.java deleted file mode 100644 index be834f63..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/TestSelectedServiceInstanceSupplier.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -/** - * Test supplier interface extending {@link ServiceInstanceListSupplier} and - * {@link SelectedInstanceCallback}. Useful if you need to verify certain behavior - * happened on a mock for example. - * - * @author Jürgen Kreitler - */ -public interface TestSelectedServiceInstanceSupplier extends ServiceInstanceListSupplier, SelectedInstanceCallback { - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplierTests.java deleted file mode 100644 index 94c35020..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/WeightedServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; - -import static java.util.stream.Collectors.summingInt; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.springframework.cloud.loadbalancer.core.WeightedServiceInstanceListSupplier.DEFAULT_WEIGHT; - -/** - * Tests for {@link WeightedServiceInstanceListSupplier}. - * - * @author Zhuozhi Ji - * @author Olga Maciaszek-Sharma - */ -class WeightedServiceInstanceListSupplierTests { - - private final DiscoveryClientServiceInstanceListSupplier delegate = mock( - DiscoveryClientServiceInstanceListSupplier.class); - - @Test - void shouldReturnEmptyWhenDelegateReturnedEmpty() { - when(delegate.get()).thenReturn(Flux.just(Collections.emptyList())); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - assertThat(serviceInstances).isEmpty(); - } - - @Test - void shouldBeSameAsWeightsRatioWhenGcdOfWeightsIs1() { - ServiceInstance one = serviceInstance("test-1", buildWeightMetadata(1)); - ServiceInstance two = serviceInstance("test-2", buildWeightMetadata(2)); - ServiceInstance three = serviceInstance("test-3", buildWeightMetadata(3)); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", 1); - assertThat(counter).containsEntry("test-2", 2); - assertThat(counter).containsEntry("test-3", 3); - } - - @Test - void shouldBeSameAsWeightsRatioWhenGcdOfWeightsIs10() { - ServiceInstance one = serviceInstance("test-1", buildWeightMetadata(10)); - ServiceInstance two = serviceInstance("test-2", buildWeightMetadata(20)); - ServiceInstance three = serviceInstance("test-3", buildWeightMetadata(30)); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", 1); - assertThat(counter).containsEntry("test-2", 2); - assertThat(counter).containsEntry("test-3", 3); - } - - @Test - void shouldUseDefaultWeightWhenWeightNotSpecified() { - ServiceInstance one = serviceInstance("test-1", Collections.emptyMap()); - ServiceInstance two = serviceInstance("test-2", Collections.emptyMap()); - ServiceInstance three = serviceInstance("test-3", buildWeightMetadata(3)); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-2", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-3", 3); - } - - @Test - void shouldUseDefaultWeightWhenWeightIsNotNumber() { - ServiceInstance one = serviceInstance("test-1", buildWeightMetadata("Foo")); - ServiceInstance two = serviceInstance("test-2", buildWeightMetadata("Bar")); - ServiceInstance three = serviceInstance("test-3", buildWeightMetadata("Baz")); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-2", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-3", DEFAULT_WEIGHT); - } - - @Test - void shouldUseDefaultWeightWhenWeightedFunctionReturnedZero() { - ServiceInstance one = serviceInstance("test-1", Collections.emptyMap()); - ServiceInstance two = serviceInstance("test-2", Collections.emptyMap()); - ServiceInstance three = serviceInstance("test-3", Collections.emptyMap()); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate, instance -> 0); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-2", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-3", DEFAULT_WEIGHT); - } - - @Test - void shouldUseDefaultWeightWhenWeightedFunctionReturnedNegative() { - ServiceInstance one = serviceInstance("test-1", Collections.emptyMap()); - ServiceInstance two = serviceInstance("test-2", Collections.emptyMap()); - ServiceInstance three = serviceInstance("test-3", Collections.emptyMap()); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate, - instance -> -1); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-2", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-3", DEFAULT_WEIGHT); - } - - @Test - void shouldUseDefaultWeightWhenWeightedFunctionThrownException() { - ServiceInstance one = serviceInstance("test-1", Collections.emptyMap()); - ServiceInstance two = serviceInstance("test-2", Collections.emptyMap()); - ServiceInstance three = serviceInstance("test-3", Collections.emptyMap()); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate, instance -> { - throw new RuntimeException(); - }); - - List serviceInstances = Objects.requireNonNull(supplier.get().blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-2", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-3", DEFAULT_WEIGHT); - } - - @Test - void shouldCallGetRequestOnDelegate() { - LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - LoadBalancerProperties properties = new LoadBalancerProperties(); - when(loadBalancerClientFactory.getProperties(any())).thenReturn(properties); - ServiceInstance one = serviceInstance("test-1", Collections.emptyMap()); - ServiceInstance two = serviceInstance("test-2", Collections.emptyMap()); - ServiceInstance three = serviceInstance("test-3", buildWeightMetadata(3)); - Request request = new DefaultRequest<>(new DefaultRequestContext()); - - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(one, two, three))); - when(delegate.get(request)).thenReturn(Flux.just(Arrays.asList(one, two))); - WeightedServiceInstanceListSupplier supplier = new WeightedServiceInstanceListSupplier(delegate, - loadBalancerClientFactory); - - List serviceInstances = Objects.requireNonNull(supplier.get(request).blockFirst()); - Map counter = serviceInstances.stream() - .collect(Collectors.groupingBy(ServiceInstance::getInstanceId, summingInt(e -> 1))); - assertThat(counter).containsEntry("test-1", DEFAULT_WEIGHT); - assertThat(counter).containsEntry("test-2", DEFAULT_WEIGHT); - assertThat(counter).doesNotContainEntry("test-3", 3); - } - - private ServiceInstance serviceInstance(String instanceId, Map metadata) { - return new DefaultServiceInstance(instanceId, "test", "localhost", 8080, false, metadata); - } - - private Map buildWeightMetadata(Object weight) { - Map metadata = new HashMap<>(); - metadata.put("weight", weight.toString()); - return metadata; - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java deleted file mode 100644 index 3c6b500c..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/XForwardedHeadersTransformerTests.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.net.URI; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.web.reactive.function.client.ClientRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link XForwardedHeadersTransformer}. - * - * @author Gandhimathi Velusamy - * @author Olga Maciaszek-Sharma - */ - -class XForwardedHeadersTransformerTests { - - private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - - private final LoadBalancerProperties loadBalancerProperties = new LoadBalancerProperties(); - - private final ServiceInstance serviceInstance = new DefaultServiceInstance("test1", "test", "test.org", 8080, - false); - - private final ClientRequest request = mock(ClientRequest.class); - - @BeforeEach - void setUp() { - when(request.method()).thenReturn(HttpMethod.GET); - when(request.url()).thenReturn(URI.create("https://spring.io")); - when(request.headers()).thenReturn(new HttpHeaders()); - } - - @Test - void shouldAppendXForwardedHeadersIfEnabled() { - loadBalancerProperties.getXForwarded().setEnabled(true); - when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); - - ClientRequest newRequest = transformer.transformRequest(request, serviceInstance); - - assertThat(newRequest.headers()).containsKey("X-Forwarded-Host"); - assertThat(newRequest.headers().getFirst("X-Forwarded-Host")).isEqualTo("spring.io"); - assertThat(newRequest.headers()).containsKey("X-Forwarded-Proto"); - assertThat(newRequest.headers().getFirst("X-Forwarded-Proto")).isEqualTo("https"); - } - - @Test - void shouldNotAppendXForwardedHeadersIfDefault() { - when(loadBalancerClientFactory.getProperties("test")).thenReturn(loadBalancerProperties); - XForwardedHeadersTransformer transformer = new XForwardedHeadersTransformer(loadBalancerClientFactory); - - ClientRequest newRequest = transformer.transformRequest(request, serviceInstance); - - assertThat(newRequest.headers()).doesNotContainKey("X-Forwarded-Host"); - assertThat(newRequest.headers()).doesNotContainKey("X-Forwarded-Proto"); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplierTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplierTests.java deleted file mode 100644 index cea7bde2..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/core/ZonePreferenceServiceInstanceListSupplierTests.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2012-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.core; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.loadbalancer.config.LoadBalancerZoneConfig; -import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link ZonePreferenceServiceInstanceListSupplier}. - * - * @author Olga Maciaszek-Sharma - */ -class ZonePreferenceServiceInstanceListSupplierTests { - - private final DiscoveryClientServiceInstanceListSupplier delegate = mock( - DiscoveryClientServiceInstanceListSupplier.class); - - private final LoadBalancerZoneConfig zoneConfig = new LoadBalancerZoneConfig(null); - - private ZonePreferenceServiceInstanceListSupplier supplier; - - private final LoadBalancerClientFactory loadBalancerClientFactory = mock(LoadBalancerClientFactory.class); - - private final ServiceInstance first = serviceInstance("test-1", buildZoneMetadata("zone1")); - - private final ServiceInstance second = serviceInstance("test-2", buildZoneMetadata("zone1")); - - private final ServiceInstance third = serviceInstance("test-3", buildZoneMetadata("zone2")); - - private final ServiceInstance fourth = serviceInstance("test-4", buildZoneMetadata("zone3")); - - private final ServiceInstance fifth = serviceInstance("test-5", buildZoneMetadata(null)); - - @BeforeEach - void setUp() { - LoadBalancerProperties properties = new LoadBalancerProperties(); - when(loadBalancerClientFactory.getProperties(any())).thenReturn(properties); - supplier = new ZonePreferenceServiceInstanceListSupplier(delegate, zoneConfig, loadBalancerClientFactory); - } - - @Test - void shouldFilterInstancesByZone() { - zoneConfig.setZone("zone1"); - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(first, second, third, fourth, fifth))); - - List filtered = supplier.get().blockFirst(); - - assertThat(filtered).hasSize(2); - assertThat(filtered).contains(first, second); - assertThat(filtered).doesNotContain(third); - assertThat(filtered).doesNotContain(fourth); - assertThat(filtered).doesNotContain(fifth); - } - - @Test - void shouldCallGetRequestOnDelegate() { - zoneConfig.setZone("zone1"); - Request request = new DefaultRequest<>(new DefaultRequestContext()); - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(first, second, third, fourth, fifth))); - when(delegate.get(request)).thenReturn(Flux.just(Arrays.asList(first, third, fourth, fifth))); - - List filtered = supplier.get(request).blockFirst(); - - assertThat(filtered).hasSize(1); - assertThat(filtered).containsOnly(first); - } - - @Test - void shouldReturnAllInstancesIfNoZoneInstances() { - zoneConfig.setZone("zone1"); - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(third, fourth))); - - List filtered = supplier.get().blockFirst(); - - assertThat(filtered).hasSize(2); - assertThat(filtered).contains(third, fourth); - } - - @Test - void shouldNotThrowNPEIfNullInstanceMetadata() { - zoneConfig.setZone("zone1"); - when(delegate.get()).thenReturn(Flux.just(Collections.singletonList(serviceInstance("test-6", null)))); - assertThatCode(() -> supplier.get().blockFirst()).doesNotThrowAnyException(); - } - - @Test - void shouldReturnAllInstancesIfNoZone() { - zoneConfig.setZone(null); - when(delegate.get()).thenReturn(Flux.just(Arrays.asList(first, second, third, fourth))); - - List filtered = supplier.get().blockFirst(); - - assertThat(filtered).hasSize(4); - assertThat(filtered).contains(first, second, third, fourth); - } - - private DefaultServiceInstance serviceInstance(String instanceId, Map metadata) { - return new DefaultServiceInstance(instanceId, "test", "http://test.test", 9080, false, metadata); - } - - private Map buildZoneMetadata(String zone) { - Map metadata = new HashMap<>(); - metadata.put("zone", zone); - return metadata; - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfigurationTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfigurationTests.java deleted file mode 100644 index cafada1e..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/security/OAuth2LoadBalancerClientAutoConfigurationTests.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2015-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.loadbalancer.security; - -import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.test.ClassPathExclusions; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Dave Syer - * - */ -@ClassPathExclusions("spring-retry-*.jar") -public class OAuth2LoadBalancerClientAutoConfigurationTests { - - private ConfigurableApplicationContext context; - - @BeforeEach - public void before() { - // FIXME: why do I need to do this? (fails in maven build without it. - // https://stackoverflow.com/questions/28911560/tomcat-8-embedded-error-org-apache-catalina-core-containerbase-a-child-con - // https://github.com/spring-projects/spring-boot/issues/21535 - TomcatURLStreamHandlerFactory.disable(); - } - - @AfterEach - public void close() { - if (this.context != null) { - this.context.close(); - } - } - - @Test - @Disabled - public void userInfoNotLoadBalanced() { - this.context = new SpringApplicationBuilder(ClientConfiguration.class).properties("spring.config.name=test", - "server.port=0", "security.oauth2.resource.userInfoUri:https://example.com").run(); - - assertThat(this.context.containsBean("loadBalancedUserInfoRestTemplateCustomizer")).isFalse(); - assertThat(this.context.containsBean("retryLoadBalancedUserInfoRestTemplateCustomizer")).isFalse(); - } - - @Test - @Disabled - public void userInfoLoadBalancedNoRetry() { - this.context = new SpringApplicationBuilder(ClientConfiguration.class).properties("spring.config.name=test", - "server.port=0", "security.oauth2.resource.userInfoUri:https://nosuchservice", - "spring.cloud.oauth2.load-balanced.enabled=true").run(); - - assertThat(this.context.containsBean("loadBalancedUserInfoRestTemplateCustomizer")).isTrue(); - assertThat(this.context.containsBean("retryLoadBalancedUserInfoRestTemplateCustomizer")).isFalse(); - - /* - * OAuth2RestTemplate template = - * this.context.getBean(UserInfoRestTemplateFactory.class).getUserInfoRestTemplate - * (); ClientHttpRequest request = template.getRequestFactory().createRequest(new - * URI("https://nosuchservice"), HttpMethod.GET); - * expected.expectMessage("No instances available for nosuchservice"); - * request.execute(); - */ - } - - @EnableAutoConfiguration - @Configuration(proxyBeanMethods = false) - // @EnableOAuth2Sso - protected static class ClientConfiguration { - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java deleted file mode 100644 index 49d8714c..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/stats/MicrometerStatsLoadBalancerLifecycleTests.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.stats; - -import java.net.URI; -import java.util.HashMap; - -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Tag; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.client.DefaultServiceInstance; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.loadbalancer.CompletionContext; -import org.springframework.cloud.client.loadbalancer.DefaultRequest; -import org.springframework.cloud.client.loadbalancer.DefaultRequestContext; -import org.springframework.cloud.client.loadbalancer.DefaultResponse; -import org.springframework.cloud.client.loadbalancer.EmptyResponse; -import org.springframework.cloud.client.loadbalancer.Request; -import org.springframework.cloud.client.loadbalancer.RequestData; -import org.springframework.cloud.client.loadbalancer.RequestDataContext; -import org.springframework.cloud.client.loadbalancer.Response; -import org.springframework.cloud.client.loadbalancer.ResponseData; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.util.MultiValueMapAdapter; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.loadbalancer.stats.LoadBalancerTags.UNKNOWN; - -/** - * Tests for {@link MicrometerStatsLoadBalancerLifecycle}. - * - * @author Olga Maciaszek-Sharma - */ -class MicrometerStatsLoadBalancerLifecycleTests { - - MeterRegistry meterRegistry = new SimpleMeterRegistry(); - - MicrometerStatsLoadBalancerLifecycle statsLifecycle = new MicrometerStatsLoadBalancerLifecycle(meterRegistry); - - @Test - void shouldRecordSuccessfulTimedRequest() { - RequestData requestData = new RequestData(HttpMethod.GET, URI.create("http://test.org/test"), new HttpHeaders(), - new HttpHeaders(), new HashMap<>()); - Request lbRequest = new DefaultRequest<>(new RequestDataContext(requestData)); - Response lbResponse = new DefaultResponse( - new DefaultServiceInstance("test-1", "test", "test.org", 8080, false, new HashMap<>())); - ResponseData responseData = new ResponseData(HttpStatus.OK, new HttpHeaders(), - new MultiValueMapAdapter<>(new HashMap<>()), requestData); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, responseData)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.success").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().getId().getTags()).contains( - Tag.of("method", "GET"), Tag.of("outcome", "SUCCESS"), Tag.of("serviceId", "test"), - Tag.of("serviceInstance.host", "test.org"), Tag.of("serviceInstance.instanceId", "test-1"), - Tag.of("serviceInstance.port", "8080"), Tag.of("status", "200"), Tag.of("uri", "/test")); - } - - @Test - void shouldRecordFailedTimedRequest() { - RequestData requestData = new RequestData(HttpMethod.GET, URI.create("http://test.org/test"), new HttpHeaders(), - new HttpHeaders(), new HashMap<>()); - Request lbRequest = new DefaultRequest<>(new RequestDataContext(requestData)); - Response lbResponse = new DefaultResponse( - new DefaultServiceInstance("test-1", "test", "test.org", 8080, false, new HashMap<>())); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.FAILED, new IllegalStateException(), - lbRequest, lbResponse)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.failed").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.failed").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.failed").timer().getId().getTags()).contains( - Tag.of("exception", "IllegalStateException"), Tag.of("method", "GET"), Tag.of("serviceId", "test"), - Tag.of("serviceInstance.host", "test.org"), Tag.of("serviceInstance.instanceId", "test-1"), - Tag.of("serviceInstance.port", "8080"), Tag.of("uri", "/test")); - } - - @Test - void shouldNotRecordDiscardedRequest() { - RequestData requestData = new RequestData(HttpMethod.GET, URI.create("http://test.org/test"), new HttpHeaders(), - new HttpHeaders(), new HashMap<>()); - Request lbRequest = new DefaultRequest<>(new RequestDataContext(requestData)); - Response lbResponse = new EmptyResponse(); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - - statsLifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.DISCARD, lbRequest, lbResponse)); - assertThat(meterRegistry.getMeters()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.discard").counter().count()).isEqualTo(1); - } - - @Test - void shouldNotRecordUnTimedRequest() { - Request lbRequest = new DefaultRequest<>(new StatsTestContext()); - Response lbResponse = new DefaultResponse( - new DefaultServiceInstance("test-1", "test", "test.org", 8080, false, new HashMap<>())); - ResponseData responseData = new ResponseData(HttpStatus.OK, new HttpHeaders(), - new MultiValueMapAdapter<>(new HashMap<>()), null); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, responseData)); - - assertThat(meterRegistry.getMeters()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - } - - @Test - void shouldNotCreateNullTagsWhenNullDataObjects() { - Request lbRequest = new DefaultRequest<>(new DefaultRequestContext()); - Response lbResponse = new DefaultResponse(new DefaultServiceInstance()); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle - .onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, null)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.success").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().getId().getTags()).contains( - Tag.of("method", UNKNOWN), Tag.of("outcome", UNKNOWN), Tag.of("serviceId", UNKNOWN), - Tag.of("serviceInstance.host", UNKNOWN), Tag.of("serviceInstance.instanceId", UNKNOWN), - Tag.of("serviceInstance.port", "0"), Tag.of("status", UNKNOWN), Tag.of("uri", UNKNOWN)); - } - - @Test - void shouldNotCreateNullTagsWhenEmptyDataObjects() { - RequestData requestData = new RequestData(null, null, null, null, null); - Request lbRequest = new DefaultRequest<>(new RequestDataContext()); - Response lbResponse = new DefaultResponse(new DefaultServiceInstance()); - ResponseData responseData = new ResponseData(null, null, null, requestData); - statsLifecycle.onStartRequest(lbRequest, lbResponse); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(1); - - statsLifecycle.onComplete( - new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, responseData)); - - assertThat(meterRegistry.getMeters()).hasSize(2); - assertThat(meterRegistry.get("loadbalancer.requests.active").gauge().value()).isEqualTo(0); - assertThat(meterRegistry.get("loadbalancer.requests.success").timers()).hasSize(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().count()).isEqualTo(1); - assertThat(meterRegistry.get("loadbalancer.requests.success").timer().getId().getTags()).contains( - Tag.of("method", UNKNOWN), Tag.of("outcome", "SUCCESS"), Tag.of("serviceId", UNKNOWN), - Tag.of("serviceInstance.host", UNKNOWN), Tag.of("serviceInstance.instanceId", UNKNOWN), - Tag.of("serviceInstance.port", "0"), Tag.of("status", "200"), Tag.of("uri", UNKNOWN)); - } - - private static class StatsTestContext { - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializerTest.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializerTest.java deleted file mode 100644 index 67ebc080..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEagerContextInitializerTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.support; - -import java.util.Collections; -import java.util.concurrent.atomic.AtomicInteger; - -import org.junit.jupiter.api.Test; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; -import org.springframework.cloud.loadbalancer.config.LoadBalancerAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Andrii Bohutskyi - */ -@SpringBootTest( - classes = { LoadBalancerAutoConfiguration.class, LoadBalancerEagerContextInitializerTest.SomeTestConfig.class }) -class LoadBalancerEagerContextInitializerTest { - - private static final String LOAD_BALANCER = "testLoadBalancer"; - - @Autowired - private LoadBalancerClientFactory factory; - - @Test - void testLoadBalancerInstanceShouldBeInitialized() { - assertThat(LoadBalancerCounter.getCount()).isEqualTo(1); - factory.getInstance(LOAD_BALANCER); - assertThat(LoadBalancerCounter.getCount()).isEqualTo(1); - } - - @Configuration(proxyBeanMethods = false) - @LoadBalancerClient(name = LOAD_BALANCER, configuration = TestLoadBalancerConfiguration.class) - static class SomeTestConfig { - - @Bean - public LoadBalancerEagerContextInitializer testLoadBalancerEagerContextInitializer( - LoadBalancerClientFactory factory) { - return new LoadBalancerEagerContextInitializer(factory, Collections.singletonList(LOAD_BALANCER)); - } - - } - - static class TestLoadBalancerConfiguration { - - @Bean - public LoadBalancerCounter loadBalancerCounter() { - return new LoadBalancerCounter(); - } - - } - - static class LoadBalancerCounter { - - private static final AtomicInteger COUNT = new AtomicInteger(); - - LoadBalancerCounter() { - COUNT.incrementAndGet(); - } - - public static int getCount() { - return COUNT.get(); - } - - } - -} diff --git a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtilsTests.java b/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtilsTests.java deleted file mode 100644 index 6e8105b1..00000000 --- a/spring-cloud-loadbalancer/src/test/java/org/springframework/cloud/loadbalancer/support/LoadBalancerEnvironmentPropertyUtilsTests.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2012-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.loadbalancer.support; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import org.springframework.mock.env.MockEnvironment; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link LoadBalancerEnvironmentPropertyUtils}. - * - * @author Olga Maciaszek-Sharma - */ -class LoadBalancerEnvironmentPropertyUtilsTests { - - MockEnvironment environment = new MockEnvironment(); - - @BeforeEach - void setUp() { - environment.setProperty("loadbalancer.client.name", "x"); - } - - @Test - void shouldReturnTrueWhenTrueForClient() { - environment.setProperty("spring.cloud.loadbalancer.clients.x.test", "true"); - environment.setProperty("spring.cloud.loadbalancer.test", "false"); - - assertThat(LoadBalancerEnvironmentPropertyUtils.trueForClientOrDefault(environment, "test")).isTrue(); - assertThat(LoadBalancerEnvironmentPropertyUtils.trueOrMissingForClientOrDefault(environment, "test")).isTrue(); - } - - @Test - void shouldReturnTrueWhenTrueForDefault() { - environment.setProperty("spring.cloud.loadbalancer.test", "true"); - - assertThat(LoadBalancerEnvironmentPropertyUtils.trueForClientOrDefault(environment, "test")).isTrue(); - assertThat(LoadBalancerEnvironmentPropertyUtils.trueOrMissingForClientOrDefault(environment, "test")).isTrue(); - } - - @Test - void shouldReturnTrueWhenEqualForClient() { - environment.setProperty("spring.cloud.loadbalancer.clients.x.test", "true"); - environment.setProperty("spring.cloud.loadbalancer.test", "false"); - - assertThat(LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(environment, "test", "true")) - .isTrue(); - assertThat(LoadBalancerEnvironmentPropertyUtils.equalToOrMissingForClientOrDefault(environment, "test", "true")) - .isTrue(); - } - - @Test - void shouldReturnTrueWhenEqualForDefault() { - environment.setProperty("spring.cloud.loadbalancer.test", "true"); - - assertThat(LoadBalancerEnvironmentPropertyUtils.equalToForClientOrDefault(environment, "test", "true")) - .isTrue(); - assertThat(LoadBalancerEnvironmentPropertyUtils.equalToOrMissingForClientOrDefault(environment, "test", "true")) - .isTrue(); - } - - @Test - void shouldReturnTrueWhenMissingForClientAndDefault() { - assertThat(LoadBalancerEnvironmentPropertyUtils.trueOrMissingForClientOrDefault(environment, "test")).isTrue(); - assertThat(LoadBalancerEnvironmentPropertyUtils.equalToOrMissingForClientOrDefault(environment, "test", "true")) - .isTrue(); - } - -} diff --git a/spring-cloud-loadbalancer/src/test/resources/application.yml b/spring-cloud-loadbalancer/src/test/resources/application.yml deleted file mode 100644 index 103f868d..00000000 --- a/spring-cloud-loadbalancer/src/test/resources/application.yml +++ /dev/null @@ -1,31 +0,0 @@ -spring: - cloud: - discovery: - client: - simple: - instances: - myservice: - - service-id: myservice - uri: http://ahost - - service-id: myservice - uri: http://chost - - service-id: myservice - uri: https://bhostsecure - anotherservice: - - service-id: myservice - uri: http://dhost - - service-id: myservice - uri: https://fhost - - service-id: myservice - uri: http://ehost - thirdservice: - - service-id: myservice - uri: http://ghost - - service-id: myservice - uri: http://hhost - - service-id: myservice - uri: http://ihost - autoconfigure.exclude: - - org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration - - org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration - - org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration \ No newline at end of file diff --git a/spring-cloud-loadbalancer/src/test/resources/logback-test.xml b/spring-cloud-loadbalancer/src/test/resources/logback-test.xml deleted file mode 100644 index 6531f0e6..00000000 --- a/spring-cloud-loadbalancer/src/test/resources/logback-test.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - \ No newline at end of file diff --git a/spring-cloud-starter-bootstrap/pom.xml b/spring-cloud-starter-bootstrap/pom.xml deleted file mode 100644 index 1d3f196c..00000000 --- a/spring-cloud-starter-bootstrap/pom.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - jar - 4.0.0 - spring-cloud-starter-bootstrap - spring-cloud-starter-bootstrap - Spring Cloud Starter Bootstrap - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - ${basedir}/../.. - - - - - org.springframework.cloud - spring-cloud-starter - - - org.junit.platform - junit-platform-launcher - test - - - org.springframework.boot - spring-boot-starter-test - test - - - \ No newline at end of file diff --git a/spring-cloud-starter-bootstrap/src/main/java/org/springframework/cloud/bootstrap/marker/Marker.java b/spring-cloud-starter-bootstrap/src/main/java/org/springframework/cloud/bootstrap/marker/Marker.java deleted file mode 100644 index bde3c6f7..00000000 --- a/spring-cloud-starter-bootstrap/src/main/java/org/springframework/cloud/bootstrap/marker/Marker.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.marker; - -/** - * A marker class, so that, if present, spring cloud bootstrap is enable similar to how - * 'spring.cloud.bootstrap.enabled=true' works. - */ -public abstract class Marker { - - private Marker() { - - } - -} diff --git a/spring-cloud-starter-bootstrap/src/test/java/org/springframework/cloud/bootstrap/marker/MarkerTests.java b/spring-cloud-starter-bootstrap/src/test/java/org/springframework/cloud/bootstrap/marker/MarkerTests.java deleted file mode 100644 index 39175b3a..00000000 --- a/spring-cloud-starter-bootstrap/src/test/java/org/springframework/cloud/bootstrap/marker/MarkerTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.bootstrap.marker; - -import org.junit.jupiter.api.Test; - -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.core.env.Environment; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest -public class MarkerTests { - - @Autowired - private Environment env; - - @Test - public void testBootstrapIsEnabled() { - assertThat(env.getProperty("my.prop")).isEqualTo("my.value"); - } - - @SpringBootConfiguration - @EnableAutoConfiguration - protected static class TestConfig { - - } - -} diff --git a/spring-cloud-starter-bootstrap/src/test/resources/bootstrap.properties b/spring-cloud-starter-bootstrap/src/test/resources/bootstrap.properties deleted file mode 100644 index 7d2d6925..00000000 --- a/spring-cloud-starter-bootstrap/src/test/resources/bootstrap.properties +++ /dev/null @@ -1 +0,0 @@ -my.prop=my.value diff --git a/spring-cloud-starter-loadbalancer/pom.xml b/spring-cloud-starter-loadbalancer/pom.xml deleted file mode 100644 index a32be536..00000000 --- a/spring-cloud-starter-loadbalancer/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - 4.0.0 - spring-cloud-starter-loadbalancer - spring-cloud-starter-loadbalancer - Spring Cloud Starter LoadBalancer - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - ${basedir}/../.. - - - - - org.springframework.cloud - spring-cloud-starter - - - org.springframework.cloud - spring-cloud-loadbalancer - - - org.springframework.boot - spring-boot-starter-cache - - - com.stoyanr - evictor - ${evictor.version} - - - \ No newline at end of file diff --git a/spring-cloud-starter/pom.xml b/spring-cloud-starter/pom.xml deleted file mode 100644 index 20d92718..00000000 --- a/spring-cloud-starter/pom.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - 4.0.0 - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - - spring-cloud-starter - spring-cloud-starter - Spring Cloud Starter - https://projects.spring.io/spring-cloud - - Pivotal Software, Inc. - https://www.spring.io - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.cloud - spring-cloud-context - - - org.springframework.cloud - spring-cloud-commons - - - org.springframework.security - spring-security-rsa - - - org.projectlombok - lombok - - compile - true - - - diff --git a/spring-cloud-test-support/README.md b/spring-cloud-test-support/README.md deleted file mode 100644 index e690ca0a..00000000 --- a/spring-cloud-test-support/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## Spring Cloud Commons - -Common classes used in different Spring Cloud implementations (eg. Spring Cloud Netflix vs. Spring Cloud Consul). \ No newline at end of file diff --git a/spring-cloud-test-support/eclipse/eclipse-code-formatter.xml b/spring-cloud-test-support/eclipse/eclipse-code-formatter.xml deleted file mode 100644 index 5cbf769b..00000000 --- a/spring-cloud-test-support/eclipse/eclipse-code-formatter.xml +++ /dev/null @@ -1,754 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/spring-cloud-test-support/eclipse/org.eclipse.jdt.core.prefs b/spring-cloud-test-support/eclipse/org.eclipse.jdt.core.prefs deleted file mode 100644 index 63d59166..00000000 --- a/spring-cloud-test-support/eclipse/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,389 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.codeComplete.argumentPrefixes= -org.eclipse.jdt.core.codeComplete.argumentSuffixes= -org.eclipse.jdt.core.codeComplete.fieldPrefixes= -org.eclipse.jdt.core.codeComplete.fieldSuffixes= -org.eclipse.jdt.core.codeComplete.localPrefixes= -org.eclipse.jdt.core.codeComplete.localSuffixes= -org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= -org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.doc.comment.support=enabled -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning -org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag -org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled -org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullReference=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 -org.eclipse.jdt.core.formatter.align_type_members_on_columns=false -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_assignment=0 -org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 -org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 -org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 -org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 -org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 -org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 -org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 -org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 -org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 -org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 -org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_after_package=1 -org.eclipse.jdt.core.formatter.blank_lines_before_field=0 -org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 -org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 -org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 -org.eclipse.jdt.core.formatter.blank_lines_before_method=1 -org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 -org.eclipse.jdt.core.formatter.blank_lines_before_package=0 -org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 -org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 -org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line -org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false -org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false -org.eclipse.jdt.core.formatter.comment.format_block_comments=true -org.eclipse.jdt.core.formatter.comment.format_header=false -org.eclipse.jdt.core.formatter.comment.format_html=true -org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true -org.eclipse.jdt.core.formatter.comment.format_line_comments=true -org.eclipse.jdt.core.formatter.comment.format_source_code=false -org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true -org.eclipse.jdt.core.formatter.comment.indent_root_tags=false -org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert -org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert -org.eclipse.jdt.core.formatter.comment.line_length=90 -org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true -org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true -org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false -org.eclipse.jdt.core.formatter.compact_else_if=true -org.eclipse.jdt.core.formatter.continuation_indentation=2 -org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 -org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off -org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on -org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false -org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true -org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true -org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_empty_lines=false -org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true -org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true -org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false -org.eclipse.jdt.core.formatter.indentation.size=8 -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert -org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert -org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert -org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert -org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert -org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert -org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert -org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert -org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert -org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert -org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert -org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert -org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert -org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert -org.eclipse.jdt.core.formatter.join_lines_in_comments=true -org.eclipse.jdt.core.formatter.join_wrapped_lines=true -org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false -org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false -org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false -org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false -org.eclipse.jdt.core.formatter.lineSplit=90 -org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false -org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false -org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 -org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 -org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true -org.eclipse.jdt.core.formatter.tabulation.char=tab -org.eclipse.jdt.core.formatter.tabulation.size=4 -org.eclipse.jdt.core.formatter.use_on_off_tags=false -org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false -org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true -org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true -org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true diff --git a/spring-cloud-test-support/eclipse/org.eclipse.jdt.ui.prefs b/spring-cloud-test-support/eclipse/org.eclipse.jdt.ui.prefs deleted file mode 100644 index badcb453..00000000 --- a/spring-cloud-test-support/eclipse/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,125 +0,0 @@ -cleanup.add_default_serial_version_id=true -cleanup.add_generated_serial_version_id=false -cleanup.add_missing_annotations=true -cleanup.add_missing_deprecated_annotations=true -cleanup.add_missing_methods=false -cleanup.add_missing_nls_tags=false -cleanup.add_missing_override_annotations=true -cleanup.add_missing_override_annotations_interface_methods=true -cleanup.add_serial_version_id=false -cleanup.always_use_blocks=true -cleanup.always_use_parentheses_in_expressions=false -cleanup.always_use_this_for_non_static_field_access=true -cleanup.always_use_this_for_non_static_method_access=false -cleanup.convert_functional_interfaces=false -cleanup.convert_to_enhanced_for_loop=false -cleanup.correct_indentation=false -cleanup.format_source_code=true -cleanup.format_source_code_changes_only=false -cleanup.insert_inferred_type_arguments=false -cleanup.make_local_variable_final=false -cleanup.make_parameters_final=false -cleanup.make_private_fields_final=false -cleanup.make_type_abstract_if_missing_method=false -cleanup.make_variable_declarations_final=false -cleanup.never_use_blocks=false -cleanup.never_use_parentheses_in_expressions=true -cleanup.organize_imports=true -cleanup.qualify_static_field_accesses_with_declaring_class=false -cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -cleanup.qualify_static_member_accesses_with_declaring_class=true -cleanup.qualify_static_method_accesses_with_declaring_class=false -cleanup.remove_private_constructors=true -cleanup.remove_redundant_type_arguments=true -cleanup.remove_trailing_whitespaces=true -cleanup.remove_trailing_whitespaces_all=true -cleanup.remove_trailing_whitespaces_ignore_empty=false -cleanup.remove_unnecessary_casts=true -cleanup.remove_unnecessary_nls_tags=false -cleanup.remove_unused_imports=true -cleanup.remove_unused_local_variables=false -cleanup.remove_unused_private_fields=true -cleanup.remove_unused_private_members=false -cleanup.remove_unused_private_methods=true -cleanup.remove_unused_private_types=true -cleanup.sort_members=false -cleanup.sort_members_all=false -cleanup.use_anonymous_class_creation=false -cleanup.use_blocks=true -cleanup.use_blocks_only_for_return_and_throw=false -cleanup.use_lambda=true -cleanup.use_parentheses_in_expressions=false -cleanup.use_this_for_non_static_field_access=true -cleanup.use_this_for_non_static_field_access_only_if_necessary=false -cleanup.use_this_for_non_static_method_access=false -cleanup.use_this_for_non_static_method_access_only_if_necessary=true -cleanup.use_type_arguments=false -cleanup_profile=_Spring Cloud Cleanup Conventions -cleanup_settings_version=2 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -formatter_profile=_Spring Cloud Java Conventions -formatter_settings_version=12 -org.eclipse.jdt.ui.exception.name=e -org.eclipse.jdt.ui.gettersetter.use.is=false -org.eclipse.jdt.ui.ignorelowercasenames=true -org.eclipse.jdt.ui.importorder=java;javax;org;com;\#; -org.eclipse.jdt.ui.javadoc=true -org.eclipse.jdt.ui.keywordthis=false -org.eclipse.jdt.ui.ondemandthreshold=9999 -org.eclipse.jdt.ui.overrideannotation=true -org.eclipse.jdt.ui.staticondemandthreshold=9999 -org.eclipse.jdt.ui.text.custom_code_templates= -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=true -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=true -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=true -sp_cleanup.always_use_this_for_non_static_field_access=true -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=true -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=false -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=false -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=true -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=true -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=true -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=true -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=true -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=false -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/spring-cloud-test-support/pom.xml b/spring-cloud-test-support/pom.xml deleted file mode 100644 index ac2b3068..00000000 --- a/spring-cloud-test-support/pom.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-commons-parent - 4.1.0-SNAPSHOT - .. - - spring-cloud-test-support - jar - spring-cloud-test-support - Spring Cloud Test Support - - 3.5.4 - 1.1.1 - - - - org.apache.maven.resolver - maven-resolver-connector-basic - ${maven-resolver.version} - - - org.apache.maven.resolver - maven-resolver-impl - ${maven-resolver.version} - - - org.apache.maven - maven-resolver-provider - ${maven.version} - - - com.google.guava - guava - - - - - org.apache.maven.resolver - maven-resolver-transport-http - ${maven-resolver.version} - - - jcl-over-slf4j - org.slf4j - - - - - junit - junit - true - - - org.springframework - spring-core - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.platform - junit-platform-engine - provided - - - org.junit.platform - junit-platform-launcher - provided - - - org.junit.jupiter - junit-jupiter - provided - - - org.hibernate.validator - hibernate-validator - test - - - javax.validation - validation-api - - - - - jakarta.validation - jakarta.validation-api - test - - - diff --git a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathExclusions.java b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathExclusions.java deleted file mode 100644 index 075ec66b..00000000 --- a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathExclusions.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.junit.jupiter.api.extension.ExtendWith; - -/** - * Taken from Spring Boot test utils. https://github.com/spring-projects/spring-boot/blob/ - * 1.4.x/spring-boot/src/test/java/org/springframework/boot/testutil/ClassPathExclusions.java - * @author Ryan Baxter - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@ExtendWith(ModifiedClassPathExtension.class) -public @interface ClassPathExclusions { - - /** - * One or more Ant-style patterns that identify entries to be excluded from the class - * path. Matching is performed against an entry's {@link java.io.File#getName() file - * name}. For example, to exclude Hibernate Validator from the classpath, - * {@code "hibernate-validator-*.jar"} can be used. - * @return the exclusion patterns - */ - String[] value(); - -} diff --git a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathOverrides.java b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathOverrides.java deleted file mode 100644 index 5724a696..00000000 --- a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ClassPathOverrides.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.junit.jupiter.api.extension.ExtendWith; - -/** - * Annotation used in combination with {@link ModifiedClassPathExtension} to override - * entries on the classpath. - * - * @author Andy Wilkinson - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@ExtendWith(ModifiedClassPathExtension.class) -public @interface ClassPathOverrides { - - /** - * One or more sets of Maven coordinates ({@code groupId:artifactId:version}) to be - * added to the classpath. The additions will take precedence over any existing - * classes on the classpath. - * @return the coordinates - */ - String[] value(); - -} diff --git a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathClassLoader.java b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathClassLoader.java deleted file mode 100644 index df044250..00000000 --- a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathClassLoader.java +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import java.io.File; -import java.lang.management.ManagementFactory; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Method; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.collection.CollectRequest; -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.impl.DefaultServiceLocator; -import org.eclipse.aether.repository.LocalRepository; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.resolution.ArtifactResult; -import org.eclipse.aether.resolution.DependencyRequest; -import org.eclipse.aether.resolution.DependencyResult; -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; -import org.eclipse.aether.spi.connector.transport.TransporterFactory; -import org.eclipse.aether.transport.http.HttpTransporterFactory; - -import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * Custom {@link URLClassLoader} that modifies the class path. - * - * @author Andy Wilkinson - * @author Christoph Dreis - * @author Siva Krishna Battu - * @see ModifiedClassPathClassLoader.java - */ -final class ModifiedClassPathClassLoader extends URLClassLoader { - - private static final Map, ModifiedClassPathClassLoader> cache = new ConcurrentReferenceHashMap<>(); - - private static final Pattern INTELLIJ_CLASSPATH_JAR_PATTERN = Pattern.compile(".*classpath(\\d+)?\\.jar"); - - private static final int MAX_RESOLUTION_ATTEMPTS = 5; - - private final ClassLoader junitLoader; - - ModifiedClassPathClassLoader(URL[] urls, ClassLoader parent, ClassLoader junitLoader) { - super(urls, parent); - this.junitLoader = junitLoader; - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException { - if (name.startsWith("org.junit") || name.startsWith("org.hamcrest") - || name.startsWith("io.netty.internal.tcnative")) { - return Class.forName(name, false, this.junitLoader); - } - return super.loadClass(name); - } - - static ModifiedClassPathClassLoader get(Class testClass, Method testMethod, List arguments) { - Set candidates = new LinkedHashSet<>(); - candidates.add(testClass); - candidates.add(testMethod); - candidates.addAll(getAnnotatedElements(arguments.toArray())); - List annotatedElements = candidates.stream() - .filter(ModifiedClassPathClassLoader::hasAnnotation).collect(Collectors.toList()); - if (annotatedElements.isEmpty()) { - return null; - } - return cache.computeIfAbsent(annotatedElements, (key) -> compute(testClass.getClassLoader(), key)); - } - - private static Collection getAnnotatedElements(Object[] array) { - Set result = new LinkedHashSet<>(); - for (Object item : array) { - if (item instanceof AnnotatedElement) { - result.add((AnnotatedElement) item); - } - else if (ObjectUtils.isArray(item)) { - result.addAll(getAnnotatedElements(ObjectUtils.toObjectArray(item))); - } - } - return result; - } - - private static boolean hasAnnotation(AnnotatedElement element) { - MergedAnnotations annotations = MergedAnnotations.from(element, - MergedAnnotations.SearchStrategy.TYPE_HIERARCHY); - return annotations.isPresent(ClassPathOverrides.class) || annotations.isPresent(ClassPathExclusions.class); - } - - private static ModifiedClassPathClassLoader compute(ClassLoader classLoader, - List annotatedClasses) { - List annotations = annotatedClasses.stream() - .map((source) -> MergedAnnotations.from(source, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY)) - .toList(); - return new ModifiedClassPathClassLoader(processUrls(extractUrls(classLoader), annotations), - classLoader.getParent(), classLoader); - } - - private static URL[] extractUrls(ClassLoader classLoader) { - List extractedUrls = new ArrayList<>(); - doExtractUrls(classLoader).forEach((URL url) -> { - if (isManifestOnlyJar(url)) { - extractedUrls.addAll(extractUrlsFromManifestClassPath(url)); - } - else { - extractedUrls.add(url); - } - }); - return extractedUrls.toArray(new URL[0]); - } - - private static Stream doExtractUrls(ClassLoader classLoader) { - if (classLoader instanceof URLClassLoader urlClassLoader) { - return Stream.of(urlClassLoader.getURLs()); - } - return Stream.of(ManagementFactory.getRuntimeMXBean().getClassPath().split(File.pathSeparator)) - .map(ModifiedClassPathClassLoader::toURL); - } - - private static URL toURL(String entry) { - try { - return new File(entry).toURI().toURL(); - } - catch (Exception ex) { - throw new IllegalArgumentException(ex); - } - } - - private static boolean isManifestOnlyJar(URL url) { - return isShortenedIntelliJJar(url); - } - - private static boolean isShortenedIntelliJJar(URL url) { - String urlPath = url.getPath(); - boolean isCandidate = INTELLIJ_CLASSPATH_JAR_PATTERN.matcher(urlPath).matches(); - if (isCandidate) { - try { - Attributes attributes = getManifestMainAttributesFromUrl(url); - String createdBy = attributes.getValue("Created-By"); - return createdBy != null && createdBy.contains("IntelliJ"); - } - catch (Exception ex) { - } - } - return false; - } - - private static List extractUrlsFromManifestClassPath(URL booterJar) { - List urls = new ArrayList<>(); - try { - for (String entry : getClassPath(booterJar)) { - urls.add(new URL(entry)); - } - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - return urls; - } - - private static String[] getClassPath(URL booterJar) throws Exception { - Attributes attributes = getManifestMainAttributesFromUrl(booterJar); - return StringUtils.delimitedListToStringArray(attributes.getValue(Attributes.Name.CLASS_PATH), " "); - } - - private static Attributes getManifestMainAttributesFromUrl(URL url) throws Exception { - try (JarFile jarFile = new JarFile(new File(url.toURI()))) { - return jarFile.getManifest().getMainAttributes(); - } - } - - private static URL[] processUrls(URL[] urls, List annotations) { - ClassPathEntryFilter filter = new ClassPathEntryFilter(annotations); - List additionalUrls = getAdditionalUrls(annotations); - List processedUrls = new ArrayList<>(additionalUrls); - for (URL url : urls) { - if (!filter.isExcluded(url)) { - processedUrls.add(url); - } - } - return processedUrls.toArray(new URL[0]); - } - - private static List getAdditionalUrls(List annotations) { - Set urls = new LinkedHashSet<>(); - for (MergedAnnotations candidate : annotations) { - MergedAnnotation annotation = candidate.get(ClassPathOverrides.class); - if (annotation.isPresent()) { - urls.addAll(resolveCoordinates(annotation.getStringArray(MergedAnnotation.VALUE))); - } - } - return urls.stream().toList(); - } - - private static List resolveCoordinates(String[] coordinates) { - Exception latestFailure = null; - DefaultServiceLocator serviceLocator = MavenRepositorySystemUtils.newServiceLocator(); - serviceLocator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); - serviceLocator.addService(TransporterFactory.class, HttpTransporterFactory.class); - RepositorySystem repositorySystem = serviceLocator.getService(RepositorySystem.class); - DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - LocalRepository localRepository = new LocalRepository(System.getProperty("user.home") + "/.m2/repository"); - RemoteRepository remoteRepository = new RemoteRepository.Builder("central", "default", - "https://repo.maven.apache.org/maven2").build(); - session.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(session, localRepository)); - for (int i = 0; i < MAX_RESOLUTION_ATTEMPTS; i++) { - CollectRequest collectRequest = new CollectRequest(null, Arrays.asList(remoteRepository)); - collectRequest.setDependencies(createDependencies(coordinates)); - DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, null); - try { - DependencyResult result = repositorySystem.resolveDependencies(session, dependencyRequest); - List resolvedArtifacts = new ArrayList<>(); - for (ArtifactResult artifact : result.getArtifactResults()) { - resolvedArtifacts.add(artifact.getArtifact().getFile().toURI().toURL()); - } - return resolvedArtifacts; - } - catch (Exception ex) { - latestFailure = ex; - } - } - throw new IllegalStateException("Resolution failed after " + MAX_RESOLUTION_ATTEMPTS + " attempts", - latestFailure); - } - - private static List createDependencies(String[] allCoordinates) { - List dependencies = new ArrayList<>(); - for (String coordinate : allCoordinates) { - dependencies.add(new Dependency(new DefaultArtifact(coordinate), null)); - } - return dependencies; - } - - /** - * Filter for class path entries. - */ - private static final class ClassPathEntryFilter { - - private final List exclusions; - - private final AntPathMatcher matcher = new AntPathMatcher(); - - private ClassPathEntryFilter(List annotations) { - Set exclusions = new LinkedHashSet<>(); - for (MergedAnnotations candidate : annotations) { - MergedAnnotation annotation = candidate.get(ClassPathExclusions.class); - if (annotation.isPresent()) { - exclusions.addAll(Arrays.asList(annotation.getStringArray(MergedAnnotation.VALUE))); - } - } - this.exclusions = exclusions.stream().toList(); - } - - private boolean isExcluded(URL url) { - if ("file".equals(url.getProtocol())) { - try { - String name = new File(url.toURI()).getName(); - for (String exclusion : this.exclusions) { - if (this.matcher.match(exclusion, name)) { - return true; - } - } - } - catch (URISyntaxException ex) { - } - } - return false; - } - - } - -} diff --git a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathExtension.java b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathExtension.java deleted file mode 100644 index 898eaa54..00000000 --- a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathExtension.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2012-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import java.lang.reflect.Method; -import java.net.URLClassLoader; - -import org.junit.jupiter.api.extension.Extension; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.InvocationInterceptor; -import org.junit.jupiter.api.extension.ReflectiveInvocationContext; -import org.junit.platform.engine.discovery.DiscoverySelectors; -import org.junit.platform.launcher.Launcher; -import org.junit.platform.launcher.LauncherDiscoveryRequest; -import org.junit.platform.launcher.TestPlan; -import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; -import org.junit.platform.launcher.core.LauncherFactory; -import org.junit.platform.launcher.listeners.SummaryGeneratingListener; -import org.junit.platform.launcher.listeners.TestExecutionSummary; - -import org.springframework.util.CollectionUtils; - -/** - * A custom {@link Extension} that runs tests using a modified class path. Entries are - * excluded from the class path using {@link ClassPathExclusions @ClassPathExclusions} and - * overridden using {@link ClassPathOverrides @ClassPathOverrides} on the test class. A - * class loader is created with the customized class path and is used both to load the - * test class and as the thread context class loader while the test is being run. - * - * @author Christoph Dreis - * @author Siva Krishna Battu - * @see ModifiedClassPathExtension.java - */ -class ModifiedClassPathExtension implements InvocationInterceptor { - - @Override - public void interceptBeforeAllMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { - intercept(invocation, extensionContext); - } - - @Override - public void interceptBeforeEachMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { - intercept(invocation, extensionContext); - } - - @Override - public void interceptAfterEachMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { - intercept(invocation, extensionContext); - } - - @Override - public void interceptAfterAllMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { - intercept(invocation, extensionContext); - } - - @Override - public void interceptTestMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, - ExtensionContext extensionContext) throws Throwable { - interceptMethod(invocation, invocationContext, extensionContext); - } - - @Override - public void interceptTestTemplateMethod(Invocation invocation, - ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { - interceptMethod(invocation, invocationContext, extensionContext); - } - - private void interceptMethod(Invocation invocation, ReflectiveInvocationContext invocationContext, - ExtensionContext extensionContext) throws Throwable { - if (isModifiedClassPathClassLoader(extensionContext)) { - invocation.proceed(); - return; - } - Class testClass = extensionContext.getRequiredTestClass(); - Method testMethod = invocationContext.getExecutable(); - URLClassLoader modifiedClassLoader = ModifiedClassPathClassLoader.get(testClass, testMethod, - invocationContext.getArguments()); - if (modifiedClassLoader == null) { - invocation.proceed(); - return; - } - invocation.skip(); - ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(modifiedClassLoader); - try { - runTest(extensionContext.getUniqueId()); - } - finally { - Thread.currentThread().setContextClassLoader(originalClassLoader); - } - } - - private void runTest(String testId) throws Throwable { - LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() - .selectors(DiscoverySelectors.selectUniqueId(testId)).build(); - Launcher launcher = LauncherFactory.create(); - TestPlan testPlan = launcher.discover(request); - SummaryGeneratingListener listener = new SummaryGeneratingListener(); - launcher.registerTestExecutionListeners(listener); - launcher.execute(testPlan); - TestExecutionSummary summary = listener.getSummary(); - if (!CollectionUtils.isEmpty(summary.getFailures())) { - throw summary.getFailures().get(0).getException(); - } - } - - private void intercept(Invocation invocation, ExtensionContext extensionContext) throws Throwable { - if (isModifiedClassPathClassLoader(extensionContext)) { - invocation.proceed(); - return; - } - invocation.skip(); - } - - private boolean isModifiedClassPathClassLoader(ExtensionContext extensionContext) { - Class testClass = extensionContext.getRequiredTestClass(); - ClassLoader classLoader = testClass.getClassLoader(); - return classLoader.getClass().getName().equals(ModifiedClassPathClassLoader.class.getName()); - } - -} diff --git a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java deleted file mode 100644 index de4c237b..00000000 --- a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/ModifiedClassPathRunner.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import java.io.File; -import java.lang.annotation.Annotation; -import java.lang.management.ManagementFactory; -import java.lang.reflect.Method; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.jar.Attributes; -import java.util.jar.JarFile; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -import org.apache.maven.repository.internal.MavenRepositorySystemUtils; -import org.eclipse.aether.DefaultRepositorySystemSession; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.collection.CollectRequest; -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.impl.DefaultServiceLocator; -import org.eclipse.aether.repository.LocalRepository; -import org.eclipse.aether.repository.RemoteRepository; -import org.eclipse.aether.resolution.ArtifactResult; -import org.eclipse.aether.resolution.DependencyRequest; -import org.eclipse.aether.resolution.DependencyResult; -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; -import org.eclipse.aether.spi.connector.transport.TransporterFactory; -import org.eclipse.aether.transport.http.HttpTransporterFactory; -import org.junit.runners.BlockJUnit4ClassRunner; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.InitializationError; -import org.junit.runners.model.TestClass; - -import org.springframework.core.annotation.MergedAnnotation; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; -import org.springframework.util.AntPathMatcher; -import org.springframework.util.StringUtils; - -/** - * - * A custom {@link BlockJUnit4ClassRunner} that runs tests using a modified class path. - * Entries are excluded from the class path using - * {@link ClassPathExclusions @ClassPathExclusions} and overridden using - * {@link ClassPathOverrides @ClassPathOverrides} on the test class. A class loader is - * created with the customized class path and is used both to load the test class and as - * the thread context class loader while the test is being run. - * - * @author Andy Wilkinson - * @deprecated Replaced by {@link ModifiedClassPathExtension} - */ - -@Deprecated -public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { - - private static final Pattern INTELLIJ_CLASSPATH_JAR_PATTERN = Pattern.compile(".*classpath(\\d+)?\\.jar"); - - public ModifiedClassPathRunner(Class testClass) throws InitializationError { - super(testClass); - } - - @Override - protected TestClass createTestClass(Class testClass) { - try { - ClassLoader classLoader = createTestClassLoader(testClass); - return new ModifiedClassPathTestClass(classLoader, testClass.getName()); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - } - - @Override - protected Object createTest() throws Exception { - ModifiedClassPathTestClass testClass = (ModifiedClassPathTestClass) getTestClass(); - return testClass.doWithModifiedClassPathThreadContextClassLoader(ModifiedClassPathRunner.super::createTest); - } - - private URLClassLoader createTestClassLoader(Class testClass) throws Exception { - ClassLoader classLoader = this.getClass().getClassLoader(); - return new ModifiedClassPathClassLoader(processUrls(extractUrls(classLoader), testClass), - classLoader.getParent(), classLoader); - } - - private URL[] extractUrls(ClassLoader classLoader) throws Exception { - List extractedUrls = new ArrayList<>(); - doExtractUrls(classLoader).forEach((URL url) -> { - if (isManifestOnlyJar(url)) { - extractedUrls.addAll(extractUrlsFromManifestClassPath(url)); - } - else { - extractedUrls.add(url); - } - }); - return extractedUrls.toArray(new URL[0]); - } - - private Stream doExtractUrls(ClassLoader classLoader) { - if (classLoader instanceof URLClassLoader) { - return Stream.of(((URLClassLoader) classLoader).getURLs()); - } - return Stream.of(ManagementFactory.getRuntimeMXBean().getClassPath().split(File.pathSeparator)) - .map(this::toURL); - } - - private URL toURL(String entry) { - try { - return new File(entry).toURI().toURL(); - } - catch (Exception ex) { - throw new IllegalArgumentException(ex); - } - } - - private boolean isManifestOnlyJar(URL url) { - return isSurefireBooterJar(url) || isShortenedIntelliJJar(url); - } - - private boolean isSurefireBooterJar(URL url) { - return url.getPath().contains("surefirebooter"); - } - - private boolean isShortenedIntelliJJar(URL url) { - String urlPath = url.getPath(); - boolean isCandidate = INTELLIJ_CLASSPATH_JAR_PATTERN.matcher(urlPath).matches(); - if (isCandidate) { - try { - Attributes attributes = getManifestMainAttributesFromUrl(url); - String createdBy = attributes.getValue("Created-By"); - return createdBy != null && createdBy.contains("IntelliJ"); - } - catch (Exception ex) { - } - } - return false; - } - - private List extractUrlsFromManifestClassPath(URL booterJar) { - List urls = new ArrayList<>(); - try { - for (String entry : getClassPath(booterJar)) { - urls.add(new URL(entry)); - } - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - return urls; - } - - private String[] getClassPath(URL booterJar) throws Exception { - Attributes attributes = getManifestMainAttributesFromUrl(booterJar); - return StringUtils.delimitedListToStringArray(attributes.getValue(Attributes.Name.CLASS_PATH), " "); - } - - private Attributes getManifestMainAttributesFromUrl(URL url) throws Exception { - try (JarFile jarFile = new JarFile(new File(url.toURI()))) { - return jarFile.getManifest().getMainAttributes(); - } - } - - private URL[] processUrls(URL[] urls, Class testClass) throws Exception { - MergedAnnotations annotations = MergedAnnotations.from(testClass, SearchStrategy.TYPE_HIERARCHY); - ClassPathEntryFilter filter = new ClassPathEntryFilter(annotations.get(ClassPathExclusions.class)); - List additionalUrls = getAdditionalUrls(annotations.get(ClassPathOverrides.class)); - List processedUrls = new ArrayList<>(additionalUrls); - for (URL url : urls) { - if (!filter.isExcluded(url)) { - processedUrls.add(url); - } - } - return processedUrls.toArray(new URL[0]); - } - - private List getAdditionalUrls(MergedAnnotation annotation) throws Exception { - if (!annotation.isPresent()) { - return Collections.emptyList(); - } - return resolveCoordinates(annotation.getStringArray(MergedAnnotation.VALUE)); - } - - private List resolveCoordinates(String[] coordinates) throws Exception { - DefaultServiceLocator serviceLocator = MavenRepositorySystemUtils.newServiceLocator(); - serviceLocator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); - serviceLocator.addService(TransporterFactory.class, HttpTransporterFactory.class); - RepositorySystem repositorySystem = serviceLocator.getService(RepositorySystem.class); - DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); - LocalRepository localRepository = new LocalRepository(System.getProperty("user.home") + "/.m2/repository"); - session.setLocalRepositoryManager(repositorySystem.newLocalRepositoryManager(session, localRepository)); - CollectRequest collectRequest = new CollectRequest(null, Collections.singletonList( - new RemoteRepository.Builder("central", "default", "https://repo.maven.apache.org/maven2").build())); - - collectRequest.setDependencies(createDependencies(coordinates)); - DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, null); - DependencyResult result = repositorySystem.resolveDependencies(session, dependencyRequest); - List resolvedArtifacts = new ArrayList<>(); - for (ArtifactResult artifact : result.getArtifactResults()) { - resolvedArtifacts.add(artifact.getArtifact().getFile().toURI().toURL()); - } - return resolvedArtifacts; - } - - private List createDependencies(String[] allCoordinates) { - List dependencies = new ArrayList<>(); - for (String coordinate : allCoordinates) { - dependencies.add(new Dependency(new DefaultArtifact(coordinate), null)); - } - return dependencies; - } - - /** - * Filter for class path entries. - */ - private static final class ClassPathEntryFilter { - - private final List exclusions; - - private final AntPathMatcher matcher = new AntPathMatcher(); - - private ClassPathEntryFilter(MergedAnnotation annotation) { - this.exclusions = new ArrayList<>(); - this.exclusions.add("log4j-*.jar"); - if (annotation.isPresent()) { - this.exclusions.addAll(Arrays.asList(annotation.getStringArray(MergedAnnotation.VALUE))); - } - } - - private boolean isExcluded(URL url) throws Exception { - if (!"file".equals(url.getProtocol())) { - return false; - } - String name = new File(url.toURI()).getName(); - for (String exclusion : this.exclusions) { - if (this.matcher.match(exclusion, name)) { - return true; - } - } - return false; - } - - } - - /** - * Custom {@link TestClass} that uses a modified class path. - */ - private static final class ModifiedClassPathTestClass extends TestClass { - - private final ClassLoader classLoader; - - ModifiedClassPathTestClass(ClassLoader classLoader, String testClassName) throws ClassNotFoundException { - super(classLoader.loadClass(testClassName)); - this.classLoader = classLoader; - } - - @Override - public List getAnnotatedMethods(Class annotationClass) { - try { - return getAnnotatedMethods(annotationClass.getName()); - } - catch (ClassNotFoundException ex) { - throw new RuntimeException(ex); - } - } - - @SuppressWarnings("unchecked") - private List getAnnotatedMethods(String annotationClassName) throws ClassNotFoundException { - Class annotationClass = (Class) this.classLoader - .loadClass(annotationClassName); - List methods = super.getAnnotatedMethods(annotationClass); - return wrapFrameworkMethods(methods); - } - - private List wrapFrameworkMethods(List methods) { - List wrapped = new ArrayList<>(methods.size()); - for (FrameworkMethod frameworkMethod : methods) { - wrapped.add(new ModifiedClassPathFrameworkMethod(frameworkMethod.getMethod())); - } - return wrapped; - } - - private T doWithModifiedClassPathThreadContextClassLoader( - ModifiedClassPathTcclAction action) throws E { - ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(this.classLoader); - try { - return action.perform(); - } - finally { - Thread.currentThread().setContextClassLoader(originalClassLoader); - } - } - - /** - * An action to be performed with the {@link ModifiedClassPathClassLoader} set as - * the thread context class loader. - */ - private interface ModifiedClassPathTcclAction { - - T perform() throws E; - - } - - /** - * Custom {@link FrameworkMethod} that runs methods with - * {@link ModifiedClassPathClassLoader} as the thread context class loader. - */ - private final class ModifiedClassPathFrameworkMethod extends FrameworkMethod { - - private ModifiedClassPathFrameworkMethod(Method method) { - super(method); - } - - @Override - public Object invokeExplosively(Object target, Object... params) throws Throwable { - return doWithModifiedClassPathThreadContextClassLoader( - () -> ModifiedClassPathFrameworkMethod.super.invokeExplosively(target, params)); - } - - } - - } - - /** - * Custom {@link URLClassLoader} that modifies the class path. - */ - private static final class ModifiedClassPathClassLoader extends URLClassLoader { - - private final ClassLoader junitLoader; - - ModifiedClassPathClassLoader(URL[] urls, ClassLoader parent, ClassLoader junitLoader) { - super(urls, parent); - this.junitLoader = junitLoader; - } - - @Override - public Class loadClass(String name) throws ClassNotFoundException { - if (name.startsWith("org.junit") || name.startsWith("org.hamcrest")) { - return this.junitLoader.loadClass(name); - } - return super.loadClass(name); - } - - } - -} diff --git a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/TestSocketUtils.java b/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/TestSocketUtils.java deleted file mode 100644 index f877430e..00000000 --- a/spring-cloud-test-support/src/main/java/org/springframework/cloud/test/TestSocketUtils.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright 2002-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.util.Random; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.net.ServerSocketFactory; - -import org.springframework.util.Assert; - -/** - * Simple utility methods for working with network sockets — for example, for - * finding available ports on {@code localhost}. - * - *

- * Within this class, a TCP port refers to a port for a {@link ServerSocket}; whereas, a - * UDP port refers to a port for a {@link DatagramSocket}. - * - *

- * {@code SocketUtils} was introduced in Spring Framework 4.0, primarily to assist in - * writing integration tests which start an external server on an available random port. - * However, these utilities make no guarantee about the subsequent availability of a given - * port and are therefore unreliable. Instead of using {@code SocketUtils} to find an - * available local port for a server, it is recommended that you rely on a server's - * ability to start on a random port that it selects or is assigned by the operating - * system. To interact with that server, you should query the server for the port it is - * currently using. - * - * @author Sam Brannen - * @author Ben Hale - * @author Arjen Poutsma - * @author Gunnar Hillert - * @author Gary Russell - * @since 4.0 - */ -public abstract class TestSocketUtils { - - /** - * The default minimum value for port ranges used when finding an available socket - * port. - */ - public static final int PORT_RANGE_MIN = 1024; - - /** - * The default maximum value for port ranges used when finding an available socket - * port. - */ - public static final int PORT_RANGE_MAX = 65535; - - private static final Random random = new Random(System.nanoTime()); - - /** - * Find an available TCP port randomly selected from the range - * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort() { - return findAvailableTcpPort(PORT_RANGE_MIN); - } - - /** - * Find an available TCP port randomly selected from the range [{@code minPort}, - * {@value #PORT_RANGE_MAX}]. - * @param minPort the minimum port number - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort(int minPort) { - return findAvailableTcpPort(minPort, PORT_RANGE_MAX); - } - - /** - * Find an available TCP port randomly selected from the range [{@code minPort}, - * {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available TCP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableTcpPort(int minPort, int maxPort) { - return SocketType.TCP.findAvailablePort(minPort, maxPort); - } - - /** - * Find the requested number of available TCP ports, each randomly selected from the - * range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @param numRequested the number of available ports to find - * @return a sorted set of available TCP port numbers - * @throws IllegalStateException if the requested number of available ports could not - * be found - */ - public static SortedSet findAvailableTcpPorts(int numRequested) { - return findAvailableTcpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); - } - - /** - * Find the requested number of available TCP ports, each randomly selected from the - * range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available TCP port numbers - * @throws IllegalStateException if the requested number of available ports could not - * be found - */ - public static SortedSet findAvailableTcpPorts(int numRequested, int minPort, int maxPort) { - return SocketType.TCP.findAvailablePorts(numRequested, minPort, maxPort); - } - - /** - * Find an available UDP port randomly selected from the range - * [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort() { - return findAvailableUdpPort(PORT_RANGE_MIN); - } - - /** - * Find an available UDP port randomly selected from the range [{@code minPort}, - * {@value #PORT_RANGE_MAX}]. - * @param minPort the minimum port number - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort(int minPort) { - return findAvailableUdpPort(minPort, PORT_RANGE_MAX); - } - - /** - * Find an available UDP port randomly selected from the range [{@code minPort}, - * {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available UDP port number - * @throws IllegalStateException if no available port could be found - */ - public static int findAvailableUdpPort(int minPort, int maxPort) { - return SocketType.UDP.findAvailablePort(minPort, maxPort); - } - - /** - * Find the requested number of available UDP ports, each randomly selected from the - * range [{@value #PORT_RANGE_MIN}, {@value #PORT_RANGE_MAX}]. - * @param numRequested the number of available ports to find - * @return a sorted set of available UDP port numbers - * @throws IllegalStateException if the requested number of available ports could not - * be found - */ - public static SortedSet findAvailableUdpPorts(int numRequested) { - return findAvailableUdpPorts(numRequested, PORT_RANGE_MIN, PORT_RANGE_MAX); - } - - /** - * Find the requested number of available UDP ports, each randomly selected from the - * range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available UDP port numbers - * @throws IllegalStateException if the requested number of available ports could not - * be found - */ - public static SortedSet findAvailableUdpPorts(int numRequested, int minPort, int maxPort) { - return SocketType.UDP.findAvailablePorts(numRequested, minPort, maxPort); - } - - private enum SocketType { - - TCP { - @Override - protected boolean isPortAvailable(int port) { - try { - ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(port, 1, - InetAddress.getByName("localhost")); - serverSocket.close(); - return true; - } - catch (Exception ex) { - return false; - } - } - }, - - UDP { - @Override - protected boolean isPortAvailable(int port) { - try { - DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost")); - socket.close(); - return true; - } - catch (Exception ex) { - return false; - } - } - }; - - /** - * Determine if the specified port for this {@code SocketType} is currently - * available on {@code localhost}. - */ - protected abstract boolean isPortAvailable(int port); - - /** - * Find a pseudo-random port number within the range [{@code minPort}, - * {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a random port number within the specified range - */ - private int findRandomPort(int minPort, int maxPort) { - int portRange = maxPort - minPort; - return minPort + random.nextInt(portRange + 1); - } - - /** - * Find an available port for this {@code SocketType}, randomly selected from the - * range [{@code minPort}, {@code maxPort}]. - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return an available port number for this socket type - * @throws IllegalStateException if no available port could be found - */ - int findAvailablePort(int minPort, int maxPort) { - Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); - Assert.isTrue(maxPort >= minPort, "'maxPort' must be greater than or equal to 'minPort'"); - Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); - - int portRange = maxPort - minPort; - int candidatePort; - int searchCounter = 0; - do { - if (searchCounter > portRange) { - throw new IllegalStateException( - String.format("Could not find an available %s port in the range [%d, %d] after %d attempts", - name(), minPort, maxPort, searchCounter)); - } - candidatePort = findRandomPort(minPort, maxPort); - searchCounter++; - } - while (!isPortAvailable(candidatePort)); - - return candidatePort; - } - - /** - * Find the requested number of available ports for this {@code SocketType}, each - * randomly selected from the range [{@code minPort}, {@code maxPort}]. - * @param numRequested the number of available ports to find - * @param minPort the minimum port number - * @param maxPort the maximum port number - * @return a sorted set of available port numbers for this socket type - * @throws IllegalStateException if the requested number of available ports could - * not be found - */ - SortedSet findAvailablePorts(int numRequested, int minPort, int maxPort) { - Assert.isTrue(minPort > 0, "'minPort' must be greater than 0"); - Assert.isTrue(maxPort > minPort, "'maxPort' must be greater than 'minPort'"); - Assert.isTrue(maxPort <= PORT_RANGE_MAX, "'maxPort' must be less than or equal to " + PORT_RANGE_MAX); - Assert.isTrue(numRequested > 0, "'numRequested' must be greater than 0"); - Assert.isTrue((maxPort - minPort) >= numRequested, - "'numRequested' must not be greater than 'maxPort' - 'minPort'"); - - SortedSet availablePorts = new TreeSet<>(); - int attemptCount = 0; - while ((++attemptCount <= numRequested + 100) && availablePorts.size() < numRequested) { - availablePorts.add(findAvailablePort(minPort, maxPort)); - } - - if (availablePorts.size() != numRequested) { - throw new IllegalStateException( - String.format("Could not find %d available %s ports in the range [%d, %d]", numRequested, - name(), minPort, maxPort)); - } - - return availablePorts; - } - - } - -} diff --git a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerExclusionsTests.java b/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerExclusionsTests.java deleted file mode 100644 index e35c996c..00000000 --- a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerExclusionsTests.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import org.hamcrest.Matcher; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.isA; - -/** - * Tests for {@link ModifiedClassPathExtension} excluding entries from the class path. - * - * @author Andy Wilkinson - */ -@ClassPathExclusions("hibernate-validator-*.jar") -public class ModifiedClassPathRunnerExclusionsTests { - - private static final String EXCLUDED_RESOURCE = "META-INF/services/" + "javax.validation.spi.ValidationProvider"; - - @Test - public void entriesAreFilteredFromTestClassClassLoader() { - assertThat(getClass().getClassLoader().getResource(EXCLUDED_RESOURCE)).isNull(); - } - - @Test - public void entriesAreFilteredFromThreadContextClassLoader() { - assertThat(Thread.currentThread().getContextClassLoader().getResource(EXCLUDED_RESOURCE)).isNull(); - } - - @Test - public void testsThatUseHamcrestWorkCorrectly() { - Matcher matcher = isA(IllegalStateException.class); - assertThat(matcher.matches(new IllegalStateException())).isTrue(); - } - -} diff --git a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerOverridesTests.java b/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerOverridesTests.java deleted file mode 100644 index 6b6ccd30..00000000 --- a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/ModifiedClassPathRunnerOverridesTests.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2012-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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import org.junit.jupiter.api.Test; - -import org.springframework.context.ApplicationContext; -import org.springframework.util.StringUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link ModifiedClassPathExtension} overriding entries on the class path. - * - * @author Andy Wilkinson - */ -@ClassPathOverrides("org.springframework:spring-context:4.1.0.RELEASE") -public class ModifiedClassPathRunnerOverridesTests { - - @Test - public void classesAreLoadedFromOverride() { - assertThat(ApplicationContext.class.getProtectionDomain().getCodeSource().getLocation().toString()) - .endsWith("spring-context-4.1.0.RELEASE.jar"); - } - - @Test - public void classesAreLoadedFromTransitiveDependencyOfOverride() { - assertThat(StringUtils.class.getProtectionDomain().getCodeSource().getLocation().toString()) - .endsWith("spring-core-4.1.0.RELEASE.jar"); - } - -} diff --git a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/TestSocketUtilsTests.java b/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/TestSocketUtilsTests.java deleted file mode 100644 index 20c1600a..00000000 --- a/spring-cloud-test-support/src/test/java/org/springframework/cloud/test/TestSocketUtilsTests.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2002-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.test; - -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.util.SortedSet; - -import javax.net.ServerSocketFactory; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; - -/** - * Unit tests for {@link TestSocketUtils}. - * - * @author Sam Brannen - * @author Gary Russell - */ -class TestSocketUtilsTests { - - // TCP - - @Test - void findAvailableTcpPortWithZeroMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> TestSocketUtils.findAvailableTcpPort(0)); - } - - @Test - void findAvailableTcpPortWithNegativeMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> TestSocketUtils.findAvailableTcpPort(-500)); - } - - @Test - void findAvailableTcpPort() { - int port = TestSocketUtils.findAvailableTcpPort(); - assertPortInRange(port, TestSocketUtils.PORT_RANGE_MIN, TestSocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableTcpPortWithMinPortEqualToMaxPort() { - int minMaxPort = TestSocketUtils.findAvailableTcpPort(); - int port = TestSocketUtils.findAvailableTcpPort(minMaxPort, minMaxPort); - assertThat(port).isEqualTo(minMaxPort); - } - - @Test - void findAvailableTcpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception { - int port = TestSocketUtils.findAvailableTcpPort(); - try (ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(port, 1, - InetAddress.getByName("localhost"))) { - assertThat(socket).isNotNull(); - // will only look for the exact port - assertThatIllegalStateException().isThrownBy(() -> TestSocketUtils.findAvailableTcpPort(port, port)) - .withMessageStartingWith("Could not find an available TCP port") - .withMessageEndingWith("after 1 attempts"); - } - } - - @Test - void findAvailableTcpPortWithMin() { - int port = TestSocketUtils.findAvailableTcpPort(50000); - assertPortInRange(port, 50000, TestSocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableTcpPortInRange() { - int minPort = 20000; - int maxPort = minPort + 1000; - int port = TestSocketUtils.findAvailableTcpPort(minPort, maxPort); - assertPortInRange(port, minPort, maxPort); - } - - @Test - void find4AvailableTcpPorts() { - findAvailableTcpPorts(4); - } - - @Test - void find50AvailableTcpPorts() { - findAvailableTcpPorts(50); - } - - @Test - void find4AvailableTcpPortsInRange() { - findAvailableTcpPorts(4, 30000, 35000); - } - - @Test - void find50AvailableTcpPortsInRange() { - findAvailableTcpPorts(50, 40000, 45000); - } - - @Test - void findAvailableTcpPortsWithRequestedNumberGreaterThanSizeOfRange() { - assertThatIllegalArgumentException().isThrownBy(() -> findAvailableTcpPorts(50, 45000, 45010)); - } - - // UDP - - @Test - void findAvailableUdpPortWithZeroMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> TestSocketUtils.findAvailableUdpPort(0)); - } - - @Test - void findAvailableUdpPortWithNegativeMinPort() { - assertThatIllegalArgumentException().isThrownBy(() -> TestSocketUtils.findAvailableUdpPort(-500)); - } - - @Test - void findAvailableUdpPort() { - int port = TestSocketUtils.findAvailableUdpPort(); - assertPortInRange(port, TestSocketUtils.PORT_RANGE_MIN, TestSocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableUdpPortWhenPortOnLoopbackInterfaceIsNotAvailable() throws Exception { - int port = TestSocketUtils.findAvailableUdpPort(); - try (DatagramSocket socket = new DatagramSocket(port, InetAddress.getByName("localhost"))) { - assertThat(socket).isNotNull(); - // will only look for the exact port - assertThatIllegalStateException().isThrownBy(() -> TestSocketUtils.findAvailableUdpPort(port, port)) - .withMessageStartingWith("Could not find an available UDP port") - .withMessageEndingWith("after 1 attempts"); - } - } - - @Test - void findAvailableUdpPortWithMin() { - int port = TestSocketUtils.findAvailableUdpPort(50000); - assertPortInRange(port, 50000, TestSocketUtils.PORT_RANGE_MAX); - } - - @Test - void findAvailableUdpPortInRange() { - int minPort = 20000; - int maxPort = minPort + 1000; - int port = TestSocketUtils.findAvailableUdpPort(minPort, maxPort); - assertPortInRange(port, minPort, maxPort); - } - - @Test - void find4AvailableUdpPorts() { - findAvailableUdpPorts(4); - } - - @Test - void find50AvailableUdpPorts() { - findAvailableUdpPorts(50); - } - - @Test - void find4AvailableUdpPortsInRange() { - findAvailableUdpPorts(4, 30000, 35000); - } - - @Test - void find50AvailableUdpPortsInRange() { - findAvailableUdpPorts(50, 40000, 45000); - } - - @Test - void findAvailableUdpPortsWithRequestedNumberGreaterThanSizeOfRange() { - assertThatIllegalArgumentException().isThrownBy(() -> findAvailableUdpPorts(50, 45000, 45010)); - } - - // Helpers - - private void findAvailableTcpPorts(int numRequested) { - SortedSet ports = TestSocketUtils.findAvailableTcpPorts(numRequested); - assertAvailablePorts(ports, numRequested, TestSocketUtils.PORT_RANGE_MIN, TestSocketUtils.PORT_RANGE_MAX); - } - - private void findAvailableTcpPorts(int numRequested, int minPort, int maxPort) { - SortedSet ports = TestSocketUtils.findAvailableTcpPorts(numRequested, minPort, maxPort); - assertAvailablePorts(ports, numRequested, minPort, maxPort); - } - - private void findAvailableUdpPorts(int numRequested) { - SortedSet ports = TestSocketUtils.findAvailableUdpPorts(numRequested); - assertAvailablePorts(ports, numRequested, TestSocketUtils.PORT_RANGE_MIN, TestSocketUtils.PORT_RANGE_MAX); - } - - private void findAvailableUdpPorts(int numRequested, int minPort, int maxPort) { - SortedSet ports = TestSocketUtils.findAvailableUdpPorts(numRequested, minPort, maxPort); - assertAvailablePorts(ports, numRequested, minPort, maxPort); - } - - private void assertPortInRange(int port, int minPort, int maxPort) { - assertThat(port >= minPort).as("port [" + port + "] >= " + minPort).isTrue(); - assertThat(port <= maxPort).as("port [" + port + "] <= " + maxPort).isTrue(); - } - - private void assertAvailablePorts(SortedSet ports, int numRequested, int minPort, int maxPort) { - assertThat(ports.size()).as("number of ports requested").isEqualTo(numRequested); - for (int port : ports) { - assertPortInRange(port, minPort, maxPort); - } - } - -} diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml deleted file mode 100644 index 9d2f3dc5..00000000 --- a/src/checkstyle/checkstyle-suppressions.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/supplemental-ui/partials/nav-search.hbs b/supplemental-ui/partials/nav-search.hbs new file mode 100644 index 00000000..5e379552 --- /dev/null +++ b/supplemental-ui/partials/nav-search.hbs @@ -0,0 +1,11 @@ +{{#if env.ALGOLIA_API_KEY}} +

+{{/if}} diff --git a/supplemental-ui/partials/search.hbs b/supplemental-ui/partials/search.hbs new file mode 100644 index 00000000..384e505f --- /dev/null +++ b/supplemental-ui/partials/search.hbs @@ -0,0 +1,27 @@ + +{{#if env.ALGOLIA_API_KEY}} + + + + + + + + +{{/if}}