Tidy up failure cases of discovery client
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-cloudfoundry</artifactId>
|
||||
<version>1.0.2.BUILD-SNAPSHOT</version>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
|
||||
@@ -1,80 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-cloudfoundry-discovery</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>Spring Cloud CloudFoundry Discovery</description>
|
||||
<artifactId>spring-cloud-cloudfoundry-discovery</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>Spring Cloud CloudFoundry Discovery</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-cloudfoundry</artifactId>
|
||||
<version>1.0.2.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-cloudfoundry</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cloudfoundry</groupId>
|
||||
<artifactId>cloudfoundry-client-lib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
<artifactId>archaius-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!---->
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<scope>test</scope>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
</dependency>
|
||||
<!---->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.cloudfoundry</groupId>
|
||||
<artifactId>cloudfoundry-client-lib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<scope>test</scope>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -16,8 +16,15 @@
|
||||
|
||||
package org.springframework.cloud.cloudfoundry.discovery;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.cloudfoundry.client.lib.CloudCredentials;
|
||||
@@ -32,147 +39,162 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* A Cloud Foundry v2 API-aware implementation of the {@link DiscoveryClient discovery client}
|
||||
* SPI. Cloud Foundry already retains a registry of running applications which we expose here as services.
|
||||
* Newer versions of Cloud Foundry support instance-specific networking, but as the Cloud Foundry client API doesn't
|
||||
* yet support that, this {@link DiscoveryClient implementation doesn't either}.
|
||||
* A Cloud Foundry v2 API-aware implementation of the {@link DiscoveryClient discovery
|
||||
* client} SPI. Cloud Foundry already retains a registry of running applications which we
|
||||
* expose here as services. Newer versions of Cloud Foundry support instance-specific
|
||||
* networking, but as the Cloud Foundry client API doesn't yet support that, this
|
||||
* {@link DiscoveryClient implementation doesn't either}.
|
||||
* <p/>
|
||||
* You need to provide an instance of the {@link CloudFoundryClient}. A workable configuration looks like this:
|
||||
* You need to provide an instance of the {@link CloudFoundryClient}. A workable
|
||||
* configuration looks like this:
|
||||
* <p/>
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Bean
|
||||
* CloudFoundryClient cloudFoundryClient(
|
||||
* @Value("${MY_CUSTOM_CF_API:https://api.run.pivotal.io}") String api,
|
||||
* CloudCredentials cc) throws MalformedURLException {
|
||||
* CloudFoundryClient cloudFoundryClient = new CloudFoundryClient(cc, URI.create(api).toURL());
|
||||
* cloudFoundryClient.login();
|
||||
* return cloudFoundryClient;
|
||||
* @Value("${MY_CUSTOM_CF_API:https://api.run.pivotal.io}") String api,
|
||||
* CloudCredentials cc) throws MalformedURLException {
|
||||
* CloudFoundryClient cloudFoundryClient = new CloudFoundryClient(cc, URI.create(api)
|
||||
* .toURL());
|
||||
* cloudFoundryClient.login();
|
||||
* return cloudFoundryClient;
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* You can configure all sorts of other things including which Cloud Foundry cloud controller URI to use,
|
||||
* how and whether to use an HTTP proxy, and more using alternative constructors. As configured above, the client
|
||||
* will talk to all services and applications deployed in <EM>all</EM> spaces and organizations. Use one of the
|
||||
* {@link CloudFoundryClient#CloudFoundryClient(CloudCredentials, URL, String, String)} variants to specify which space
|
||||
* and organization to use.
|
||||
* You can configure all sorts of other things including which Cloud Foundry cloud
|
||||
* controller URI to use, how and whether to use an HTTP proxy, and more using alternative
|
||||
* constructors. As configured above, the client will talk to all services and
|
||||
* applications deployed in <EM>all</EM> spaces and organizations. Use one of the
|
||||
* {@link CloudFoundryClient#CloudFoundryClient(CloudCredentials, URL, String, String)}
|
||||
* variants to specify which space and organization to use.
|
||||
* <p/>
|
||||
*
|
||||
* @author <A href="mailto:josh@joshlong.com">Josh Long</A>
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class CloudFoundryDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
private static final String DESCRIPTION = "Cloud Foundry " + DiscoveryClient.class.getName() + " implementation";
|
||||
private static final String DESCRIPTION = "Cloud Foundry "
|
||||
+ DiscoveryClient.class.getName() + " implementation";
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
private static final Log log = LogFactory.getLog(CloudFoundryDiscoveryClient.class);
|
||||
|
||||
private final ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
|
||||
private final ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
|
||||
|
||||
private final CloudFoundryClient cloudFoundryClient;
|
||||
private final CloudFoundryClient cloudFoundryClient;
|
||||
|
||||
private final String vcapApplicationName;
|
||||
private final String vcapApplicationName;
|
||||
|
||||
public CloudFoundryDiscoveryClient(CloudFoundryClient cloudFoundryClient, Environment environment) {
|
||||
public CloudFoundryDiscoveryClient(CloudFoundryClient cloudFoundryClient,
|
||||
Environment environment) {
|
||||
|
||||
this.cloudFoundryClient = cloudFoundryClient;
|
||||
this.cloudFoundryClient = cloudFoundryClient;
|
||||
|
||||
String vcapApplication = environment.getProperty("VCAP_APPLICATION");
|
||||
String vcapApplication = environment.getProperty("VCAP_APPLICATION");
|
||||
|
||||
try {
|
||||
JsonNode jsonNode = objectMapper.readTree(vcapApplication);
|
||||
JsonNode appNameNode = jsonNode.get("application_name");
|
||||
try {
|
||||
JsonNode jsonNode = objectMapper.readTree(vcapApplication);
|
||||
JsonNode appNameNode = jsonNode.get("application_name");
|
||||
|
||||
this.vcapApplicationName = appNameNode.toString().replaceAll("\"", "");
|
||||
this.vcapApplicationName = appNameNode.toString().replaceAll("\"", "");
|
||||
|
||||
this.log.debug("Current ServiceInstance information...");
|
||||
this.log.debug("\tvcapApplicationName: " + this.vcapApplicationName);
|
||||
log.debug("Current ServiceInstance information...");
|
||||
log.debug("\tvcapApplicationName: " + this.vcapApplicationName);
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return DESCRIPTION;
|
||||
}
|
||||
@Override
|
||||
public String description() {
|
||||
return DESCRIPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance getLocalServiceInstance() {
|
||||
CloudApplication application = this.cloudFoundryClient.getApplication(this.vcapApplicationName);
|
||||
List<ServiceInstance> serviceInstances =
|
||||
this.createServiceInstancesFromCloudApplications(Collections.singletonList(application));
|
||||
return serviceInstances.size() > 0 ? serviceInstances.iterator().next() : null;
|
||||
}
|
||||
@Override
|
||||
public ServiceInstance getLocalServiceInstance() {
|
||||
List<ServiceInstance> serviceInstances = null;
|
||||
try {
|
||||
CloudApplication application = this.cloudFoundryClient
|
||||
.getApplication(this.vcapApplicationName);
|
||||
serviceInstances = this
|
||||
.createServiceInstancesFromCloudApplications(Collections
|
||||
.singletonList(application));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Could not determine local service instance: " + e.getClass() + " ("
|
||||
+ e.getMessage() + ")");
|
||||
}
|
||||
return serviceInstances != null && serviceInstances.size() > 0 ? serviceInstances
|
||||
.iterator().next() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String s) {
|
||||
CloudApplication applications = this.cloudFoundryClient.getApplication(s);
|
||||
return this.createServiceInstancesFromCloudApplications(
|
||||
Collections.singletonList(applications));
|
||||
}
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String s) {
|
||||
CloudApplication applications = this.cloudFoundryClient.getApplication(s);
|
||||
return this.createServiceInstancesFromCloudApplications(Collections
|
||||
.singletonList(applications));
|
||||
}
|
||||
|
||||
private boolean isRunning(CloudApplication ca) {
|
||||
InstancesInfo ii = this.cloudFoundryClient.getApplicationInstances(ca);
|
||||
List<InstanceInfo> instances;
|
||||
if (ii != null && (instances = ii.getInstances()) != null) {
|
||||
for (InstanceInfo resolved : instances) {
|
||||
InstanceState state = resolved.getState();
|
||||
if (state != null && state.equals(InstanceState.RUNNING)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private boolean isRunning(CloudApplication ca) {
|
||||
InstancesInfo ii = this.cloudFoundryClient.getApplicationInstances(ca);
|
||||
List<InstanceInfo> instances;
|
||||
if (ii != null && (instances = ii.getInstances()) != null) {
|
||||
for (InstanceInfo resolved : instances) {
|
||||
InstanceState state = resolved.getState();
|
||||
if (state != null && state.equals(InstanceState.RUNNING)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
List<String> services = new ArrayList<>();
|
||||
List<CloudApplication> applications = this.cloudFoundryClient.getApplications();
|
||||
Set<String> serviceIds = new HashSet<>();
|
||||
for (CloudApplication ca : applications) {
|
||||
if (isRunning(ca)) {
|
||||
serviceIds.add(ca.getName());
|
||||
}
|
||||
}
|
||||
services.addAll(serviceIds);
|
||||
return services;
|
||||
}
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
List<String> services = new ArrayList<>();
|
||||
List<CloudApplication> applications = this.cloudFoundryClient.getApplications();
|
||||
Set<String> serviceIds = new HashSet<>();
|
||||
for (CloudApplication ca : applications) {
|
||||
if (isRunning(ca)) {
|
||||
serviceIds.add(ca.getName());
|
||||
}
|
||||
}
|
||||
services.addAll(serviceIds);
|
||||
return services;
|
||||
}
|
||||
|
||||
protected List<ServiceInstance> createServiceInstancesFromCloudApplications(
|
||||
Collection<CloudApplication> cloudApplications) {
|
||||
Set<ServiceInstance> serviceInstances = new HashSet<>();
|
||||
for (CloudApplication ca : cloudApplications) {
|
||||
if (isRunning(ca)) {
|
||||
serviceInstances.add(new CloudFoundryServiceInstance(ca));
|
||||
}
|
||||
}
|
||||
List<ServiceInstance> instances = new ArrayList<>();
|
||||
instances.addAll(serviceInstances);
|
||||
return instances;
|
||||
}
|
||||
protected List<ServiceInstance> createServiceInstancesFromCloudApplications(
|
||||
Collection<CloudApplication> cloudApplications) {
|
||||
Set<ServiceInstance> serviceInstances = new HashSet<>();
|
||||
for (CloudApplication ca : cloudApplications) {
|
||||
if (isRunning(ca)) {
|
||||
serviceInstances.add(new CloudFoundryServiceInstance(ca));
|
||||
}
|
||||
}
|
||||
List<ServiceInstance> instances = new ArrayList<>();
|
||||
instances.addAll(serviceInstances);
|
||||
return instances;
|
||||
}
|
||||
|
||||
public static class CloudFoundryServiceInstance extends DefaultServiceInstance {
|
||||
public static class CloudFoundryServiceInstance extends DefaultServiceInstance {
|
||||
|
||||
private final CloudApplication cloudApplication;
|
||||
private final CloudApplication cloudApplication;
|
||||
|
||||
public CloudApplication getCloudApplication() {
|
||||
return cloudApplication;
|
||||
}
|
||||
public CloudApplication getCloudApplication() {
|
||||
return cloudApplication;
|
||||
}
|
||||
|
||||
public CloudFoundryServiceInstance(CloudApplication ca) {
|
||||
super(ca.getName(),
|
||||
ca.getUris().iterator().next(),
|
||||
80,
|
||||
false);
|
||||
public CloudFoundryServiceInstance(CloudApplication ca) {
|
||||
super(ca.getName(), ca.getUris().iterator().next(), 80, false);
|
||||
|
||||
this.cloudApplication = ca;
|
||||
}
|
||||
}
|
||||
this.cloudApplication = ca;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,53 +16,58 @@
|
||||
|
||||
package org.springframework.cloud.cloudfoundry.discovery;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.cloudfoundry.client.lib.CloudCredentials;
|
||||
import org.cloudfoundry.client.lib.CloudFoundryClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author <A href="mailto:josh@joshlong.com">Josh Long</A>
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(CloudFoundryClient.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.cloudfoundry.discovery.enabled", matchIfMissing = true)
|
||||
public class CloudFoundryDiscoveryClientConfiguration {
|
||||
|
||||
@Autowired
|
||||
private CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties;
|
||||
@Autowired
|
||||
private CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CloudCredentials.class)
|
||||
public CloudCredentials cloudCredentials() {
|
||||
return new CloudCredentials(this.cloudFoundryDiscoveryProperties.getEmail(),
|
||||
this.cloudFoundryDiscoveryProperties.getPassword());
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CloudCredentials.class)
|
||||
public CloudCredentials cloudCredentials() {
|
||||
return new CloudCredentials(this.cloudFoundryDiscoveryProperties.getEmail(),
|
||||
this.cloudFoundryDiscoveryProperties.getPassword());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CloudFoundryClient.class)
|
||||
public CloudFoundryClient cloudFoundryClient(CloudCredentials cc) throws MalformedURLException {
|
||||
CloudFoundryClient cloudFoundryClient = new CloudFoundryClient(cc,
|
||||
URI.create(this.cloudFoundryDiscoveryProperties.getCloudControllerUrl()).toURL());
|
||||
cloudFoundryClient.login();
|
||||
return cloudFoundryClient;
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CloudFoundryClient.class)
|
||||
public CloudFoundryClient cloudFoundryClient(CloudCredentials cc)
|
||||
throws MalformedURLException {
|
||||
CloudFoundryClient cloudFoundryClient = new CloudFoundryClient(cc, URI.create(
|
||||
this.cloudFoundryDiscoveryProperties.getCloudControllerUrl()).toURL());
|
||||
cloudFoundryClient.login();
|
||||
return cloudFoundryClient;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CloudFoundryDiscoveryClient.class)
|
||||
public CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient(
|
||||
CloudFoundryClient cloudFoundryClient, Environment environment) {
|
||||
return new CloudFoundryDiscoveryClient(cloudFoundryClient, environment);
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CloudFoundryDiscoveryClient.class)
|
||||
public CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient(
|
||||
CloudFoundryClient cloudFoundryClient, Environment environment) {
|
||||
return new CloudFoundryDiscoveryClient(cloudFoundryClient, environment);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties() {
|
||||
return new CloudFoundryDiscoveryProperties();
|
||||
}
|
||||
@Bean
|
||||
public CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties() {
|
||||
return new CloudFoundryDiscoveryProperties();
|
||||
}
|
||||
}
|
||||
@@ -24,33 +24,43 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
@ConfigurationProperties(prefix = "spring.cloud.cloudfoundry.discovery")
|
||||
public class CloudFoundryDiscoveryProperties {
|
||||
|
||||
private String cloudControllerUrl = "https://api.run.pivotal.io";
|
||||
private String cloudControllerUrl = "https://api.run.pivotal.io";
|
||||
|
||||
private String email;
|
||||
private String email;
|
||||
|
||||
private String password;
|
||||
private String password;
|
||||
|
||||
public String getCloudControllerUrl() {
|
||||
return cloudControllerUrl;
|
||||
}
|
||||
private boolean enabled = true;
|
||||
|
||||
public void setCloudControllerUrl(String cloudControllerUrl) {
|
||||
this.cloudControllerUrl = cloudControllerUrl;
|
||||
}
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
public String getCloudControllerUrl() {
|
||||
return cloudControllerUrl;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
public void setCloudControllerUrl(String cloudControllerUrl) {
|
||||
this.cloudControllerUrl = cloudControllerUrl;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
@@ -36,47 +36,52 @@ import javax.annotation.PostConstruct;
|
||||
@Configuration
|
||||
public class CloudFoundryRibbonClientConfiguration {
|
||||
|
||||
protected static final String DEFAULT_NAMESPACE = "ribbon";
|
||||
protected static final String VALUE_NOT_SET = "__not__set__";
|
||||
protected static final String DEFAULT_NAMESPACE = "ribbon";
|
||||
protected static final String VALUE_NOT_SET = "__not__set__";
|
||||
|
||||
@Value("${ribbon.client.name}")
|
||||
private String serviceId;
|
||||
private String serviceId;
|
||||
|
||||
public CloudFoundryRibbonClientConfiguration (){ }
|
||||
public CloudFoundryRibbonClientConfiguration() {
|
||||
}
|
||||
|
||||
public CloudFoundryRibbonClientConfiguration (String svcId) {
|
||||
this.serviceId = svcId;
|
||||
}
|
||||
public CloudFoundryRibbonClientConfiguration(String svcId) {
|
||||
this.serviceId = svcId;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<?> ribbonServerList(CloudFoundryClient cloudFoundryClient, IClientConfig config) {
|
||||
CloudFoundryServerList cloudFoundryServerList = new CloudFoundryServerList(cloudFoundryClient);
|
||||
cloudFoundryServerList.initWithNiwsConfig(config);
|
||||
return cloudFoundryServerList;
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<?> ribbonServerList(CloudFoundryClient cloudFoundryClient,
|
||||
IClientConfig config) {
|
||||
CloudFoundryServerList cloudFoundryServerList = new CloudFoundryServerList(
|
||||
cloudFoundryClient);
|
||||
cloudFoundryServerList.initWithNiwsConfig(config);
|
||||
return cloudFoundryServerList;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
// FIXME: what should this be?
|
||||
setProp(this.serviceId, CommonClientConfigKey.DeploymentContextBasedVipAddresses.key(), this.serviceId);
|
||||
setProp(this.serviceId, CommonClientConfigKey.EnableZoneAffinity.key(), "true");
|
||||
}
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
// FIXME: what should this be?
|
||||
setProp(this.serviceId,
|
||||
CommonClientConfigKey.DeploymentContextBasedVipAddresses.key(),
|
||||
this.serviceId);
|
||||
setProp(this.serviceId, CommonClientConfigKey.EnableZoneAffinity.key(), "true");
|
||||
}
|
||||
|
||||
protected void setProp(String serviceId, String suffix, String value) {
|
||||
// how to set the namespace properly?
|
||||
String key = getKey(serviceId, suffix);
|
||||
DynamicStringProperty property = getProperty(key);
|
||||
if (property.get().equals(VALUE_NOT_SET)) {
|
||||
ConfigurationManager.getConfigInstance().setProperty(key, value);
|
||||
}
|
||||
}
|
||||
protected void setProp(String serviceId, String suffix, String value) {
|
||||
// how to set the namespace properly?
|
||||
String key = getKey(serviceId, suffix);
|
||||
DynamicStringProperty property = getProperty(key);
|
||||
if (property.get().equals(VALUE_NOT_SET)) {
|
||||
ConfigurationManager.getConfigInstance().setProperty(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected DynamicStringProperty getProperty(String key) {
|
||||
return DynamicPropertyFactory.getInstance().getStringProperty(key, VALUE_NOT_SET);
|
||||
}
|
||||
protected DynamicStringProperty getProperty(String key) {
|
||||
return DynamicPropertyFactory.getInstance().getStringProperty(key, VALUE_NOT_SET);
|
||||
}
|
||||
|
||||
protected String getKey(String serviceId, String suffix) {
|
||||
return serviceId + "." + DEFAULT_NAMESPACE + "." + suffix;
|
||||
}
|
||||
protected String getKey(String serviceId, String suffix) {
|
||||
return serviceId + "." + DEFAULT_NAMESPACE + "." + suffix;
|
||||
}
|
||||
}
|
||||
@@ -24,37 +24,37 @@ import org.cloudfoundry.client.lib.domain.CloudApplication;
|
||||
*/
|
||||
public class CloudFoundryServer extends Server {
|
||||
|
||||
private final MetaInfo metaInfo;
|
||||
private final MetaInfo metaInfo;
|
||||
|
||||
public CloudFoundryServer(final CloudApplication cloudApplication) {
|
||||
public CloudFoundryServer(final CloudApplication cloudApplication) {
|
||||
|
||||
super(cloudApplication.getUris().iterator().next(), 80);
|
||||
super(cloudApplication.getUris().iterator().next(), 80);
|
||||
|
||||
this.metaInfo = new MetaInfo() {
|
||||
@Override
|
||||
public String getAppName() {
|
||||
return cloudApplication.getName();
|
||||
}
|
||||
this.metaInfo = new MetaInfo() {
|
||||
@Override
|
||||
public String getAppName() {
|
||||
return cloudApplication.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServerGroup() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getServerGroup() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceIdForDiscovery() {
|
||||
return cloudApplication.getName();
|
||||
}
|
||||
@Override
|
||||
public String getServiceIdForDiscovery() {
|
||||
return cloudApplication.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInstanceId() {
|
||||
return cloudApplication.getName();
|
||||
}
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public String getInstanceId() {
|
||||
return cloudApplication.getName();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetaInfo getMetaInfo() {
|
||||
return metaInfo;
|
||||
}
|
||||
@Override
|
||||
public MetaInfo getMetaInfo() {
|
||||
return metaInfo;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,9 @@ package org.springframework.cloud.cloudfoundry.discovery;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractServerList;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.cloudfoundry.client.lib.CloudFoundryClient;
|
||||
import org.cloudfoundry.client.lib.domain.CloudApplication;
|
||||
|
||||
@@ -29,31 +32,40 @@ import java.util.List;
|
||||
*/
|
||||
public class CloudFoundryServerList extends AbstractServerList<CloudFoundryServer> {
|
||||
|
||||
protected String serviceId;
|
||||
private static final Log log = LogFactory.getLog(CloudFoundryServerList.class);
|
||||
|
||||
private final CloudFoundryClient cloudFoundryClient;
|
||||
protected String serviceId;
|
||||
|
||||
public CloudFoundryServerList(CloudFoundryClient cloudFoundryClient) {
|
||||
this.cloudFoundryClient = cloudFoundryClient;
|
||||
}
|
||||
private final CloudFoundryClient cloudFoundryClient;
|
||||
|
||||
@Override
|
||||
public void initWithNiwsConfig(IClientConfig iClientConfig) {
|
||||
this.serviceId = iClientConfig.getClientName();
|
||||
}
|
||||
public CloudFoundryServerList(CloudFoundryClient cloudFoundryClient) {
|
||||
this.cloudFoundryClient = cloudFoundryClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CloudFoundryServer> getInitialListOfServers() {
|
||||
return this.cloudFoundryServers();
|
||||
}
|
||||
@Override
|
||||
public void initWithNiwsConfig(IClientConfig iClientConfig) {
|
||||
this.serviceId = iClientConfig.getClientName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CloudFoundryServer> getUpdatedListOfServers() {
|
||||
return this.cloudFoundryServers();
|
||||
}
|
||||
@Override
|
||||
public List<CloudFoundryServer> getInitialListOfServers() {
|
||||
return this.cloudFoundryServers();
|
||||
}
|
||||
|
||||
protected List<CloudFoundryServer> cloudFoundryServers() {
|
||||
CloudApplication cloudApplications = this.cloudFoundryClient.getApplication(this.serviceId);
|
||||
return Collections.singletonList(new CloudFoundryServer(cloudApplications));
|
||||
}
|
||||
@Override
|
||||
public List<CloudFoundryServer> getUpdatedListOfServers() {
|
||||
return this.cloudFoundryServers();
|
||||
}
|
||||
|
||||
protected List<CloudFoundryServer> cloudFoundryServers() {
|
||||
try {
|
||||
CloudApplication cloudApplications = this.cloudFoundryClient
|
||||
.getApplication(this.serviceId);
|
||||
return Collections.singletonList(new CloudFoundryServer(cloudApplications));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Cannot determine server list for " + serviceId + ": " + e.getClass() + "(" + e.getMessage() + ")");
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package org.springframework.cloud.cloudfoundry.discovery;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -40,63 +39,65 @@ import java.util.Collections;
|
||||
*/
|
||||
public class CloudFoundryAutoConfigurationTest {
|
||||
|
||||
private ConfigurableApplicationContext context;
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
String hiServiceServiceId = "foo-service";
|
||||
String hiServiceServiceId = "foo-service";
|
||||
|
||||
Object vcapAppl = "{\"limits\":{\"mem\":1024,\"disk\":1024,\"fds\":16384},\"application_version\":" +
|
||||
"\"36eff082-96d6-498f-8214-508fda72ba65\",\"application_name\":\"" + hiServiceServiceId +
|
||||
"\",\"application_uris\"" +
|
||||
":[\"" + hiServiceServiceId +
|
||||
".cfapps.io\"],\"version\":\"36eff082-96d6-498f-8214-508fda72ba65\",\"name\":" +
|
||||
"\"hi-service\",\"space_name\":\"joshlong\",\"space_id\":\"e0cd969c-3461-41ae-abde-4e11bb5acbd1\"," +
|
||||
"\"uris\":[\"hi-service.cfapps.io\"],\"users\":null,\"application_id\":\"af350f7c-88c4-4e35-a04e-698a1dbc7354\"," +
|
||||
"\"instance_id\":\"e4843ca23bd947b28e6d4cb3f9b92cbb\",\"instance_index\":0,\"host\":\"0.0.0.0\",\"port\":61590," +
|
||||
"\"started_at\":\"2015-05-07 20:00:10 +0000\",\"started_at_timestamp\":1431028810,\"start\":\"2015-05-07 20:00:10 +0000\"," +
|
||||
"\"state_timestamp\":1431028810}";
|
||||
Object vcapAppl = "{\"limits\":{\"mem\":1024,\"disk\":1024,\"fds\":16384},\"application_version\":"
|
||||
+ "\"36eff082-96d6-498f-8214-508fda72ba65\",\"application_name\":\""
|
||||
+ hiServiceServiceId
|
||||
+ "\",\"application_uris\""
|
||||
+ ":[\""
|
||||
+ hiServiceServiceId
|
||||
+ ".cfapps.io\"],\"version\":\"36eff082-96d6-498f-8214-508fda72ba65\",\"name\":"
|
||||
+ "\"hi-service\",\"space_name\":\"joshlong\",\"space_id\":\"e0cd969c-3461-41ae-abde-4e11bb5acbd1\","
|
||||
+ "\"uris\":[\"hi-service.cfapps.io\"],\"users\":null,\"application_id\":\"af350f7c-88c4-4e35-a04e-698a1dbc7354\","
|
||||
+ "\"instance_id\":\"e4843ca23bd947b28e6d4cb3f9b92cbb\",\"instance_index\":0,\"host\":\"0.0.0.0\",\"port\":61590,"
|
||||
+ "\"started_at\":\"2015-05-07 20:00:10 +0000\",\"started_at_timestamp\":1431028810,\"start\":\"2015-05-07 20:00:10 +0000\","
|
||||
+ "\"state_timestamp\":1431028810}";
|
||||
|
||||
this.context = new SpringApplicationBuilder()
|
||||
.properties(Collections.singletonMap("VCAP_APPLICATION", vcapAppl))
|
||||
.sources(SimpleConfiguration.class)
|
||||
.run();
|
||||
}
|
||||
this.context = new SpringApplicationBuilder()
|
||||
.properties(Collections.singletonMap("VCAP_APPLICATION", vcapAppl))
|
||||
.sources(SimpleConfiguration.class).run();
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws Throwable {
|
||||
synchronized (this) {
|
||||
if (null != this.context)
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
@After
|
||||
public void after() throws Throwable {
|
||||
synchronized (this) {
|
||||
if (null != this.context)
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients
|
||||
@EnableAutoConfiguration
|
||||
public static class SimpleConfiguration {
|
||||
|
||||
@Configuration
|
||||
@EnableDiscoveryClient
|
||||
@EnableFeignClients
|
||||
@EnableAutoConfiguration
|
||||
public static class SimpleConfiguration {
|
||||
@Bean
|
||||
CloudCredentials cloudCredentials() {
|
||||
return Mockito.mock(CloudCredentials.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
CloudCredentials cloudCredentials() {
|
||||
return Mockito.mock(CloudCredentials.class);
|
||||
}
|
||||
@Bean
|
||||
CloudFoundryClient cloudFoundryClient() {
|
||||
return Mockito.mock(CloudFoundryClient.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
CloudFoundryClient cloudFoundryClient() {
|
||||
return Mockito.mock(CloudFoundryClient.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contextLoaded() {
|
||||
LogFactory.getLog(getClass()).debug("contextLoad()");
|
||||
Assert.assertTrue(this.context.getBeansOfType(CloudFoundryDiscoveryClient.class).size() > 0);
|
||||
Assert.assertTrue(this.context.getBeansOfType(CloudFoundryDiscoveryProperties.class).size() > 0);
|
||||
Assert.assertTrue(this.context.getBeansOfType(CloudFoundryClient.class).size() > 0);
|
||||
}
|
||||
@Test
|
||||
public void contextLoaded() {
|
||||
LogFactory.getLog(getClass()).debug("contextLoad()");
|
||||
Assert.assertTrue(this.context.getBeansOfType(CloudFoundryDiscoveryClient.class)
|
||||
.size() > 0);
|
||||
Assert.assertTrue(this.context.getBeansOfType(
|
||||
CloudFoundryDiscoveryProperties.class).size() > 0);
|
||||
Assert.assertTrue(this.context.getBeansOfType(CloudFoundryClient.class).size() > 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cloud.cloudfoundry.discovery;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.cloudfoundry.client.lib.CloudFoundryClient;
|
||||
import org.cloudfoundry.client.lib.CloudFoundryException;
|
||||
import org.cloudfoundry.client.lib.domain.CloudApplication;
|
||||
import org.cloudfoundry.client.lib.domain.InstanceInfo;
|
||||
import org.cloudfoundry.client.lib.domain.InstanceState;
|
||||
@@ -28,6 +29,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -43,114 +45,135 @@ import static org.mockito.BDDMockito.mock;
|
||||
*/
|
||||
public class CloudFoundryDiscoveryClientTest {
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
private CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient;
|
||||
private CloudFoundryDiscoveryClient cloudFoundryDiscoveryClient;
|
||||
|
||||
private CloudApplication cloudApplication;
|
||||
private CloudApplication cloudApplication;
|
||||
|
||||
private String hiServiceServiceId = "hi-service";
|
||||
private String hiServiceServiceId = "hi-service";
|
||||
|
||||
private CloudFoundryClient cloudFoundryClient;
|
||||
private CloudFoundryClient cloudFoundryClient;
|
||||
|
||||
private CloudApplication fakeCloudApplication(String name, String... uri) {
|
||||
CloudApplication cloudApplication = mock(CloudApplication.class);
|
||||
given(cloudApplication.getName()).willReturn(name);
|
||||
given(cloudApplication.getUris()).willReturn(Arrays.asList(uri));
|
||||
return cloudApplication;
|
||||
}
|
||||
private CloudApplication fakeCloudApplication(String name, String... uri) {
|
||||
CloudApplication cloudApplication = mock(CloudApplication.class);
|
||||
given(cloudApplication.getName()).willReturn(name);
|
||||
given(cloudApplication.getUris()).willReturn(Arrays.asList(uri));
|
||||
return cloudApplication;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.cloudFoundryClient = mock(CloudFoundryClient.class);
|
||||
Environment environment = mock(Environment.class);
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.cloudFoundryClient = mock(CloudFoundryClient.class);
|
||||
Environment environment = mock(Environment.class);
|
||||
|
||||
given(environment.getProperty("VCAP_APPLICATION"))
|
||||
.willReturn("{\"limits\":{\"mem\":1024,\"disk\":1024,\"fds\":16384},\"application_version\":" +
|
||||
"\"36eff082-96d6-498f-8214-508fda72ba65\",\"application_name\":\"" + hiServiceServiceId +
|
||||
"\",\"application_uris\"" +
|
||||
":[\"" + hiServiceServiceId +
|
||||
".cfapps.io\"],\"version\":\"36eff082-96d6-498f-8214-508fda72ba65\",\"name\":" +
|
||||
"\"hi-service\",\"space_name\":\"joshlong\",\"space_id\":\"e0cd969c-3461-41ae-abde-4e11bb5acbd1\"," +
|
||||
"\"uris\":[\"hi-service.cfapps.io\"],\"users\":null,\"application_id\":\"af350f7c-88c4-4e35-a04e-698a1dbc7354\"," +
|
||||
"\"instance_id\":\"e4843ca23bd947b28e6d4cb3f9b92cbb\",\"instance_index\":0,\"host\":\"0.0.0.0\",\"port\":61590," +
|
||||
"\"started_at\":\"2015-05-07 20:00:10 +0000\",\"started_at_timestamp\":1431028810,\"start\":\"2015-05-07 20:00:10 +0000\"," +
|
||||
"\"state_timestamp\":1431028810}");
|
||||
given(environment.getProperty("VCAP_APPLICATION"))
|
||||
.willReturn(
|
||||
"{\"limits\":{\"mem\":1024,\"disk\":1024,\"fds\":16384},\"application_version\":"
|
||||
+ "\"36eff082-96d6-498f-8214-508fda72ba65\",\"application_name\":\""
|
||||
+ hiServiceServiceId
|
||||
+ "\",\"application_uris\""
|
||||
+ ":[\""
|
||||
+ hiServiceServiceId
|
||||
+ ".cfapps.io\"],\"version\":\"36eff082-96d6-498f-8214-508fda72ba65\",\"name\":"
|
||||
+ "\"hi-service\",\"space_name\":\"joshlong\",\"space_id\":\"e0cd969c-3461-41ae-abde-4e11bb5acbd1\","
|
||||
+ "\"uris\":[\"hi-service.cfapps.io\"],\"users\":null,\"application_id\":\"af350f7c-88c4-4e35-a04e-698a1dbc7354\","
|
||||
+ "\"instance_id\":\"e4843ca23bd947b28e6d4cb3f9b92cbb\",\"instance_index\":0,\"host\":\"0.0.0.0\",\"port\":61590,"
|
||||
+ "\"started_at\":\"2015-05-07 20:00:10 +0000\",\"started_at_timestamp\":1431028810,\"start\":\"2015-05-07 20:00:10 +0000\","
|
||||
+ "\"state_timestamp\":1431028810}");
|
||||
|
||||
List<CloudApplication> cloudApplications = new ArrayList<>();
|
||||
cloudApplications.add(fakeCloudApplication(this.hiServiceServiceId, "hi-service.cfapps.io", "hi-service-1.cfapps.io"));
|
||||
cloudApplications.add(fakeCloudApplication("config-service", "conf-service.cfapps.io", "conf-service-1.cfapps.io"));
|
||||
List<CloudApplication> cloudApplications = new ArrayList<>();
|
||||
cloudApplications.add(fakeCloudApplication(this.hiServiceServiceId,
|
||||
"hi-service.cfapps.io", "hi-service-1.cfapps.io"));
|
||||
cloudApplications.add(fakeCloudApplication("config-service",
|
||||
"conf-service.cfapps.io", "conf-service-1.cfapps.io"));
|
||||
|
||||
given(this.cloudFoundryClient.getApplications())
|
||||
.willReturn(cloudApplications);
|
||||
given(this.cloudFoundryClient.getApplications()).willReturn(cloudApplications);
|
||||
|
||||
cloudApplication = cloudApplications.get(0);
|
||||
given(this.cloudFoundryClient.getApplication(this.hiServiceServiceId))
|
||||
.willReturn(cloudApplication);
|
||||
cloudApplication = cloudApplications.get(0);
|
||||
given(this.cloudFoundryClient.getApplication(this.hiServiceServiceId))
|
||||
.willReturn(cloudApplication);
|
||||
|
||||
given(this.cloudFoundryClient.getApplication(this.hiServiceServiceId))
|
||||
.willReturn(this.cloudApplication);
|
||||
given(this.cloudFoundryClient.getApplication(this.hiServiceServiceId))
|
||||
.willReturn(this.cloudApplication);
|
||||
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
InstancesInfo instancesInfo = mock(InstancesInfo.class);
|
||||
given(instancesInfo.getInstances())
|
||||
.willReturn(Collections.singletonList(instanceInfo));
|
||||
given(instanceInfo.getState())
|
||||
.willReturn(InstanceState.RUNNING);
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
InstancesInfo instancesInfo = mock(InstancesInfo.class);
|
||||
given(instancesInfo.getInstances()).willReturn(
|
||||
Collections.singletonList(instanceInfo));
|
||||
given(instanceInfo.getState()).willReturn(InstanceState.RUNNING);
|
||||
|
||||
given(this.cloudFoundryClient.getApplicationInstances(this.cloudApplication))
|
||||
.willReturn(instancesInfo);
|
||||
given(this.cloudFoundryClient.getApplicationInstances(this.cloudApplication))
|
||||
.willReturn(instancesInfo);
|
||||
|
||||
this.cloudFoundryDiscoveryClient = new CloudFoundryDiscoveryClient(cloudFoundryClient, environment);
|
||||
}
|
||||
this.cloudFoundryDiscoveryClient = new CloudFoundryDiscoveryClient(
|
||||
cloudFoundryClient, environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testServiceResolution() {
|
||||
List<String> serviceNames = this.cloudFoundryDiscoveryClient.getServices();
|
||||
@Test
|
||||
public void testServiceResolution() {
|
||||
List<String> serviceNames = this.cloudFoundryDiscoveryClient.getServices();
|
||||
|
||||
Assert.assertTrue("there should be one registered service.", serviceNames.contains(
|
||||
this.hiServiceServiceId));
|
||||
Assert.assertTrue("there should be one registered service.",
|
||||
serviceNames.contains(this.hiServiceServiceId));
|
||||
|
||||
for (String serviceName : serviceNames) {
|
||||
this.log.debug("\t discovered serviceName: " + serviceName);
|
||||
}
|
||||
}
|
||||
for (String serviceName : serviceNames) {
|
||||
this.log.debug("\t discovered serviceName: " + serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstances() {
|
||||
List<ServiceInstance> instances = this.cloudFoundryDiscoveryClient.getInstances(
|
||||
this.hiServiceServiceId);
|
||||
assertEquals(instances.size(), 1);
|
||||
}
|
||||
@Test
|
||||
public void testInstances() {
|
||||
List<ServiceInstance> instances = this.cloudFoundryDiscoveryClient
|
||||
.getInstances(this.hiServiceServiceId);
|
||||
assertEquals(instances.size(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalServiceInstanceRunning() {
|
||||
@Test
|
||||
public void testLocalServiceInstanceRunning() {
|
||||
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
InstancesInfo instancesInfo = mock(InstancesInfo.class);
|
||||
given(instancesInfo.getInstances()).willReturn(Collections.singletonList(instanceInfo));
|
||||
given(instanceInfo.getState()).willReturn(InstanceState.RUNNING);
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
InstancesInfo instancesInfo = mock(InstancesInfo.class);
|
||||
given(instancesInfo.getInstances()).willReturn(
|
||||
Collections.singletonList(instanceInfo));
|
||||
given(instanceInfo.getState()).willReturn(InstanceState.RUNNING);
|
||||
|
||||
given(cloudFoundryClient.getApplicationInstances(this.cloudApplication)).willReturn(instancesInfo);
|
||||
given(cloudFoundryClient.getApplicationInstances(this.cloudApplication))
|
||||
.willReturn(instancesInfo);
|
||||
|
||||
ServiceInstance localServiceInstance = this.cloudFoundryDiscoveryClient.getLocalServiceInstance();
|
||||
assertTrue(localServiceInstance.getHost().contains("hi-service.cfapps.io"));
|
||||
assertTrue(localServiceInstance.getServiceId().equals(this.hiServiceServiceId));
|
||||
assertEquals(localServiceInstance.getPort(), 80);
|
||||
}
|
||||
ServiceInstance localServiceInstance = this.cloudFoundryDiscoveryClient
|
||||
.getLocalServiceInstance();
|
||||
assertTrue(localServiceInstance.getHost().contains("hi-service.cfapps.io"));
|
||||
assertTrue(localServiceInstance.getServiceId().equals(this.hiServiceServiceId));
|
||||
assertEquals(localServiceInstance.getPort(), 80);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalServiceInstanceNotRunning() {
|
||||
@Test
|
||||
public void testLocalServiceInstanceNotRunning() {
|
||||
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
InstancesInfo instancesInfo = mock(InstancesInfo.class);
|
||||
given(instancesInfo.getInstances()).willReturn(Collections.singletonList(instanceInfo));
|
||||
given(instanceInfo.getState()).willReturn(InstanceState.CRASHED);
|
||||
InstanceInfo instanceInfo = mock(InstanceInfo.class);
|
||||
InstancesInfo instancesInfo = mock(InstancesInfo.class);
|
||||
given(instancesInfo.getInstances()).willReturn(
|
||||
Collections.singletonList(instanceInfo));
|
||||
given(instanceInfo.getState()).willReturn(InstanceState.CRASHED);
|
||||
|
||||
given(cloudFoundryClient.getApplicationInstances(this.cloudApplication)).willReturn(instancesInfo);
|
||||
given(cloudFoundryClient.getApplicationInstances(this.cloudApplication))
|
||||
.willReturn(instancesInfo);
|
||||
|
||||
ServiceInstance localServiceInstance = this.cloudFoundryDiscoveryClient.getLocalServiceInstance();
|
||||
assertNull(localServiceInstance);
|
||||
}
|
||||
ServiceInstance localServiceInstance = this.cloudFoundryDiscoveryClient
|
||||
.getLocalServiceInstance();
|
||||
assertNull(localServiceInstance);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalServiceInstanceNotFoundg() {
|
||||
|
||||
given(cloudFoundryClient.getApplicationInstances(this.cloudApplication))
|
||||
.willThrow(new CloudFoundryException(HttpStatus.NOT_FOUND));
|
||||
|
||||
ServiceInstance localServiceInstance = this.cloudFoundryDiscoveryClient
|
||||
.getLocalServiceInstance();
|
||||
assertNull(localServiceInstance);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,13 +17,16 @@
|
||||
package org.springframework.cloud.cloudfoundry.discovery;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
|
||||
import org.cloudfoundry.client.lib.CloudFoundryClient;
|
||||
import org.cloudfoundry.client.lib.CloudFoundryException;
|
||||
import org.cloudfoundry.client.lib.domain.CloudApplication;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -36,40 +39,54 @@ import static org.mockito.BDDMockito.mock;
|
||||
*/
|
||||
public class CloudFoundryServerListTest {
|
||||
|
||||
private CloudFoundryServerList cloudFoundryServerList;
|
||||
private String serviceId = "foo-service";
|
||||
private CloudFoundryServerList cloudFoundryServerList;
|
||||
private String serviceId = "foo-service";
|
||||
private CloudFoundryClient cloudFoundryClient;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
CloudApplication cloudApplication = mock(CloudApplication.class);
|
||||
given(cloudApplication.getUris()).will(new Answer<List<String>>() {
|
||||
@Override
|
||||
public List<String> answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||
return Arrays.asList("a-url.com", "b-url.com");
|
||||
}
|
||||
});
|
||||
CloudApplication cloudApplication = mock(CloudApplication.class);
|
||||
given(cloudApplication.getUris()).will(new Answer<List<String>>() {
|
||||
@Override
|
||||
public List<String> answer(InvocationOnMock invocationOnMock)
|
||||
throws Throwable {
|
||||
return Arrays.asList("a-url.com", "b-url.com");
|
||||
}
|
||||
});
|
||||
|
||||
CloudFoundryClient cloudFoundryClient = mock(CloudFoundryClient.class);
|
||||
given(cloudFoundryClient.getApplication(this.serviceId)).willReturn(cloudApplication);
|
||||
cloudFoundryClient = mock(CloudFoundryClient.class);
|
||||
given(cloudFoundryClient.getApplication(this.serviceId)).willReturn(
|
||||
cloudApplication);
|
||||
|
||||
IClientConfig iClientConfig = mock(IClientConfig.class);
|
||||
given(iClientConfig.getClientName()).willReturn(this.serviceId);
|
||||
IClientConfig iClientConfig = mock(IClientConfig.class);
|
||||
given(iClientConfig.getClientName()).willReturn(this.serviceId);
|
||||
|
||||
this.cloudFoundryServerList = new CloudFoundryServerList(cloudFoundryClient);
|
||||
this.cloudFoundryServerList.initWithNiwsConfig(iClientConfig);
|
||||
}
|
||||
this.cloudFoundryServerList = new CloudFoundryServerList(cloudFoundryClient);
|
||||
this.cloudFoundryServerList.initWithNiwsConfig(iClientConfig);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListOfServers() {
|
||||
List<CloudFoundryServer> initialListOfServers = this.cloudFoundryServerList.getInitialListOfServers();
|
||||
List<CloudFoundryServer> updatedListOfServers = this.cloudFoundryServerList.getUpdatedListOfServers();
|
||||
Assert.assertEquals(updatedListOfServers, initialListOfServers);
|
||||
Assert.assertTrue(initialListOfServers.size() == 1);
|
||||
}
|
||||
@Test
|
||||
public void testListOfServers() {
|
||||
List<CloudFoundryServer> initialListOfServers = this.cloudFoundryServerList
|
||||
.getInitialListOfServers();
|
||||
List<CloudFoundryServer> updatedListOfServers = this.cloudFoundryServerList
|
||||
.getUpdatedListOfServers();
|
||||
Assert.assertEquals(updatedListOfServers, initialListOfServers);
|
||||
Assert.assertTrue(initialListOfServers.size() == 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInit() {
|
||||
Assert.assertEquals(this.cloudFoundryServerList.serviceId, this.serviceId);
|
||||
}
|
||||
@Test
|
||||
public void testListOfServersFails() {
|
||||
given(cloudFoundryClient.getApplication(this.serviceId)).willThrow(
|
||||
new CloudFoundryException(HttpStatus.NOT_FOUND));
|
||||
List<CloudFoundryServer> initialListOfServers = this.cloudFoundryServerList
|
||||
.getInitialListOfServers();
|
||||
Assert.assertTrue(initialListOfServers.size() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInit() {
|
||||
Assert.assertEquals(this.cloudFoundryServerList.serviceId, this.serviceId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,26 +33,26 @@ import static org.mockito.BDDMockito.mock;
|
||||
*/
|
||||
public class CloudFoundryServerTest {
|
||||
|
||||
private CloudFoundryServer cloudFoundryServer;
|
||||
private List<String> urls = Arrays.asList("a-url.com", "b-url.com");
|
||||
private String serverName = "server-name";
|
||||
private CloudFoundryServer cloudFoundryServer;
|
||||
private List<String> urls = Arrays.asList("a-url.com", "b-url.com");
|
||||
private String serverName = "server-name";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
CloudApplication cloudApplication = mock(CloudApplication.class);
|
||||
given(cloudApplication.getUris()).willReturn(this.urls);
|
||||
given(cloudApplication.getName()).willReturn(this.serverName);
|
||||
given(cloudApplication.getRunningInstances()).willReturn(1);
|
||||
this.cloudFoundryServer = new CloudFoundryServer(cloudApplication);
|
||||
}
|
||||
@Before
|
||||
public void setUp() {
|
||||
CloudApplication cloudApplication = mock(CloudApplication.class);
|
||||
given(cloudApplication.getUris()).willReturn(this.urls);
|
||||
given(cloudApplication.getName()).willReturn(this.serverName);
|
||||
given(cloudApplication.getRunningInstances()).willReturn(1);
|
||||
this.cloudFoundryServer = new CloudFoundryServer(cloudApplication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProperConstruction() {
|
||||
Server.MetaInfo metaInfo = this.cloudFoundryServer.getMetaInfo();
|
||||
@Test
|
||||
public void testProperConstruction() {
|
||||
Server.MetaInfo metaInfo = this.cloudFoundryServer.getMetaInfo();
|
||||
|
||||
Assert.assertEquals(metaInfo.getAppName(), this.serverName);
|
||||
Assert.assertEquals(metaInfo.getServiceIdForDiscovery(), this.serverName);
|
||||
Assert.assertEquals(metaInfo.getInstanceId(), this.serverName);
|
||||
Assert.assertEquals(this.cloudFoundryServer.getHost(), this.urls.get(0));
|
||||
}
|
||||
Assert.assertEquals(metaInfo.getAppName(), this.serverName);
|
||||
Assert.assertEquals(metaInfo.getServiceIdForDiscovery(), this.serverName);
|
||||
Assert.assertEquals(metaInfo.getInstanceId(), this.serverName);
|
||||
Assert.assertEquals(this.cloudFoundryServer.getHost(), this.urls.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,61 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-cloudfoundry-sample</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>spring-cloud-cloudfoundry-sample</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-cloudfoundry</artifactId>
|
||||
<version>1.0.2.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-cloudfoundry-discovery</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-cloudfoundry</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!--skip deploy -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-cloudfoundry-discovery</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.springframework.cloud.cloudfoundry.sample;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
|
||||
import org.apache.commons.lang.builder.ToStringStyle;
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -24,89 +27,105 @@ import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.cloudfoundry.discovery.CloudFoundryDiscoveryClient;
|
||||
import org.springframework.cloud.cloudfoundry.discovery.EnableCloudFoundryClient;
|
||||
import org.springframework.cloud.netflix.feign.EnableFeignClients;
|
||||
import org.springframework.cloud.netflix.feign.FeignClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This example assumes you've registered an application on <A href="http://cloudfoundry.org">Cloud Foundry</A>
|
||||
* named {@code hi-service} that responds with a String at {@code /hi/{name}}. There is a sample file in the project
|
||||
* root called {@code hi-service.groovy} which you can deploy using the {@code spring} CLI and the {@code cf} CLI that
|
||||
* works appropriately for this demonstration.
|
||||
* This example assumes you've registered an application on <A
|
||||
* href="http://cloudfoundry.org">Cloud Foundry</A> named {@code hi-service} that responds
|
||||
* with a String at {@code /hi/ name} . There is a sample file in the project root called
|
||||
* {@code hi-service.groovy} which you can deploy using the {@code spring} CLI and the
|
||||
* {@code cf} CLI that works appropriately for this demonstration.
|
||||
*
|
||||
* @author <a href="mailto:josh@joshlong.com">Josh Long</a>
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
@EnableCloudFoundryClient
|
||||
@EnableFeignClients
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DemoApplication.class, args);
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DemoApplication.class, args);
|
||||
}
|
||||
|
||||
private Log log = LogFactory.getLog(getClass());
|
||||
private Log log = LogFactory.getLog(getClass());
|
||||
|
||||
@Bean
|
||||
CommandLineRunner consume(final LoadBalancerClient loadBalancerClient,
|
||||
final DiscoveryClient discoveryClient,
|
||||
final HiServiceClient hiServiceClient,
|
||||
final RestTemplate restTemplate) {
|
||||
@Bean
|
||||
CommandLineRunner consume(final LoadBalancerClient loadBalancerClient,
|
||||
final CloudFoundryDiscoveryClient discoveryClient, final HiServiceClient hiServiceClient,
|
||||
final RestTemplate restTemplate) {
|
||||
|
||||
return new CommandLineRunner() {
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
return new CommandLineRunner() {
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
|
||||
// this demonstrates using the CF/Ribbon-aware RestTemplate interceptor
|
||||
log.info("=====================================");
|
||||
log.info("Hi: " + restTemplate.getForEntity("http://hi-service/hi/{name}", String.class, "Josh"));
|
||||
try {
|
||||
// this demonstrates using the CF/Ribbon-aware RestTemplate
|
||||
// interceptor
|
||||
log.info("=====================================");
|
||||
log.info("Hi: "
|
||||
+ restTemplate.getForEntity("http://hi-service/hi/{name}",
|
||||
String.class, "Josh"));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Failed to fetch hi-service", e);
|
||||
}
|
||||
|
||||
// this demonstrates using the Spring Cloud Commons DiscoveryClient abstraction
|
||||
log.info("=====================================");
|
||||
for (String svc : discoveryClient.getServices()) {
|
||||
log.info("service = " + svc);
|
||||
List<ServiceInstance> instances = discoveryClient.getInstances(svc);
|
||||
for (ServiceInstance si : instances) {
|
||||
log.info("\t" + ReflectionToStringBuilder.reflectionToString(si, ToStringStyle.MULTI_LINE_STYLE));
|
||||
}
|
||||
}
|
||||
// this demonstrates using the Spring Cloud Commons DiscoveryClient
|
||||
// abstraction
|
||||
log.info("=====================================");
|
||||
for (String svc : discoveryClient.getServices()) {
|
||||
log.info("service = " + svc);
|
||||
List<ServiceInstance> instances = discoveryClient.getInstances(svc);
|
||||
for (ServiceInstance si : instances) {
|
||||
log.info("\t"
|
||||
+ ReflectionToStringBuilder.reflectionToString(si,
|
||||
ToStringStyle.MULTI_LINE_STYLE));
|
||||
}
|
||||
}
|
||||
|
||||
log.info("=====================================");
|
||||
log.info("local: ");
|
||||
log.info("\t" + ReflectionToStringBuilder.reflectionToString(
|
||||
discoveryClient.getLocalServiceInstance(), ToStringStyle.MULTI_LINE_STYLE));
|
||||
log.info("=====================================");
|
||||
log.info("local: ");
|
||||
log.info("\t"
|
||||
+ ReflectionToStringBuilder.reflectionToString(
|
||||
discoveryClient.getLocalServiceInstance(),
|
||||
ToStringStyle.MULTI_LINE_STYLE));
|
||||
|
||||
// this demonstrates using a CF/Ribbon-aware Feign client
|
||||
log.info("=====================================");
|
||||
log.info("Hi:" + hiServiceClient.hi("Josh"));
|
||||
try {
|
||||
// this demonstrates using a CF/Ribbon-aware Feign client
|
||||
log.info("=====================================");
|
||||
log.info("Hi:" + hiServiceClient.hi("Josh"));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.warn("Failed to fetch hi-service", e);
|
||||
}
|
||||
|
||||
// this demonstrates using the Spring Cloud Commons LoadBalancerClient
|
||||
log.info("=====================================");
|
||||
ServiceInstance choose = loadBalancerClient.choose("hi-service");
|
||||
log.info("chose: " + '(' + choose.getServiceId() + ") " + choose.getHost() + ':' + choose.getPort());
|
||||
}
|
||||
};
|
||||
}
|
||||
// this demonstrates using the Spring Cloud Commons LoadBalancerClient
|
||||
log.info("=====================================");
|
||||
ServiceInstance choose = loadBalancerClient.choose("hi-service");
|
||||
if (choose != null) {
|
||||
log.info("chose: " + '(' + choose.getServiceId() + ") "
|
||||
+ choose.getHost() + ':' + choose.getPort());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@FeignClient("hi-service")
|
||||
interface HiServiceClient {
|
||||
|
||||
@RequestMapping(value = "/hi/{name}", method = RequestMethod.GET)
|
||||
Map<String, Object> hi(@PathVariable("name") String name);
|
||||
@RequestMapping(value = "/hi/{name}", method = RequestMethod.GET)
|
||||
Map<String, Object> hi(@PathVariable("name") String name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
spring.application.name=test-app
|
||||
spring.cloud.cloudfoundry.discovery.email=starbuxman@gmail.com
|
||||
spring.cloud.cloudfoundry.discovery.password=xxxx
|
||||
spring.cloud.cloudfoundry.discovery.email=${email:starbuxman@gmail.com}
|
||||
spring.cloud.cloudfoundry.discovery.password=${password:xxxx}
|
||||
VCAP_APPLICATION={"limits":{"mem":1024,"disk":1024,"fds":16384},"application_version":"36eff082-96d6-498f-8214-508fda72ba65","application_name":"hi-service","application_uris":["hi-service.cfapps.io"],"version":"36eff082-96d6-498f-8214-508fda72ba65","name":"hi-service","space_name":"joshlong","space_id":"e0cd969c-3461-41ae-abde-4e11bb5acbd1","uris":["hi-service.cfapps.io"],"users":null,"application_id":"af350f7c-88c4-4e35-a04e-698a1dbc7354","instance_id":"e4843ca23bd947b28e6d4cb3f9b92cbb","instance_index":0,"host":"0.0.0.0","port":61590,"started_at":"2015-05-07 20:00:10 +0000","started_at_timestamp":1431028810,"start":"2015-05-07 20:00:10 +0000","state_timestamp":1431028810}
|
||||
@@ -10,7 +10,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-cloudfoundry</artifactId>
|
||||
<version>1.0.2.BUILD-SNAPSHOT</version>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user