Bumping versions
This commit is contained in:
@@ -47,12 +47,9 @@ import org.springframework.context.annotation.Lazy;
|
|||||||
* @author Scott Frederick
|
* @author Scott Frederick
|
||||||
*/
|
*/
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(prefix = "spring.cloud.cloudfoundry",
|
@ConditionalOnProperty(prefix = "spring.cloud.cloudfoundry", name = { "username", "password" })
|
||||||
name = { "username", "password" })
|
@ConditionalOnClass(name = { "reactor.core.publisher.Flux", "org.cloudfoundry.operations.DefaultCloudFoundryOperations",
|
||||||
@ConditionalOnClass(name = { "reactor.core.publisher.Flux",
|
"org.cloudfoundry.reactor.client.ReactorCloudFoundryClient", "org.reactivestreams.Publisher" })
|
||||||
"org.cloudfoundry.operations.DefaultCloudFoundryOperations",
|
|
||||||
"org.cloudfoundry.reactor.client.ReactorCloudFoundryClient",
|
|
||||||
"org.reactivestreams.Publisher" })
|
|
||||||
@EnableConfigurationProperties(CloudFoundryProperties.class)
|
@EnableConfigurationProperties(CloudFoundryProperties.class)
|
||||||
public class CloudFoundryClientAutoConfiguration {
|
public class CloudFoundryClientAutoConfiguration {
|
||||||
|
|
||||||
@@ -65,59 +62,50 @@ public class CloudFoundryClientAutoConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@Lazy
|
@Lazy
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public CloudFoundryService cloudFoundryService(
|
public CloudFoundryService cloudFoundryService(CloudFoundryOperations cloudFoundryOperations) {
|
||||||
CloudFoundryOperations cloudFoundryOperations) {
|
|
||||||
return new CloudFoundryService(cloudFoundryOperations);
|
return new CloudFoundryService(cloudFoundryOperations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Lazy
|
@Lazy
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public DefaultCloudFoundryOperations cloudFoundryOperations(
|
public DefaultCloudFoundryOperations cloudFoundryOperations(CloudFoundryClient cloudFoundryClient,
|
||||||
CloudFoundryClient cloudFoundryClient, DopplerClient dopplerClient,
|
DopplerClient dopplerClient, RoutingClient routingClient, UaaClient uaaClient) {
|
||||||
RoutingClient routingClient, UaaClient uaaClient) {
|
|
||||||
String organization = this.cloudFoundryProperties.getOrg();
|
String organization = this.cloudFoundryProperties.getOrg();
|
||||||
String space = this.cloudFoundryProperties.getSpace();
|
String space = this.cloudFoundryProperties.getSpace();
|
||||||
return DefaultCloudFoundryOperations.builder()
|
return DefaultCloudFoundryOperations.builder().cloudFoundryClient(cloudFoundryClient)
|
||||||
.cloudFoundryClient(cloudFoundryClient).dopplerClient(dopplerClient)
|
.dopplerClient(dopplerClient).routingClient(routingClient).uaaClient(uaaClient)
|
||||||
.routingClient(routingClient).uaaClient(uaaClient)
|
|
||||||
.organization(organization).space(space).build();
|
.organization(organization).space(space).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Lazy
|
@Lazy
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public ReactorCloudFoundryClient cloudFoundryClient(
|
public ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext,
|
||||||
ConnectionContext connectionContext, TokenProvider tokenProvider) {
|
TokenProvider tokenProvider) {
|
||||||
return ReactorCloudFoundryClient.builder().connectionContext(connectionContext)
|
return ReactorCloudFoundryClient.builder().connectionContext(connectionContext).tokenProvider(tokenProvider)
|
||||||
.tokenProvider(tokenProvider).build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Lazy
|
@Lazy
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public DopplerClient dopplerClient(ConnectionContext connectionContext,
|
public DopplerClient dopplerClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
|
||||||
TokenProvider tokenProvider) {
|
return ReactorDopplerClient.builder().connectionContext(connectionContext).tokenProvider(tokenProvider).build();
|
||||||
return ReactorDopplerClient.builder().connectionContext(connectionContext)
|
|
||||||
.tokenProvider(tokenProvider).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Lazy
|
@Lazy
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public RoutingClient routingClient(ConnectionContext connectionContext,
|
public RoutingClient routingClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
|
||||||
TokenProvider tokenProvider) {
|
return ReactorRoutingClient.builder().connectionContext(connectionContext).tokenProvider(tokenProvider).build();
|
||||||
return ReactorRoutingClient.builder().connectionContext(connectionContext)
|
|
||||||
.tokenProvider(tokenProvider).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Lazy
|
@Lazy
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public ReactorUaaClient uaaClient(ConnectionContext connectionContext,
|
public ReactorUaaClient uaaClient(ConnectionContext connectionContext, TokenProvider tokenProvider) {
|
||||||
TokenProvider tokenProvider) {
|
return ReactorUaaClient.builder().connectionContext(connectionContext).tokenProvider(tokenProvider).build();
|
||||||
return ReactorUaaClient.builder().connectionContext(connectionContext)
|
|
||||||
.tokenProvider(tokenProvider).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -127,8 +115,7 @@ public class CloudFoundryClientAutoConfiguration {
|
|||||||
String apiHost = this.cloudFoundryProperties.getUrl();
|
String apiHost = this.cloudFoundryProperties.getUrl();
|
||||||
Boolean skipSslValidation = this.cloudFoundryProperties.isSkipSslValidation();
|
Boolean skipSslValidation = this.cloudFoundryProperties.isSkipSslValidation();
|
||||||
|
|
||||||
return DefaultConnectionContext.builder().apiHost(apiHost)
|
return DefaultConnectionContext.builder().apiHost(apiHost).skipSslValidation(skipSslValidation).build();
|
||||||
.skipSslValidation(skipSslValidation).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -137,8 +124,7 @@ public class CloudFoundryClientAutoConfiguration {
|
|||||||
public PasswordGrantTokenProvider tokenProvider() {
|
public PasswordGrantTokenProvider tokenProvider() {
|
||||||
String username = this.cloudFoundryProperties.getUsername();
|
String username = this.cloudFoundryProperties.getUsername();
|
||||||
String password = this.cloudFoundryProperties.getPassword();
|
String password = this.cloudFoundryProperties.getPassword();
|
||||||
return PasswordGrantTokenProvider.builder().password(password).username(username)
|
return PasswordGrantTokenProvider.builder().password(password).username(username).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,8 +146,7 @@ public class CloudFoundryProperties implements InitializingBean {
|
|||||||
vals.put("url", getUrl());
|
vals.put("url", getUrl());
|
||||||
vals.put("username", getUsername());
|
vals.put("username", getUsername());
|
||||||
vals.put("password", getPassword());
|
vals.put("password", getPassword());
|
||||||
vals.forEach((key, value) -> Assert.hasText(value,
|
vals.forEach((key, value) -> Assert.hasText(value, String.format("'%s' must be provided", key)));
|
||||||
String.format("'%s' must be provided", key)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,19 +37,14 @@ public class CloudFoundryService {
|
|||||||
this.cloudFoundryOperations = cloudFoundryOperations;
|
this.cloudFoundryOperations = cloudFoundryOperations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Flux<Tuple2<ApplicationDetail, InstanceDetail>> getApplicationInstances(
|
public Flux<Tuple2<ApplicationDetail, InstanceDetail>> getApplicationInstances(String serviceId) {
|
||||||
String serviceId) {
|
GetApplicationRequest applicationRequest = GetApplicationRequest.builder().name(serviceId).build();
|
||||||
GetApplicationRequest applicationRequest = GetApplicationRequest.builder()
|
return this.cloudFoundryOperations.applications().get(applicationRequest).flatMapMany(applicationDetail -> {
|
||||||
.name(serviceId).build();
|
Flux<InstanceDetail> ids = Flux.fromStream(applicationDetail.getInstanceDetails().stream())
|
||||||
return this.cloudFoundryOperations.applications().get(applicationRequest)
|
.filter(id -> id.getState().equalsIgnoreCase("RUNNING"));
|
||||||
.flatMapMany(applicationDetail -> {
|
Flux<ApplicationDetail> generate = Flux.generate(sink -> sink.next(applicationDetail));
|
||||||
Flux<InstanceDetail> ids = Flux
|
return generate.zipWith(ids);
|
||||||
.fromStream(applicationDetail.getInstanceDetails().stream())
|
});
|
||||||
.filter(id -> id.getState().equalsIgnoreCase("RUNNING"));
|
|
||||||
Flux<ApplicationDetail> generate = Flux
|
|
||||||
.generate(sink -> sink.next(applicationDetail));
|
|
||||||
return generate.zipWith(ids);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,12 +36,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
|
|
||||||
public class CloudFoundryClientAutoConfigurationTest {
|
public class CloudFoundryClientAutoConfigurationTest {
|
||||||
|
|
||||||
private final static String[] SPRING_CLOUD_PROPERTIES = {
|
private final static String[] SPRING_CLOUD_PROPERTIES = { "spring.cloud.cloudfoundry.username",
|
||||||
"spring.cloud.cloudfoundry.username", "spring.cloud.cloudfoundry.password", };
|
"spring.cloud.cloudfoundry.password", };
|
||||||
|
|
||||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(
|
.withConfiguration(AutoConfigurations.of(CloudFoundryClientAutoConfiguration.class));
|
||||||
AutoConfigurations.of(CloudFoundryClientAutoConfiguration.class));
|
|
||||||
|
|
||||||
private static boolean requiredPropertiesSet() {
|
private static boolean requiredPropertiesSet() {
|
||||||
for (String k : SPRING_CLOUD_PROPERTIES) {
|
for (String k : SPRING_CLOUD_PROPERTIES) {
|
||||||
@@ -59,13 +58,11 @@ public class CloudFoundryClientAutoConfigurationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void autoConfiguresBeansWithAllProperties() {
|
public void autoConfiguresBeansWithAllProperties() {
|
||||||
this.contextRunner.withPropertyValues("spring.cloud.cloudfoundry.username=user",
|
this.contextRunner.withPropertyValues("spring.cloud.cloudfoundry.username=user",
|
||||||
"spring.cloud.cloudfoundry.password=secret",
|
"spring.cloud.cloudfoundry.password=secret", "spring.cloud.cloudfoundry.org=myorg",
|
||||||
"spring.cloud.cloudfoundry.org=myorg",
|
|
||||||
"spring.cloud.cloudfoundry.space=myspace").run((context) -> {
|
"spring.cloud.cloudfoundry.space=myspace").run((context) -> {
|
||||||
assertCloudFoundryClientBeansPresent(context);
|
assertCloudFoundryClientBeansPresent(context);
|
||||||
|
|
||||||
DefaultCloudFoundryOperations operations = context
|
DefaultCloudFoundryOperations operations = context.getBean(DefaultCloudFoundryOperations.class);
|
||||||
.getBean(DefaultCloudFoundryOperations.class);
|
|
||||||
assertThat(operations.getOrganization()).isEqualTo("myorg");
|
assertThat(operations.getOrganization()).isEqualTo("myorg");
|
||||||
assertThat(operations.getSpace()).isEqualTo("myspace");
|
assertThat(operations.getSpace()).isEqualTo("myspace");
|
||||||
});
|
});
|
||||||
@@ -77,8 +74,7 @@ public class CloudFoundryClientAutoConfigurationTest {
|
|||||||
"spring.cloud.cloudfoundry.password=secret").run((context) -> {
|
"spring.cloud.cloudfoundry.password=secret").run((context) -> {
|
||||||
assertCloudFoundryClientBeansPresent(context);
|
assertCloudFoundryClientBeansPresent(context);
|
||||||
|
|
||||||
DefaultCloudFoundryOperations operations = context
|
DefaultCloudFoundryOperations operations = context.getBean(DefaultCloudFoundryOperations.class);
|
||||||
.getBean(DefaultCloudFoundryOperations.class);
|
|
||||||
assertThat(operations.getOrganization()).isNullOrEmpty();
|
assertThat(operations.getOrganization()).isNullOrEmpty();
|
||||||
assertThat(operations.getSpace()).isNullOrEmpty();
|
assertThat(operations.getSpace()).isNullOrEmpty();
|
||||||
});
|
});
|
||||||
@@ -90,8 +86,7 @@ public class CloudFoundryClientAutoConfigurationTest {
|
|||||||
|
|
||||||
this.contextRunner.run((context) -> {
|
this.contextRunner.run((context) -> {
|
||||||
assertCloudFoundryClientBeansPresent(context);
|
assertCloudFoundryClientBeansPresent(context);
|
||||||
CloudFoundryOperations operations = context
|
CloudFoundryOperations operations = context.getBean(CloudFoundryOperations.class);
|
||||||
.getBean(CloudFoundryOperations.class);
|
|
||||||
|
|
||||||
OrganizationSummary summary = operations.organizations().list().blockFirst();
|
OrganizationSummary summary = operations.organizations().list().blockFirst();
|
||||||
|
|
||||||
@@ -101,8 +96,7 @@ public class CloudFoundryClientAutoConfigurationTest {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertCloudFoundryClientBeansPresent(
|
private void assertCloudFoundryClientBeansPresent(AssertableApplicationContext context) {
|
||||||
AssertableApplicationContext context) {
|
|
||||||
assertThat(context).hasSingleBean(ReactorCloudFoundryClient.class);
|
assertThat(context).hasSingleBean(ReactorCloudFoundryClient.class);
|
||||||
assertThat(context).hasSingleBean(DefaultCloudFoundryOperations.class);
|
assertThat(context).hasSingleBean(DefaultCloudFoundryOperations.class);
|
||||||
assertThat(context).hasSingleBean(DefaultConnectionContext.class);
|
assertThat(context).hasSingleBean(DefaultConnectionContext.class);
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ public class CloudFoundryAppServiceDiscoveryClient extends CloudFoundryDiscovery
|
|||||||
|
|
||||||
private static final String INTERNAL_DOMAIN = "apps.internal";
|
private static final String INTERNAL_DOMAIN = "apps.internal";
|
||||||
|
|
||||||
CloudFoundryAppServiceDiscoveryClient(CloudFoundryOperations cloudFoundryOperations,
|
CloudFoundryAppServiceDiscoveryClient(CloudFoundryOperations cloudFoundryOperations, CloudFoundryService svc,
|
||||||
CloudFoundryService svc,
|
|
||||||
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
||||||
super(cloudFoundryOperations, svc, cloudFoundryDiscoveryProperties);
|
super(cloudFoundryOperations, svc, cloudFoundryDiscoveryProperties);
|
||||||
}
|
}
|
||||||
@@ -56,23 +55,19 @@ public class CloudFoundryAppServiceDiscoveryClient extends CloudFoundryDiscovery
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ServiceInstance> getInstances(String serviceId) {
|
public List<ServiceInstance> getInstances(String serviceId) {
|
||||||
return getCloudFoundryService()
|
return getCloudFoundryService().getApplicationInstances(serviceId)
|
||||||
.getApplicationInstances(serviceId).filter(tuple -> tuple.getT1()
|
.filter(tuple -> tuple.getT1().getUrls().stream().anyMatch(this::isInternalDomain)).map(tuple -> {
|
||||||
.getUrls().stream().anyMatch(this::isInternalDomain))
|
|
||||||
.map(tuple -> {
|
|
||||||
ApplicationDetail applicationDetail = tuple.getT1();
|
ApplicationDetail applicationDetail = tuple.getT1();
|
||||||
InstanceDetail instanceDetail = tuple.getT2();
|
InstanceDetail instanceDetail = tuple.getT2();
|
||||||
String applicationId = applicationDetail.getId();
|
String applicationId = applicationDetail.getId();
|
||||||
String applicationIndex = instanceDetail.getIndex();
|
String applicationIndex = instanceDetail.getIndex();
|
||||||
String name = applicationDetail.getName();
|
String name = applicationDetail.getName();
|
||||||
String url = applicationDetail.getUrls().stream()
|
String url = applicationDetail.getUrls().stream().filter(this::isInternalDomain).findFirst()
|
||||||
.filter(this::isInternalDomain).findFirst()
|
|
||||||
.map(x -> instanceDetail.getIndex() + "." + x).get();
|
.map(x -> instanceDetail.getIndex() + "." + x).get();
|
||||||
HashMap<String, String> metadata = new HashMap<>();
|
HashMap<String, String> metadata = new HashMap<>();
|
||||||
metadata.put("applicationId", applicationId);
|
metadata.put("applicationId", applicationId);
|
||||||
metadata.put("instanceId", applicationIndex);
|
metadata.put("instanceId", applicationIndex);
|
||||||
return (ServiceInstance) new DefaultServiceInstance(name, url, 8080,
|
return (ServiceInstance) new DefaultServiceInstance(name, url, 8080, false, metadata);
|
||||||
false, metadata);
|
|
||||||
}).collectList().block();
|
}).collectList().block();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,11 +48,10 @@ public class CloudFoundryDiscoveryClient implements DiscoveryClient {
|
|||||||
|
|
||||||
private final CloudFoundryDiscoveryProperties properties;
|
private final CloudFoundryDiscoveryProperties properties;
|
||||||
|
|
||||||
private final String description = "Cloud Foundry " + DiscoveryClient.class.getName()
|
private final String description = "Cloud Foundry " + DiscoveryClient.class.getName() + " implementation";
|
||||||
+ " implementation";
|
|
||||||
|
|
||||||
CloudFoundryDiscoveryClient(CloudFoundryOperations cloudFoundryOperations,
|
CloudFoundryDiscoveryClient(CloudFoundryOperations cloudFoundryOperations, CloudFoundryService svc,
|
||||||
CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
|
CloudFoundryDiscoveryProperties properties) {
|
||||||
this.cloudFoundryService = svc;
|
this.cloudFoundryService = svc;
|
||||||
this.cloudFoundryOperations = cloudFoundryOperations;
|
this.cloudFoundryOperations = cloudFoundryOperations;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
@@ -73,24 +72,22 @@ public class CloudFoundryDiscoveryClient implements DiscoveryClient {
|
|||||||
String applicationIndex = instanceDetail.getIndex();
|
String applicationIndex = instanceDetail.getIndex();
|
||||||
String instanceId = applicationId + "." + applicationIndex;
|
String instanceId = applicationId + "." + applicationIndex;
|
||||||
String name = applicationDetail.getName();
|
String name = applicationDetail.getName();
|
||||||
String url = applicationDetail.getUrls().size() > 0
|
String url = applicationDetail.getUrls().size() > 0 ? applicationDetail.getUrls().get(0) : null;
|
||||||
? applicationDetail.getUrls().get(0) : null;
|
|
||||||
boolean secure = (url + "").toLowerCase().startsWith("https");
|
boolean secure = (url + "").toLowerCase().startsWith("https");
|
||||||
|
|
||||||
HashMap<String, String> metadata = new HashMap<>();
|
HashMap<String, String> metadata = new HashMap<>();
|
||||||
metadata.put("applicationId", applicationId);
|
metadata.put("applicationId", applicationId);
|
||||||
metadata.put("instanceId", applicationIndex);
|
metadata.put("instanceId", applicationIndex);
|
||||||
|
|
||||||
return (ServiceInstance) new DefaultServiceInstance(instanceId, name, url,
|
return (ServiceInstance) new DefaultServiceInstance(instanceId, name, url, secure ? 443 : 80, secure,
|
||||||
secure ? 443 : 80, secure, metadata);
|
metadata);
|
||||||
}).collectList().blockOptional().orElse(new ArrayList<>());
|
}).collectList().blockOptional().orElse(new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getServices() {
|
public List<String> getServices() {
|
||||||
return this.cloudFoundryOperations.applications().list()
|
return this.cloudFoundryOperations.applications().list().map(ApplicationSummary::getName).collectList()
|
||||||
.map(ApplicationSummary::getName).collectList().blockOptional()
|
.blockOptional().orElse(new ArrayList<>());
|
||||||
.orElse(new ArrayList<>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -45,39 +45,32 @@ public class CloudFoundryDiscoveryClientConfiguration {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnBean(CloudFoundryDiscoveryClient.class)
|
@ConditionalOnBean(CloudFoundryDiscoveryClient.class)
|
||||||
public CloudFoundryHeartbeatSender cloudFoundryHeartbeatSender(
|
public CloudFoundryHeartbeatSender cloudFoundryHeartbeatSender(CloudFoundryDiscoveryClient client) {
|
||||||
CloudFoundryDiscoveryClient client) {
|
|
||||||
return new CloudFoundryHeartbeatSender(client);
|
return new CloudFoundryHeartbeatSender(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "false",
|
||||||
havingValue = "false", matchIfMissing = true)
|
matchIfMissing = true)
|
||||||
public static class CloudFoundryDiscoveryClientConfig {
|
public static class CloudFoundryDiscoveryClientConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(DiscoveryClient.class)
|
@ConditionalOnMissingBean(DiscoveryClient.class)
|
||||||
public CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient(
|
public CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient(CloudFoundryOperations cf,
|
||||||
CloudFoundryOperations cf, CloudFoundryService svc,
|
CloudFoundryService svc, CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
||||||
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
return new CloudFoundryDiscoveryClient(cf, svc, cloudFoundryDiscoveryProperties);
|
||||||
return new CloudFoundryDiscoveryClient(cf, svc,
|
|
||||||
cloudFoundryDiscoveryProperties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "true")
|
||||||
havingValue = "true")
|
|
||||||
public static class DnsBasedCloudFoundryDiscoveryClientConfig {
|
public static class DnsBasedCloudFoundryDiscoveryClientConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "true")
|
||||||
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
|
|
||||||
havingValue = "true")
|
|
||||||
@ConditionalOnMissingBean(DiscoveryClient.class)
|
@ConditionalOnMissingBean(DiscoveryClient.class)
|
||||||
public SimpleDnsBasedDiscoveryClient discoveryClient(
|
public SimpleDnsBasedDiscoveryClient discoveryClient(ObjectProvider<ServiceIdToHostnameConverter> provider,
|
||||||
ObjectProvider<ServiceIdToHostnameConverter> provider,
|
|
||||||
CloudFoundryDiscoveryProperties properties) {
|
CloudFoundryDiscoveryProperties properties) {
|
||||||
ServiceIdToHostnameConverter converter = provider.getIfAvailable();
|
ServiceIdToHostnameConverter converter = provider.getIfAvailable();
|
||||||
return converter == null ? new SimpleDnsBasedDiscoveryClient(properties)
|
return converter == null ? new SimpleDnsBasedDiscoveryClient(properties)
|
||||||
@@ -85,13 +78,11 @@ public class CloudFoundryDiscoveryClientConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "false",
|
||||||
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
|
matchIfMissing = true)
|
||||||
havingValue = "false", matchIfMissing = true)
|
|
||||||
@ConditionalOnMissingBean(DiscoveryClient.class)
|
@ConditionalOnMissingBean(DiscoveryClient.class)
|
||||||
public CloudFoundryAppServiceDiscoveryClient cloudFoundryDiscoveryClient(
|
public CloudFoundryAppServiceDiscoveryClient cloudFoundryDiscoveryClient(CloudFoundryOperations cf,
|
||||||
CloudFoundryOperations cf, CloudFoundryService svc,
|
CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
|
||||||
CloudFoundryDiscoveryProperties properties) {
|
|
||||||
return new CloudFoundryAppServiceDiscoveryClient(cf, svc, properties);
|
return new CloudFoundryAppServiceDiscoveryClient(cf, svc, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,7 @@ public class CloudFoundryHeartbeatSender implements ApplicationEventPublisherAwa
|
|||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(
|
@Scheduled(fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
|
||||||
fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
|
|
||||||
public void poll() {
|
public void poll() {
|
||||||
if (this.publisher != null) {
|
if (this.publisher != null) {
|
||||||
List<String> services = this.client.getServices();
|
List<String> services = this.client.getServices();
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.enabled",
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.enabled", matchIfMissing = true)
|
||||||
matchIfMissing = true)
|
|
||||||
public @interface ConditionalOnCloudFoundryDiscoveryEnabled {
|
public @interface ConditionalOnCloudFoundryDiscoveryEnabled {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,7 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
|
|||||||
*/
|
*/
|
||||||
public class SimpleDnsBasedDiscoveryClient implements DiscoveryClient {
|
public class SimpleDnsBasedDiscoveryClient implements DiscoveryClient {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory
|
private static final Logger log = LoggerFactory.getLogger(SimpleDnsBasedDiscoveryClient.class);
|
||||||
.getLogger(SimpleDnsBasedDiscoveryClient.class);
|
|
||||||
|
|
||||||
private final ServiceIdToHostnameConverter serviceIdToHostnameConverter;
|
private final ServiceIdToHostnameConverter serviceIdToHostnameConverter;
|
||||||
|
|
||||||
@@ -67,8 +66,8 @@ public class SimpleDnsBasedDiscoveryClient implements DiscoveryClient {
|
|||||||
InetAddress[] addresses = InetAddress.getAllByName(hostname);
|
InetAddress[] addresses = InetAddress.getAllByName(hostname);
|
||||||
if (addresses != null) {
|
if (addresses != null) {
|
||||||
for (InetAddress address : addresses) {
|
for (InetAddress address : addresses) {
|
||||||
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(
|
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(serviceId,
|
||||||
serviceId, address.getHostAddress(), 8080, false);
|
address.getHostAddress(), 8080, false);
|
||||||
serviceInstances.add(serviceInstance);
|
serviceInstances.add(serviceInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,16 +34,14 @@ import org.springframework.cloud.cloudfoundry.discovery.CloudFoundryDiscoveryPro
|
|||||||
* "https://www.cloudfoundry.org/blog/polyglot-service-discovery-container-networking-cloud-foundry/">Polyglot
|
* "https://www.cloudfoundry.org/blog/polyglot-service-discovery-container-networking-cloud-foundry/">Polyglot
|
||||||
* Service Discovery for Container Networking in Cloud Foundry</a>
|
* Service Discovery for Container Networking in Cloud Foundry</a>
|
||||||
*/
|
*/
|
||||||
public class CloudFoundryAppServiceReactiveDiscoveryClient
|
public class CloudFoundryAppServiceReactiveDiscoveryClient extends CloudFoundryNativeReactiveDiscoveryClient {
|
||||||
extends CloudFoundryNativeReactiveDiscoveryClient {
|
|
||||||
|
|
||||||
private static final String INTERNAL_DOMAIN = "apps.internal";
|
private static final String INTERNAL_DOMAIN = "apps.internal";
|
||||||
|
|
||||||
private final CloudFoundryService cloudFoundryService;
|
private final CloudFoundryService cloudFoundryService;
|
||||||
|
|
||||||
CloudFoundryAppServiceReactiveDiscoveryClient(
|
CloudFoundryAppServiceReactiveDiscoveryClient(CloudFoundryOperations cloudFoundryOperations,
|
||||||
CloudFoundryOperations cloudFoundryOperations, CloudFoundryService svc,
|
CloudFoundryService svc, CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
||||||
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
|
||||||
super(cloudFoundryOperations, svc, cloudFoundryDiscoveryProperties);
|
super(cloudFoundryOperations, svc, cloudFoundryDiscoveryProperties);
|
||||||
this.cloudFoundryService = svc;
|
this.cloudFoundryService = svc;
|
||||||
}
|
}
|
||||||
@@ -56,8 +54,7 @@ public class CloudFoundryAppServiceReactiveDiscoveryClient
|
|||||||
@Override
|
@Override
|
||||||
public Flux<ServiceInstance> getInstances(String serviceId) {
|
public Flux<ServiceInstance> getInstances(String serviceId) {
|
||||||
return cloudFoundryService.getApplicationInstances(serviceId)
|
return cloudFoundryService.getApplicationInstances(serviceId)
|
||||||
.filter(tuple -> tuple.getT1().getUrls().stream()
|
.filter(tuple -> tuple.getT1().getUrls().stream().anyMatch(this::isInternalDomain))
|
||||||
.anyMatch(this::isInternalDomain))
|
|
||||||
.map(this::mapApplicationInstanceToServiceInstance);
|
.map(this::mapApplicationInstanceToServiceInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,8 +37,7 @@ import org.springframework.cloud.cloudfoundry.discovery.CloudFoundryDiscoveryPro
|
|||||||
*
|
*
|
||||||
* @author Tim Ysewyn
|
* @author Tim Ysewyn
|
||||||
*/
|
*/
|
||||||
public class CloudFoundryNativeReactiveDiscoveryClient
|
public class CloudFoundryNativeReactiveDiscoveryClient implements ReactiveDiscoveryClient {
|
||||||
implements ReactiveDiscoveryClient {
|
|
||||||
|
|
||||||
private final CloudFoundryService cloudFoundryService;
|
private final CloudFoundryService cloudFoundryService;
|
||||||
|
|
||||||
@@ -46,8 +45,8 @@ public class CloudFoundryNativeReactiveDiscoveryClient
|
|||||||
|
|
||||||
private final CloudFoundryDiscoveryProperties properties;
|
private final CloudFoundryDiscoveryProperties properties;
|
||||||
|
|
||||||
CloudFoundryNativeReactiveDiscoveryClient(CloudFoundryOperations operations,
|
CloudFoundryNativeReactiveDiscoveryClient(CloudFoundryOperations operations, CloudFoundryService svc,
|
||||||
CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
|
CloudFoundryDiscoveryProperties properties) {
|
||||||
this.cloudFoundryService = svc;
|
this.cloudFoundryService = svc;
|
||||||
this.cloudFoundryOperations = operations;
|
this.cloudFoundryOperations = operations;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
@@ -66,8 +65,7 @@ public class CloudFoundryNativeReactiveDiscoveryClient
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flux<String> getServices() {
|
public Flux<String> getServices() {
|
||||||
return this.cloudFoundryOperations.applications().list()
|
return this.cloudFoundryOperations.applications().list().map(ApplicationSummary::getName);
|
||||||
.map(ApplicationSummary::getName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -75,8 +73,7 @@ public class CloudFoundryNativeReactiveDiscoveryClient
|
|||||||
return this.properties.getOrder();
|
return this.properties.getOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ServiceInstance mapApplicationInstanceToServiceInstance(
|
protected ServiceInstance mapApplicationInstanceToServiceInstance(Tuple2<ApplicationDetail, InstanceDetail> tuple) {
|
||||||
Tuple2<ApplicationDetail, InstanceDetail> tuple) {
|
|
||||||
ApplicationDetail applicationDetail = tuple.getT1();
|
ApplicationDetail applicationDetail = tuple.getT1();
|
||||||
InstanceDetail instanceDetail = tuple.getT2();
|
InstanceDetail instanceDetail = tuple.getT2();
|
||||||
|
|
||||||
@@ -84,16 +81,14 @@ public class CloudFoundryNativeReactiveDiscoveryClient
|
|||||||
String applicationIndex = instanceDetail.getIndex();
|
String applicationIndex = instanceDetail.getIndex();
|
||||||
String instanceId = applicationId + "." + applicationIndex;
|
String instanceId = applicationId + "." + applicationIndex;
|
||||||
String name = applicationDetail.getName();
|
String name = applicationDetail.getName();
|
||||||
String url = applicationDetail.getUrls().size() > 0
|
String url = applicationDetail.getUrls().size() > 0 ? applicationDetail.getUrls().get(0) : null;
|
||||||
? applicationDetail.getUrls().get(0) : null;
|
|
||||||
boolean secure = (url + "").toLowerCase().startsWith("https");
|
boolean secure = (url + "").toLowerCase().startsWith("https");
|
||||||
|
|
||||||
HashMap<String, String> metadata = new HashMap<>();
|
HashMap<String, String> metadata = new HashMap<>();
|
||||||
metadata.put("applicationId", applicationId);
|
metadata.put("applicationId", applicationId);
|
||||||
metadata.put("instanceId", applicationIndex);
|
metadata.put("instanceId", applicationIndex);
|
||||||
|
|
||||||
return new DefaultServiceInstance(instanceId, name, url, secure ? 443 : 80,
|
return new DefaultServiceInstance(instanceId, name, url, secure ? 443 : 80, secure, metadata);
|
||||||
secure, metadata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,26 +55,22 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
public class CloudFoundryReactiveDiscoveryClientConfiguration {
|
public class CloudFoundryReactiveDiscoveryClientConfiguration {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "false",
|
||||||
havingValue = "false", matchIfMissing = true)
|
matchIfMissing = true)
|
||||||
public static class CloudFoundryNativeReactiveDiscoveryClientConfig {
|
public static class CloudFoundryNativeReactiveDiscoveryClientConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public CloudFoundryNativeReactiveDiscoveryClient nativeCloudFoundryDiscoveryClient(
|
public CloudFoundryNativeReactiveDiscoveryClient nativeCloudFoundryDiscoveryClient(CloudFoundryOperations cf,
|
||||||
CloudFoundryOperations cf, CloudFoundryService svc,
|
CloudFoundryService svc, CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
||||||
CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties) {
|
return new CloudFoundryNativeReactiveDiscoveryClient(cf, svc, cloudFoundryDiscoveryProperties);
|
||||||
return new CloudFoundryNativeReactiveDiscoveryClient(cf, svc,
|
|
||||||
cloudFoundryDiscoveryProperties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(
|
@ConditionalOnClass(name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
|
||||||
name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
|
|
||||||
@ConditionalOnDiscoveryHealthIndicatorEnabled
|
@ConditionalOnDiscoveryHealthIndicatorEnabled
|
||||||
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
|
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
|
||||||
CloudFoundryNativeReactiveDiscoveryClient client,
|
CloudFoundryNativeReactiveDiscoveryClient client, DiscoveryClientHealthIndicatorProperties properties) {
|
||||||
DiscoveryClientHealthIndicatorProperties properties) {
|
|
||||||
return new ReactiveDiscoveryClientHealthIndicator(client, properties);
|
return new ReactiveDiscoveryClientHealthIndicator(client, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,34 +83,27 @@ public class CloudFoundryReactiveDiscoveryClientConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns",
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-dns", havingValue = "true")
|
||||||
havingValue = "true")
|
|
||||||
public static class DnsConfig {
|
public static class DnsConfig {
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "true")
|
||||||
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
|
|
||||||
havingValue = "true")
|
|
||||||
public static class SimpleDnsConfig {
|
public static class SimpleDnsConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public SimpleDnsBasedReactiveDiscoveryClient dnsBasedReactiveDiscoveryClient(
|
public SimpleDnsBasedReactiveDiscoveryClient dnsBasedReactiveDiscoveryClient(
|
||||||
ObjectProvider<ServiceIdToHostnameConverter> provider,
|
ObjectProvider<ServiceIdToHostnameConverter> provider, CloudFoundryDiscoveryProperties properties) {
|
||||||
CloudFoundryDiscoveryProperties properties) {
|
|
||||||
ServiceIdToHostnameConverter converter = provider.getIfAvailable();
|
ServiceIdToHostnameConverter converter = provider.getIfAvailable();
|
||||||
return converter == null
|
return converter == null ? new SimpleDnsBasedReactiveDiscoveryClient(properties)
|
||||||
? new SimpleDnsBasedReactiveDiscoveryClient(properties)
|
|
||||||
: new SimpleDnsBasedReactiveDiscoveryClient(converter);
|
: new SimpleDnsBasedReactiveDiscoveryClient(converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(
|
@ConditionalOnClass(name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
|
||||||
name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
|
|
||||||
@ConditionalOnDiscoveryHealthIndicatorEnabled
|
@ConditionalOnDiscoveryHealthIndicatorEnabled
|
||||||
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
|
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
|
||||||
SimpleDnsBasedReactiveDiscoveryClient client,
|
SimpleDnsBasedReactiveDiscoveryClient client, DiscoveryClientHealthIndicatorProperties properties) {
|
||||||
DiscoveryClientHealthIndicatorProperties properties) {
|
|
||||||
return new ReactiveDiscoveryClientHealthIndicator(client, properties);
|
return new ReactiveDiscoveryClientHealthIndicator(client, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,23 +116,19 @@ public class CloudFoundryReactiveDiscoveryClientConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Configuration(proxyBeanMethods = false)
|
@Configuration(proxyBeanMethods = false)
|
||||||
@ConditionalOnProperty(
|
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.use-container-ip", havingValue = "false",
|
||||||
value = "spring.cloud.cloudfoundry.discovery.use-container-ip",
|
matchIfMissing = true)
|
||||||
havingValue = "false", matchIfMissing = true)
|
|
||||||
public static class AppServiceConfig {
|
public static class AppServiceConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public CloudFoundryAppServiceReactiveDiscoveryClient appServiceReactiveDiscoveryClient(
|
public CloudFoundryAppServiceReactiveDiscoveryClient appServiceReactiveDiscoveryClient(
|
||||||
CloudFoundryOperations cf, CloudFoundryService svc,
|
CloudFoundryOperations cf, CloudFoundryService svc, CloudFoundryDiscoveryProperties properties) {
|
||||||
CloudFoundryDiscoveryProperties properties) {
|
return new CloudFoundryAppServiceReactiveDiscoveryClient(cf, svc, properties);
|
||||||
return new CloudFoundryAppServiceReactiveDiscoveryClient(cf, svc,
|
|
||||||
properties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnClass(
|
@ConditionalOnClass(name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
|
||||||
name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
|
|
||||||
@ConditionalOnDiscoveryHealthIndicatorEnabled
|
@ConditionalOnDiscoveryHealthIndicatorEnabled
|
||||||
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
|
public ReactiveDiscoveryClientHealthIndicator cloudFoundryReactiveDiscoveryClientHealthIndicator(
|
||||||
CloudFoundryAppServiceReactiveDiscoveryClient client,
|
CloudFoundryAppServiceReactiveDiscoveryClient client,
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Tim Ysewyn
|
* @author Tim Ysewyn
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class CloudFoundryReactiveHeartbeatSender
|
public class CloudFoundryReactiveHeartbeatSender implements ApplicationEventPublisherAware {
|
||||||
implements ApplicationEventPublisherAware {
|
|
||||||
|
|
||||||
private final ReactiveDiscoveryClient client;
|
private final ReactiveDiscoveryClient client;
|
||||||
|
|
||||||
@@ -41,12 +40,10 @@ public class CloudFoundryReactiveHeartbeatSender
|
|||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(
|
@Scheduled(fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
|
||||||
fixedDelayString = "${spring.cloud.cloudfoundry.discovery.heartbeatFrequency:5000}")
|
|
||||||
public void poll() {
|
public void poll() {
|
||||||
if (this.publisher != null) {
|
if (this.publisher != null) {
|
||||||
this.publisher.publishEvent(
|
this.publisher.publishEvent(new HeartbeatEvent(this.client, this.client.getServices()));
|
||||||
new HeartbeatEvent(this.client, this.client.getServices()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,18 +42,15 @@ import org.springframework.cloud.cloudfoundry.discovery.CloudFoundryDiscoveryPro
|
|||||||
*/
|
*/
|
||||||
public class SimpleDnsBasedReactiveDiscoveryClient implements ReactiveDiscoveryClient {
|
public class SimpleDnsBasedReactiveDiscoveryClient implements ReactiveDiscoveryClient {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory
|
private static final Logger log = LoggerFactory.getLogger(SimpleDnsBasedReactiveDiscoveryClient.class);
|
||||||
.getLogger(SimpleDnsBasedReactiveDiscoveryClient.class);
|
|
||||||
|
|
||||||
private final ServiceIdToHostnameConverter serviceIdToHostnameConverter;
|
private final ServiceIdToHostnameConverter serviceIdToHostnameConverter;
|
||||||
|
|
||||||
public SimpleDnsBasedReactiveDiscoveryClient(
|
public SimpleDnsBasedReactiveDiscoveryClient(ServiceIdToHostnameConverter serviceIdToHostnameConverter) {
|
||||||
ServiceIdToHostnameConverter serviceIdToHostnameConverter) {
|
|
||||||
this.serviceIdToHostnameConverter = serviceIdToHostnameConverter;
|
this.serviceIdToHostnameConverter = serviceIdToHostnameConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleDnsBasedReactiveDiscoveryClient(
|
public SimpleDnsBasedReactiveDiscoveryClient(CloudFoundryDiscoveryProperties properties) {
|
||||||
CloudFoundryDiscoveryProperties properties) {
|
|
||||||
this(serviceId -> serviceId + "." + properties.getInternalDomain());
|
this(serviceId -> serviceId + "." + properties.getInternalDomain());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,10 +61,8 @@ public class SimpleDnsBasedReactiveDiscoveryClient implements ReactiveDiscoveryC
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Flux<ServiceInstance> getInstances(String serviceId) {
|
public Flux<ServiceInstance> getInstances(String serviceId) {
|
||||||
return Mono.justOrEmpty(serviceIdToHostnameConverter.toHostname(serviceId))
|
return Mono.justOrEmpty(serviceIdToHostnameConverter.toHostname(serviceId)).flatMapMany(getInetAddresses())
|
||||||
.flatMapMany(getInetAddresses())
|
.map(address -> new DefaultServiceInstance(serviceId, address.getHostAddress(), 8080, false));
|
||||||
.map(address -> new DefaultServiceInstance(serviceId,
|
|
||||||
address.getHostAddress(), 8080, false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Function<String, Publisher<? extends InetAddress>> getInetAddresses() {
|
private Function<String, Publisher<? extends InetAddress>> getInetAddresses() {
|
||||||
|
|||||||
@@ -50,26 +50,23 @@ public class CloudFoundryAppServiceDiscoveryClientTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
this.cloudFoundryOperations = mock(CloudFoundryOperations.class);
|
this.cloudFoundryOperations = mock(CloudFoundryOperations.class);
|
||||||
this.cloudFoundryService = mock(CloudFoundryService.class);
|
this.cloudFoundryService = mock(CloudFoundryService.class);
|
||||||
this.discoveryClient = new CloudFoundryAppServiceDiscoveryClient(
|
this.discoveryClient = new CloudFoundryAppServiceDiscoveryClient(this.cloudFoundryOperations,
|
||||||
this.cloudFoundryOperations, this.cloudFoundryService,
|
this.cloudFoundryService, new CloudFoundryDiscoveryProperties());
|
||||||
new CloudFoundryDiscoveryProperties());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getInstancesOneInstance() {
|
public void getInstancesOneInstance() {
|
||||||
String serviceId = "billing";
|
String serviceId = "billing";
|
||||||
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1")
|
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1").name("billing").instances(1)
|
||||||
.name("billing").instances(1).memoryLimit(1024).stack("cflinux2")
|
.memoryLimit(1024).stack("cflinux2").diskQuota(1024).requestedState("Running").runningInstances(1)
|
||||||
.diskQuota(1024).requestedState("Running").runningInstances(1)
|
|
||||||
.urls("billing.apps.example.com", "billing.apps.internal").build();
|
.urls("billing.apps.example.com", "billing.apps.internal").build();
|
||||||
given(this.cloudFoundryService.getApplicationInstances(serviceId))
|
given(this.cloudFoundryService.getApplicationInstances(serviceId))
|
||||||
.willReturn(Flux.just(Tuples.of(applicationDetail,
|
.willReturn(Flux.just(Tuples.of(applicationDetail, InstanceDetail.builder().index("0").build())));
|
||||||
InstanceDetail.builder().index("0").build())));
|
|
||||||
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
|
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
|
||||||
|
|
||||||
assertThat(instances).hasSize(1);
|
assertThat(instances).hasSize(1);
|
||||||
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId,
|
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId, "0.billing.apps.internal", 8080,
|
||||||
"0.billing.apps.internal", 8080, false, new HashMap<String, String>() {
|
false, new HashMap<String, String>() {
|
||||||
{
|
{
|
||||||
put("applicationId", "billing1");
|
put("applicationId", "billing1");
|
||||||
put("instanceId", "0");
|
put("instanceId", "0");
|
||||||
@@ -80,37 +77,32 @@ public class CloudFoundryAppServiceDiscoveryClientTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getInstancesThreeInstance() {
|
public void getInstancesThreeInstance() {
|
||||||
String serviceId = "billing";
|
String serviceId = "billing";
|
||||||
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing-id")
|
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing-id").name("billing").instances(3)
|
||||||
.name("billing").instances(3).memoryLimit(1024).stack("cflinux2")
|
.memoryLimit(1024).stack("cflinux2").diskQuota(1024).requestedState("Running").runningInstances(3)
|
||||||
.diskQuota(1024).requestedState("Running").runningInstances(3)
|
|
||||||
.urls("billing.apps.example.com", "billing.apps.internal").build();
|
.urls("billing.apps.example.com", "billing.apps.internal").build();
|
||||||
given(this.cloudFoundryService.getApplicationInstances(serviceId))
|
given(this.cloudFoundryService.getApplicationInstances(serviceId))
|
||||||
.willReturn(Flux.just(
|
.willReturn(Flux.just(Tuples.of(applicationDetail, InstanceDetail.builder().index("0").build()),
|
||||||
Tuples.of(applicationDetail,
|
Tuples.of(applicationDetail, InstanceDetail.builder().index("1").build()),
|
||||||
InstanceDetail.builder().index("0").build()),
|
Tuples.of(applicationDetail, InstanceDetail.builder().index("2").build())));
|
||||||
Tuples.of(applicationDetail,
|
|
||||||
InstanceDetail.builder().index("1").build()),
|
|
||||||
Tuples.of(applicationDetail,
|
|
||||||
InstanceDetail.builder().index("2").build())));
|
|
||||||
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
|
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
|
||||||
|
|
||||||
assertThat(instances).hasSize(3);
|
assertThat(instances).hasSize(3);
|
||||||
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId,
|
assertThat(instances.get(0)).isEqualTo(new DefaultServiceInstance(serviceId, "0.billing.apps.internal", 8080,
|
||||||
"0.billing.apps.internal", 8080, false, new HashMap<String, String>() {
|
false, new HashMap<String, String>() {
|
||||||
{
|
{
|
||||||
put("applicationId", "billing-id");
|
put("applicationId", "billing-id");
|
||||||
put("instanceId", "0");
|
put("instanceId", "0");
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
assertThat(instances.get(1)).isEqualTo(new DefaultServiceInstance(serviceId,
|
assertThat(instances.get(1)).isEqualTo(new DefaultServiceInstance(serviceId, "1.billing.apps.internal", 8080,
|
||||||
"1.billing.apps.internal", 8080, false, new HashMap<String, String>() {
|
false, new HashMap<String, String>() {
|
||||||
{
|
{
|
||||||
put("applicationId", "billing-id");
|
put("applicationId", "billing-id");
|
||||||
put("instanceId", "1");
|
put("instanceId", "1");
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
assertThat(instances.get(2)).isEqualTo(new DefaultServiceInstance(serviceId,
|
assertThat(instances.get(2)).isEqualTo(new DefaultServiceInstance(serviceId, "2.billing.apps.internal", 8080,
|
||||||
"2.billing.apps.internal", 8080, false, new HashMap<String, String>() {
|
false, new HashMap<String, String>() {
|
||||||
{
|
{
|
||||||
put("applicationId", "billing-id");
|
put("applicationId", "billing-id");
|
||||||
put("instanceId", "2");
|
put("instanceId", "2");
|
||||||
@@ -121,13 +113,11 @@ public class CloudFoundryAppServiceDiscoveryClientTest {
|
|||||||
@Test
|
@Test
|
||||||
public void getInstancesEmpty() {
|
public void getInstancesEmpty() {
|
||||||
String serviceId = "billing";
|
String serviceId = "billing";
|
||||||
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1")
|
ApplicationDetail applicationDetail = ApplicationDetail.builder().id("billing1").name("billing").instances(1)
|
||||||
.name("billing").instances(1).memoryLimit(1024).stack("cflinux2")
|
.memoryLimit(1024).stack("cflinux2").diskQuota(1024).requestedState("Running").runningInstances(1)
|
||||||
.diskQuota(1024).requestedState("Running").runningInstances(1)
|
|
||||||
.url("billing.apps.example.com").build();
|
.url("billing.apps.example.com").build();
|
||||||
given(this.cloudFoundryService.getApplicationInstances(serviceId))
|
given(this.cloudFoundryService.getApplicationInstances(serviceId))
|
||||||
.willReturn(Flux.just(Tuples.of(applicationDetail,
|
.willReturn(Flux.just(Tuples.of(applicationDetail, InstanceDetail.builder().index("0").build())));
|
||||||
InstanceDetail.builder().index("0").build())));
|
|
||||||
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
|
List<ServiceInstance> instances = this.discoveryClient.getInstances(serviceId);
|
||||||
|
|
||||||
assertThat(instances).isEmpty();
|
assertThat(instances).isEmpty();
|
||||||
|
|||||||
@@ -37,41 +37,31 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
public class CloudFoundryDiscoveryClientConfigurationTest {
|
public class CloudFoundryDiscoveryClientConfigurationTest {
|
||||||
|
|
||||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations
|
.withConfiguration(AutoConfigurations.of(CloudFoundryDiscoveryClientConfiguration.class));
|
||||||
.of(CloudFoundryDiscoveryClientConfiguration.class));
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefault() {
|
public void testDefault() {
|
||||||
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
|
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class).run((context) -> {
|
||||||
.run((context) -> {
|
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
|
||||||
DiscoveryClient discoveryClient = context
|
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryDiscoveryClient.class);
|
||||||
.getBean(DiscoveryClient.class);
|
});
|
||||||
assertThat(discoveryClient.getClass())
|
|
||||||
.isEqualTo(CloudFoundryDiscoveryClient.class);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUseDnsTrue() {
|
public void testUseDnsTrue() {
|
||||||
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
|
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
|
||||||
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true")
|
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true").run((context) -> {
|
||||||
.run((context) -> {
|
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
|
||||||
DiscoveryClient discoveryClient = context
|
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
|
||||||
.getBean(DiscoveryClient.class);
|
|
||||||
assertThat(discoveryClient.getClass())
|
|
||||||
.isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUseDnsFalse() {
|
public void testUseDnsFalse() {
|
||||||
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
|
this.contextRunner.withUserConfiguration(CloudFoundryConfig.class)
|
||||||
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=false")
|
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=false").run((context) -> {
|
||||||
.run((context) -> {
|
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
|
||||||
DiscoveryClient discoveryClient = context
|
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryDiscoveryClient.class);
|
||||||
.getBean(DiscoveryClient.class);
|
|
||||||
assertThat(discoveryClient.getClass())
|
|
||||||
.isEqualTo(CloudFoundryDiscoveryClient.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,23 +71,17 @@ public class CloudFoundryDiscoveryClientConfigurationTest {
|
|||||||
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
||||||
"spring.cloud.cloudfoundry.discovery.use-container-ip=false")
|
"spring.cloud.cloudfoundry.discovery.use-container-ip=false")
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
DiscoveryClient discoveryClient = context
|
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
|
||||||
.getBean(DiscoveryClient.class);
|
assertThat(discoveryClient.getClass()).isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
|
||||||
assertThat(discoveryClient.getClass())
|
|
||||||
.isEqualTo(CloudFoundryAppServiceDiscoveryClient.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUseContainerIpTrue() {
|
public void testUseContainerIpTrue() {
|
||||||
this.contextRunner
|
this.contextRunner.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
||||||
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
"spring.cloud.cloudfoundry.discovery.use-container-ip=true").run((context) -> {
|
||||||
"spring.cloud.cloudfoundry.discovery.use-container-ip=true")
|
DiscoveryClient discoveryClient = context.getBean(DiscoveryClient.class);
|
||||||
.run((context) -> {
|
assertThat(discoveryClient.getClass()).isEqualTo(SimpleDnsBasedDiscoveryClient.class);
|
||||||
DiscoveryClient discoveryClient = context
|
|
||||||
.getBean(DiscoveryClient.class);
|
|
||||||
assertThat(discoveryClient.getClass())
|
|
||||||
.isEqualTo(SimpleDnsBasedDiscoveryClient.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,42 +58,35 @@ public class CloudFoundryDiscoveryClientTest {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
this.ops = mock(CloudFoundryOperations.class);
|
this.ops = mock(CloudFoundryOperations.class);
|
||||||
this.svc = mock(CloudFoundryService.class);
|
this.svc = mock(CloudFoundryService.class);
|
||||||
this.cloudFoundryDiscoveryClient = new CloudFoundryDiscoveryClient(this.ops,
|
this.cloudFoundryDiscoveryClient = new CloudFoundryDiscoveryClient(this.ops, this.svc,
|
||||||
this.svc, new CloudFoundryDiscoveryProperties());
|
new CloudFoundryDiscoveryProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testServiceResolution() {
|
public void testServiceResolution() {
|
||||||
Applications apps = mock(Applications.class);
|
Applications apps = mock(Applications.class);
|
||||||
ApplicationSummary s = ApplicationSummary.builder()
|
ApplicationSummary s = ApplicationSummary.builder().id(UUID.randomUUID().toString()).instances(2)
|
||||||
.id(UUID.randomUUID().toString()).instances(2).memoryLimit(1024)
|
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name(this.hiServiceServiceId)
|
||||||
.requestedState("requestedState").diskQuota(1024)
|
.runningInstances(2).build();
|
||||||
.name(this.hiServiceServiceId).runningInstances(2).build();
|
|
||||||
Mockito.when(apps.list()).thenReturn(Flux.just(s));
|
Mockito.when(apps.list()).thenReturn(Flux.just(s));
|
||||||
Mockito.when(this.ops.applications()).thenReturn(apps);
|
Mockito.when(this.ops.applications()).thenReturn(apps);
|
||||||
List<String> serviceNames = this.cloudFoundryDiscoveryClient.getServices();
|
List<String> serviceNames = this.cloudFoundryDiscoveryClient.getServices();
|
||||||
assertThat(serviceNames.contains(this.hiServiceServiceId))
|
assertThat(serviceNames.contains(this.hiServiceServiceId)).as("there should be one registered service.")
|
||||||
.as("there should be one registered service.").isTrue();
|
.isTrue();
|
||||||
serviceNames.forEach(serviceName -> this.log
|
serviceNames.forEach(serviceName -> this.log.debug("\t discovered serviceName: " + serviceName));
|
||||||
.debug("\t discovered serviceName: " + serviceName));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInstances() {
|
public void testInstances() {
|
||||||
ApplicationDetail applicationDetail = ApplicationDetail.builder().instances(2)
|
ApplicationDetail applicationDetail = ApplicationDetail.builder().instances(2).name("my-app").stack("stack")
|
||||||
.name("my-app").stack("stack").memoryLimit(1024).id("id")
|
.memoryLimit(1024).id("id").requestedState("requestedState").runningInstances(2)
|
||||||
.requestedState("requestedState").runningInstances(2)
|
|
||||||
.url("http://my-app-cfapps-io").diskQuota(20).build();
|
.url("http://my-app-cfapps-io").diskQuota(20).build();
|
||||||
InstanceDetail instanceDetail = InstanceDetail.builder().index("0").build();
|
InstanceDetail instanceDetail = InstanceDetail.builder().index("0").build();
|
||||||
Tuple2<ApplicationDetail, InstanceDetail> tuple2 = Tuples.of(applicationDetail,
|
Tuple2<ApplicationDetail, InstanceDetail> tuple2 = Tuples.of(applicationDetail, instanceDetail);
|
||||||
instanceDetail);
|
Mockito.when(this.svc.getApplicationInstances(this.hiServiceServiceId)).thenReturn(Flux.just(tuple2));
|
||||||
Mockito.when(this.svc.getApplicationInstances(this.hiServiceServiceId))
|
List<ServiceInstance> instances = this.cloudFoundryDiscoveryClient.getInstances(this.hiServiceServiceId);
|
||||||
.thenReturn(Flux.just(tuple2));
|
|
||||||
List<ServiceInstance> instances = this.cloudFoundryDiscoveryClient
|
|
||||||
.getInstances(this.hiServiceServiceId);
|
|
||||||
assertThat(instances.size()).as("Wrong instances: " + instances).isEqualTo(1);
|
assertThat(instances.size()).as("Wrong instances: " + instances).isEqualTo(1);
|
||||||
assertThat(instances.get(0).getInstanceId()).as("Wrong instance ID")
|
assertThat(instances.get(0).getInstanceId()).as("Wrong instance ID").isEqualTo("id.0");
|
||||||
.isEqualTo("id.0");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,22 +49,17 @@ class CloudFoundryAppServiceReactiveDiscoveryClientTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnFluxOfServiceInstances() {
|
public void shouldReturnFluxOfServiceInstances() {
|
||||||
ApplicationDetail appDetail1 = ApplicationDetail.builder()
|
ApplicationDetail appDetail1 = ApplicationDetail.builder().id(UUID.randomUUID().toString()).stack("stack")
|
||||||
.id(UUID.randomUUID().toString()).stack("stack").instances(1)
|
.instances(1).memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name("service")
|
||||||
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
|
.runningInstances(1).url("instance.apps.internal").build();
|
||||||
.name("service").runningInstances(1).url("instance.apps.internal")
|
|
||||||
.build();
|
|
||||||
Tuple2<ApplicationDetail, InstanceDetail> instance1 = Tuples.of(appDetail1,
|
Tuple2<ApplicationDetail, InstanceDetail> instance1 = Tuples.of(appDetail1,
|
||||||
InstanceDetail.builder().index("0").build());
|
InstanceDetail.builder().index("0").build());
|
||||||
ApplicationDetail appDetail2 = ApplicationDetail.builder()
|
ApplicationDetail appDetail2 = ApplicationDetail.builder().id(UUID.randomUUID().toString()).stack("stack")
|
||||||
.id(UUID.randomUUID().toString()).stack("stack").instances(1)
|
.instances(1).memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name("service")
|
||||||
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
|
.runningInstances(1).url("instance.apps.not.internal").build();
|
||||||
.name("service").runningInstances(1).url("instance.apps.not.internal")
|
|
||||||
.build();
|
|
||||||
Tuple2<ApplicationDetail, InstanceDetail> instance2 = Tuples.of(appDetail2,
|
Tuple2<ApplicationDetail, InstanceDetail> instance2 = Tuples.of(appDetail2,
|
||||||
InstanceDetail.builder().index("0").build());
|
InstanceDetail.builder().index("0").build());
|
||||||
when(this.svc.getApplicationInstances("service"))
|
when(this.svc.getApplicationInstances("service")).thenReturn(Flux.just(instance1, instance2));
|
||||||
.thenReturn(Flux.just(instance1, instance2));
|
|
||||||
Flux<ServiceInstance> instances = this.client.getInstances("service");
|
Flux<ServiceInstance> instances = this.client.getInstances("service");
|
||||||
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();
|
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,7 @@ class CloudFoundryNativeReactiveDiscoveryClientTests {
|
|||||||
@Test
|
@Test
|
||||||
public void verifyDefaults() {
|
public void verifyDefaults() {
|
||||||
when(properties.getOrder()).thenReturn(0);
|
when(properties.getOrder()).thenReturn(0);
|
||||||
assertThat(client.description())
|
assertThat(client.description()).isEqualTo("CF Reactive Service Discovery Client");
|
||||||
.isEqualTo("CF Reactive Service Discovery Client");
|
|
||||||
assertThat(client.getOrder()).isEqualTo(0);
|
assertThat(client.getOrder()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,10 +70,9 @@ class CloudFoundryNativeReactiveDiscoveryClientTests {
|
|||||||
public void shouldReturnFluxOfServices() {
|
public void shouldReturnFluxOfServices() {
|
||||||
Applications apps = mock(Applications.class);
|
Applications apps = mock(Applications.class);
|
||||||
when(operations.applications()).thenReturn(apps);
|
when(operations.applications()).thenReturn(apps);
|
||||||
ApplicationSummary summary = ApplicationSummary.builder()
|
ApplicationSummary summary = ApplicationSummary.builder().id(UUID.randomUUID().toString()).instances(1)
|
||||||
.id(UUID.randomUUID().toString()).instances(1).memoryLimit(1024)
|
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024).name("service").runningInstances(1)
|
||||||
.requestedState("requestedState").diskQuota(1024).name("service")
|
.build();
|
||||||
.runningInstances(1).build();
|
|
||||||
when(apps.list()).thenReturn(Flux.just(summary));
|
when(apps.list()).thenReturn(Flux.just(summary));
|
||||||
Flux<String> services = this.client.getServices();
|
Flux<String> services = this.client.getServices();
|
||||||
StepVerifier.create(services).expectNext("service").expectComplete().verify();
|
StepVerifier.create(services).expectNext("service").expectComplete().verify();
|
||||||
@@ -89,13 +87,11 @@ class CloudFoundryNativeReactiveDiscoveryClientTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnFluxOfServiceInstances() {
|
public void shouldReturnFluxOfServiceInstances() {
|
||||||
ApplicationDetail applicationDetail = ApplicationDetail.builder()
|
ApplicationDetail applicationDetail = ApplicationDetail.builder().id(UUID.randomUUID().toString())
|
||||||
.id(UUID.randomUUID().toString()).stack("stack").instances(1)
|
.stack("stack").instances(1).memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
|
||||||
.memoryLimit(1024).requestedState("requestedState").diskQuota(1024)
|
|
||||||
.name("service").runningInstances(1).build();
|
.name("service").runningInstances(1).build();
|
||||||
InstanceDetail instanceDetail = InstanceDetail.builder().index("0").build();
|
InstanceDetail instanceDetail = InstanceDetail.builder().index("0").build();
|
||||||
Tuple2<ApplicationDetail, InstanceDetail> instance = Tuples.of(applicationDetail,
|
Tuple2<ApplicationDetail, InstanceDetail> instance = Tuples.of(applicationDetail, instanceDetail);
|
||||||
instanceDetail);
|
|
||||||
when(this.svc.getApplicationInstances("service")).thenReturn(Flux.just(instance));
|
when(this.svc.getApplicationInstances("service")).thenReturn(Flux.just(instance));
|
||||||
Flux<ServiceInstance> instances = this.client.getInstances("service");
|
Flux<ServiceInstance> instances = this.client.getInstances("service");
|
||||||
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();
|
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();
|
||||||
|
|||||||
@@ -39,138 +39,100 @@ import static org.mockito.Mockito.mock;
|
|||||||
*/
|
*/
|
||||||
class CloudFoundryReactiveDiscoveryClientConfigurationTests {
|
class CloudFoundryReactiveDiscoveryClientConfigurationTests {
|
||||||
|
|
||||||
private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations
|
||||||
.withConfiguration(
|
.of(MockedCloudFoundryConfiguration.class, CloudFoundryReactiveDiscoveryClientConfiguration.class));
|
||||||
AutoConfigurations.of(MockedCloudFoundryConfiguration.class,
|
|
||||||
CloudFoundryReactiveDiscoveryClientConfiguration.class));
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotHaveDiscoveryClientsWhenDiscoveryDisabled() {
|
public void shouldNotHaveDiscoveryClientsWhenDiscoveryDisabled() {
|
||||||
contextRunner.withPropertyValues("spring.cloud.discovery.enabled=false")
|
contextRunner.withPropertyValues("spring.cloud.discovery.enabled=false").run(context -> {
|
||||||
.run(context -> {
|
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
|
||||||
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
||||||
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
assertThat(context).doesNotHaveBean(
|
});
|
||||||
ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotHaveDiscoveryClientsWhenReactiveDiscoveryDisabled() {
|
public void shouldNotHaveDiscoveryClientsWhenReactiveDiscoveryDisabled() {
|
||||||
contextRunner.withPropertyValues("spring.cloud.discovery.reactive.enabled=false")
|
contextRunner.withPropertyValues("spring.cloud.discovery.reactive.enabled=false").run(context -> {
|
||||||
.run(context -> {
|
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
|
||||||
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
||||||
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
assertThat(context).doesNotHaveBean(
|
});
|
||||||
ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldNotHaveDiscoveryClientsWhenCloudFoundryDiscoveryDisabled() {
|
public void shouldNotHaveDiscoveryClientsWhenCloudFoundryDiscoveryDisabled() {
|
||||||
contextRunner
|
contextRunner.withPropertyValues("spring.cloud.cloudfoundry.discovery.enabled=false").run(context -> {
|
||||||
.withPropertyValues("spring.cloud.cloudfoundry.discovery.enabled=false")
|
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
|
||||||
.run(context -> {
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
||||||
assertThat(context).doesNotHaveBean("cloudFoundryHeartbeatSender");
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
});
|
||||||
assertThat(context).doesNotHaveBean(
|
|
||||||
ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldUseNativeDiscovery() {
|
public void shouldUseNativeDiscovery() {
|
||||||
contextRunner
|
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
|
||||||
.withConfiguration(AutoConfigurations
|
|
||||||
.of(ReactiveCommonsClientAutoConfiguration.class))
|
|
||||||
.run(context -> {
|
.run(context -> {
|
||||||
assertThat(context)
|
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
||||||
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
|
||||||
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
||||||
assertThat(context).hasBean("nativeCloudFoundryDiscoveryClient");
|
assertThat(context).hasBean("nativeCloudFoundryDiscoveryClient");
|
||||||
assertThat(context)
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldUseDnsDiscovery() {
|
public void shouldUseDnsDiscovery() {
|
||||||
contextRunner
|
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
|
||||||
.withConfiguration(AutoConfigurations
|
|
||||||
.of(ReactiveCommonsClientAutoConfiguration.class))
|
|
||||||
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
||||||
"spring.cloud.cloudfoundry.discovery.use-container-ip=true")
|
"spring.cloud.cloudfoundry.discovery.use-container-ip=true")
|
||||||
.run(context -> {
|
.run(context -> {
|
||||||
assertThat(context)
|
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
||||||
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
|
||||||
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
||||||
assertThat(context).hasBean("dnsBasedReactiveDiscoveryClient");
|
assertThat(context).hasBean("dnsBasedReactiveDiscoveryClient");
|
||||||
assertThat(context)
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldUseAppServiceDiscovery() {
|
public void shouldUseAppServiceDiscovery() {
|
||||||
contextRunner
|
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
|
||||||
.withConfiguration(AutoConfigurations
|
|
||||||
.of(ReactiveCommonsClientAutoConfiguration.class))
|
|
||||||
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
.withPropertyValues("spring.cloud.cloudfoundry.discovery.use-dns=true",
|
||||||
"spring.cloud.cloudfoundry.discovery.use-container-ip=false")
|
"spring.cloud.cloudfoundry.discovery.use-container-ip=false")
|
||||||
.run(context -> {
|
.run(context -> {
|
||||||
assertThat(context)
|
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
||||||
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
|
||||||
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
||||||
assertThat(context).hasBean("appServiceReactiveDiscoveryClient");
|
assertThat(context).hasBean("appServiceReactiveDiscoveryClient");
|
||||||
assertThat(context)
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldUseCustomServiceDiscovery() {
|
public void shouldUseCustomServiceDiscovery() {
|
||||||
contextRunner
|
contextRunner.withConfiguration(AutoConfigurations.of(ReactiveCommonsClientAutoConfiguration.class))
|
||||||
.withConfiguration(AutoConfigurations
|
.withUserConfiguration(CustomCloudFoundryReactiveDiscoveryClientConfiguration.class).run(context -> {
|
||||||
.of(ReactiveCommonsClientAutoConfiguration.class))
|
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
||||||
.withUserConfiguration(
|
assertThat(context).getBeans(ReactiveDiscoveryClient.class).hasSize(2);
|
||||||
CustomCloudFoundryReactiveDiscoveryClientConfiguration.class)
|
|
||||||
.run(context -> {
|
|
||||||
assertThat(context)
|
|
||||||
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
|
||||||
assertThat(context).getBeans(ReactiveDiscoveryClient.class)
|
|
||||||
.hasSize(2);
|
|
||||||
assertThat(context).hasBean("nativeCloudFoundryDiscoveryClient");
|
assertThat(context).hasBean("nativeCloudFoundryDiscoveryClient");
|
||||||
assertThat(context)
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
.hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void worksWithoutWebflux() {
|
public void worksWithoutWebflux() {
|
||||||
contextRunner
|
contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.web.reactive")).run(context -> {
|
||||||
.withClassLoader(
|
assertThat(context).doesNotHaveBean(CloudFoundryReactiveHeartbeatSender.class);
|
||||||
new FilteredClassLoader("org.springframework.web.reactive"))
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
||||||
.run(context -> {
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
assertThat(context)
|
});
|
||||||
.doesNotHaveBean(CloudFoundryReactiveHeartbeatSender.class);
|
|
||||||
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClient.class);
|
|
||||||
assertThat(context).doesNotHaveBean(
|
|
||||||
ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void worksWithoutActuator() {
|
public void worksWithoutActuator() {
|
||||||
contextRunner
|
contextRunner.withClassLoader(new FilteredClassLoader("org.springframework.boot.actuate")).run(context -> {
|
||||||
.withClassLoader(
|
assertThat(context).hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
||||||
new FilteredClassLoader("org.springframework.boot.actuate"))
|
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
||||||
.run(context -> {
|
assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class);
|
||||||
assertThat(context)
|
});
|
||||||
.hasSingleBean(CloudFoundryReactiveHeartbeatSender.class);
|
|
||||||
assertThat(context).hasSingleBean(ReactiveDiscoveryClient.class);
|
|
||||||
assertThat(context).doesNotHaveBean(
|
|
||||||
ReactiveDiscoveryClientHealthIndicator.class);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestConfiguration
|
@TestConfiguration
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ public class CloudFoundryApplication {
|
|||||||
Log log = LogFactory.getLog(getClass());
|
Log log = LogFactory.getLog(getClass());
|
||||||
return args -> discoveryClient.getServices().forEach(svc -> {
|
return args -> discoveryClient.getServices().forEach(svc -> {
|
||||||
log.info("service = " + svc);
|
log.info("service = " + svc);
|
||||||
discoveryClient.getInstances(svc)
|
discoveryClient.getInstances(svc).forEach(si -> log.info("\tinstance = " + si));
|
||||||
.forEach(si -> log.info("\tinstance = " + si));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,9 @@ import org.springframework.util.StringUtils;
|
|||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class VcapServiceCredentialsEnvironmentPostProcessor
|
public class VcapServiceCredentialsEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
|
||||||
implements EnvironmentPostProcessor, Ordered {
|
|
||||||
|
|
||||||
static final Bindable<Map<String, Object>> STRING_OBJECT_MAP = Bindable
|
static final Bindable<Map<String, Object>> STRING_OBJECT_MAP = Bindable.mapOf(String.class, Object.class);
|
||||||
.mapOf(String.class, Object.class);
|
|
||||||
|
|
||||||
// After VcapEnvironmentPostProcessor and ConfigFileEnvironmentPostProcessor so
|
// After VcapEnvironmentPostProcessor and ConfigFileEnvironmentPostProcessor so
|
||||||
// values here can
|
// values here can
|
||||||
@@ -52,63 +50,52 @@ public class VcapServiceCredentialsEnvironmentPostProcessor
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postProcessEnvironment(ConfigurableEnvironment environment,
|
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||||
SpringApplication application) {
|
Binder.get(environment).bind("vcap.services", STRING_OBJECT_MAP).orElseGet(Collections::emptyMap);
|
||||||
Binder.get(environment).bind("vcap.services", STRING_OBJECT_MAP)
|
|
||||||
.orElseGet(Collections::emptyMap);
|
|
||||||
if (!hasChildProperties(environment, "vcap.services")) {
|
if (!hasChildProperties(environment, "vcap.services")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Map<String, Object> source = new HashMap<>();
|
Map<String, Object> source = new HashMap<>();
|
||||||
String serviceId;
|
String serviceId;
|
||||||
if (hasChildProperties(environment, "security.oauth2.resource")) {
|
if (hasChildProperties(environment, "security.oauth2.resource")) {
|
||||||
serviceId = environment.getProperty("security.oauth2.resource.service-id",
|
serviceId = environment.getProperty("security.oauth2.resource.service-id", "resource");
|
||||||
"resource");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serviceId = environment.getProperty("security.oauth2.sso.service-id", "sso");
|
serviceId = environment.getProperty("security.oauth2.sso.service-id", "sso");
|
||||||
}
|
}
|
||||||
String authDomain = environment
|
String authDomain = environment.getProperty("vcap.services." + serviceId + ".credentials.auth-domain");
|
||||||
.getProperty("vcap.services." + serviceId + ".credentials.auth-domain");
|
|
||||||
if (authDomain != null) {
|
if (authDomain != null) {
|
||||||
source.put("security.oauth2.resource.user-info-uri",
|
source.put("security.oauth2.resource.user-info-uri", authDomain + "/userinfo");
|
||||||
authDomain + "/userinfo");
|
|
||||||
source.put("security.oauth2.resource.jwt.key-uri", authDomain + "/token_key");
|
source.put("security.oauth2.resource.jwt.key-uri", authDomain + "/token_key");
|
||||||
source.put("security.oauth2.client.access-token-uri",
|
source.put("security.oauth2.client.access-token-uri", authDomain + "/oauth/token");
|
||||||
authDomain + "/oauth/token");
|
source.put("security.oauth2.client.user-authorization-uri", authDomain + "/oauth/authorize");
|
||||||
source.put("security.oauth2.client.user-authorization-uri",
|
|
||||||
authDomain + "/oauth/authorize");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
addProperty(source, environment, serviceId, "resource", "user-info-uri");
|
addProperty(source, environment, serviceId, "resource", "user-info-uri");
|
||||||
addProperty(source, environment, serviceId, "resource", "token-info-uri");
|
addProperty(source, environment, serviceId, "resource", "token-info-uri");
|
||||||
addProperty(source, environment, serviceId, "resource.jwt", "key-uri");
|
addProperty(source, environment, serviceId, "resource.jwt", "key-uri");
|
||||||
addProperty(source, environment, serviceId, "resource", "key-value");
|
addProperty(source, environment, serviceId, "resource", "key-value");
|
||||||
addProperty(source, environment, serviceId, "client", "access-token-uri",
|
addProperty(source, environment, serviceId, "client", "access-token-uri", "token-uri");
|
||||||
"token-uri");
|
addProperty(source, environment, serviceId, "client", "user-authorization-uri", "authorization-uri");
|
||||||
addProperty(source, environment, serviceId, "client",
|
|
||||||
"user-authorization-uri", "authorization-uri");
|
|
||||||
}
|
}
|
||||||
addProperty(source, environment, serviceId, "client", "client-id");
|
addProperty(source, environment, serviceId, "client", "client-id");
|
||||||
addProperty(source, environment, serviceId, "client", "client-secret");
|
addProperty(source, environment, serviceId, "client", "client-secret");
|
||||||
addProperty(source, environment, serviceId, "client", "scope");
|
addProperty(source, environment, serviceId, "client", "scope");
|
||||||
String resourceId = environment
|
String resourceId = environment.getProperty("vcap.services." + serviceId + ".credentials.id", "");
|
||||||
.getProperty("vcap.services." + serviceId + ".credentials.id", "");
|
|
||||||
if (StringUtils.hasText(resourceId)) {
|
if (StringUtils.hasText(resourceId)) {
|
||||||
source.put("security.oauth2.resource.id", resourceId);
|
source.put("security.oauth2.resource.id", resourceId);
|
||||||
}
|
}
|
||||||
environment.getPropertySources()
|
environment.getPropertySources().addLast(new MapPropertySource("cloudDefaultSecurityBindings", source));
|
||||||
.addLast(new MapPropertySource("cloudDefaultSecurityBindings", source));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasChildProperties(ConfigurableEnvironment environment, String name) {
|
private boolean hasChildProperties(ConfigurableEnvironment environment, String name) {
|
||||||
Map<String, Object> properties = Binder.get(environment)
|
Map<String, Object> properties = Binder.get(environment).bind(name, STRING_OBJECT_MAP)
|
||||||
.bind(name, STRING_OBJECT_MAP).orElseGet(Collections::emptyMap);
|
.orElseGet(Collections::emptyMap);
|
||||||
return !properties.isEmpty();
|
return !properties.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addProperty(Map<String, Object> source, PropertyResolver resolver,
|
private void addProperty(Map<String, Object> source, PropertyResolver resolver, String serviceId, String stem,
|
||||||
String serviceId, String stem, String key, String... altKeys) {
|
String key, String... altKeys) {
|
||||||
String value = resolve(resolver, serviceId, key);
|
String value = resolve(resolver, serviceId, key);
|
||||||
if (StringUtils.hasText(value)) {
|
if (StringUtils.hasText(value)) {
|
||||||
source.put("security.oauth2." + stem + "." + key, value);
|
source.put("security.oauth2." + stem + "." + key, value);
|
||||||
@@ -124,8 +111,7 @@ public class VcapServiceCredentialsEnvironmentPostProcessor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String resolve(PropertyResolver resolver, String serviceId, String key) {
|
private String resolve(PropertyResolver resolver, String serviceId, String key) {
|
||||||
return resolver.getProperty(
|
return resolver.getProperty(String.format("vcap.services.%s.credentials.%s", serviceId, key), "");
|
||||||
String.format("vcap.services.%s.credentials.%s", serviceId, key), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,12 +49,10 @@ public class StickyFilterConfiguration {
|
|||||||
filter.setOrder(Ordered.LOWEST_PRECEDENCE);
|
filter.setOrder(Ordered.LOWEST_PRECEDENCE);
|
||||||
filter.setFilter(new OncePerRequestFilter() {
|
filter.setFilter(new OncePerRequestFilter() {
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request,
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||||
HttpServletResponse response, FilterChain filterChain)
|
FilterChain filterChain) throws ServletException, IOException {
|
||||||
throws ServletException, IOException {
|
|
||||||
if (!response.containsHeader("Set-Cookie")) {
|
if (!response.containsHeader("Set-Cookie")) {
|
||||||
response.addCookie(new Cookie("JSESSIONID",
|
response.addCookie(new Cookie("JSESSIONID", StickyFilterConfiguration.this.cookie));
|
||||||
StickyFilterConfiguration.this.cookie));
|
|
||||||
}
|
}
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,85 +43,67 @@ public class VcapServiceCredentialsEnvironmentPostProcessorTests {
|
|||||||
@Test
|
@Test
|
||||||
public void noop() {
|
public void noop() {
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
Map<String, Object> properties = Binder.get(this.environment)
|
Map<String, Object> properties = Binder.get(this.environment).bind("security.oauth2", STRING_OBJECT_MAP)
|
||||||
.bind("security.oauth2", STRING_OBJECT_MAP)
|
|
||||||
.orElseGet(Collections::emptyMap);
|
.orElseGet(Collections::emptyMap);
|
||||||
assertThat(properties.isEmpty()).isTrue();
|
assertThat(properties.isEmpty()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addClientId() {
|
public void addClientId() {
|
||||||
TestPropertyValues.of("vcap.services.sso.credentials.clientId:foo")
|
TestPropertyValues.of("vcap.services.sso.credentials.clientId:foo").applyTo(this.environment);
|
||||||
.applyTo(this.environment);
|
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
assertThat(this.environment
|
assertThat(this.environment.resolvePlaceholders("${security.oauth2.client.client-id}")).isEqualTo("foo");
|
||||||
.resolvePlaceholders("${security.oauth2.client.client-id}"))
|
|
||||||
.isEqualTo("foo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addClientIdUnderscores() {
|
public void addClientIdUnderscores() {
|
||||||
TestPropertyValues.of("vcap.services.sso.credentials.client-id:foo")
|
TestPropertyValues.of("vcap.services.sso.credentials.client-id:foo").applyTo(this.environment);
|
||||||
.applyTo(this.environment);
|
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
assertThat(this.environment
|
assertThat(this.environment.resolvePlaceholders("${security.oauth2.client.client-id}")).isEqualTo("foo");
|
||||||
.resolvePlaceholders("${security.oauth2.client.client-id}"))
|
|
||||||
.isEqualTo("foo");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addTokenUri() {
|
public void addTokenUri() {
|
||||||
TestPropertyValues
|
TestPropertyValues.of("vcap.services.sso.credentials.accessTokenUri:http://exampledomain")
|
||||||
.of("vcap.services.sso.credentials.accessTokenUri:http://exampledomain")
|
|
||||||
.applyTo(this.environment);
|
.applyTo(this.environment);
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
assertThat(this.environment
|
assertThat(this.environment.resolvePlaceholders("${security.oauth2.client.access-token-uri}"))
|
||||||
.resolvePlaceholders("${security.oauth2.client.access-token-uri}"))
|
.isEqualTo("http://exampledomain");
|
||||||
.isEqualTo("http://exampledomain");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addTokenUriAuthDomain() {
|
public void addTokenUriAuthDomain() {
|
||||||
TestPropertyValues
|
TestPropertyValues.of("vcap.services.sso.credentials.auth-domain:http://exampledomain")
|
||||||
.of("vcap.services.sso.credentials.auth-domain:http://exampledomain")
|
|
||||||
.applyTo(this.environment);
|
.applyTo(this.environment);
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
assertThat(this.environment
|
assertThat(this.environment.resolvePlaceholders("${security.oauth2.client.access-token-uri}"))
|
||||||
.resolvePlaceholders("${security.oauth2.client.access-token-uri}"))
|
.isEqualTo("http://exampledomain/oauth/token");
|
||||||
.isEqualTo("http://exampledomain/oauth/token");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addUserInfoUri() {
|
public void addUserInfoUri() {
|
||||||
TestPropertyValues
|
TestPropertyValues.of("vcap.services.sso.credentials.userInfoUri:http://exampledomain")
|
||||||
.of("vcap.services.sso.credentials.userInfoUri:http://exampledomain")
|
|
||||||
.applyTo(this.environment);
|
.applyTo(this.environment);
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
assertThat(this.environment
|
assertThat(this.environment.resolvePlaceholders("${security.oauth2.resource.user-info-uri}"))
|
||||||
.resolvePlaceholders("${security.oauth2.resource.user-info-uri}"))
|
.isEqualTo("http://exampledomain");
|
||||||
.isEqualTo("http://exampledomain");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addServiceId() {
|
public void addServiceId() {
|
||||||
TestPropertyValues
|
TestPropertyValues.of("vcap.services.my.credentials.accessTokenUri:http://exampledomain",
|
||||||
.of("vcap.services.my.credentials.accessTokenUri:http://exampledomain",
|
"security.oauth2.sso.serviceId:my").applyTo(this.environment);
|
||||||
"security.oauth2.sso.serviceId:my")
|
|
||||||
.applyTo(this.environment);
|
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
assertThat(this.environment
|
assertThat(this.environment.resolvePlaceholders("${security.oauth2.client.access-token-uri}"))
|
||||||
.resolvePlaceholders("${security.oauth2.client.access-token-uri}"))
|
.isEqualTo("http://exampledomain");
|
||||||
.isEqualTo("http://exampledomain");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addJwtKeyUri() {
|
public void addJwtKeyUri() {
|
||||||
TestPropertyValues.of("vcap.services.sso.credentials.keyUri:http://exampledomain")
|
TestPropertyValues.of("vcap.services.sso.credentials.keyUri:http://exampledomain").applyTo(this.environment);
|
||||||
.applyTo(this.environment);
|
|
||||||
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
this.listener.postProcessEnvironment(this.environment, new SpringApplication());
|
||||||
assertThat(this.environment
|
assertThat(this.environment.resolvePlaceholders("${security.oauth2.resource.jwt.key-uri}"))
|
||||||
.resolvePlaceholders("${security.oauth2.resource.jwt.key-uri}"))
|
.isEqualTo("http://exampledomain");
|
||||||
.isEqualTo("http://exampledomain");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user