diff --git a/pom.xml b/pom.xml index 2865a01..85c10f8 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 spring-cloud-cloudfoundry - 1.0.2.BUILD-SNAPSHOT + 1.0.0.BUILD-SNAPSHOT pom diff --git a/spring-cloud-cloudfoundry-discovery/pom.xml b/spring-cloud-cloudfoundry-discovery/pom.xml index 9fb5379..adc65f7 100644 --- a/spring-cloud-cloudfoundry-discovery/pom.xml +++ b/spring-cloud-cloudfoundry-discovery/pom.xml @@ -1,80 +1,84 @@ - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - spring-cloud-cloudfoundry-discovery - jar - Spring Cloud CloudFoundry Discovery + spring-cloud-cloudfoundry-discovery + jar + Spring Cloud CloudFoundry Discovery - - org.springframework.cloud - spring-cloud-cloudfoundry - 1.0.2.BUILD-SNAPSHOT - .. - + + org.springframework.cloud + spring-cloud-cloudfoundry + 1.0.0.BUILD-SNAPSHOT + .. + - - - org.springframework.cloud - spring-cloud-netflix-core - - - org.springframework.boot - spring-boot-starter-logging - - - com.netflix.archaius - archaius-core - - - com.netflix.ribbon - ribbon - - - com.netflix.ribbon - ribbon-core - - - com.netflix.ribbon - ribbon-httpclient - - - com.netflix.ribbon - ribbon-loadbalancer - + + + org.springframework.cloud + spring-cloud-commons + + + org.cloudfoundry + cloudfoundry-client-lib + + + org.springframework.cloud + spring-cloud-netflix-core + true + + + com.netflix.archaius + archaius-core + true + + + com.netflix.ribbon + ribbon + true + + + com.netflix.ribbon + ribbon-core + true + + + com.netflix.ribbon + ribbon-httpclient + true + + + com.netflix.ribbon + ribbon-loadbalancer + true + - - - - com.netflix.feign - feign-core - test - - - com.netflix.feign - feign-ribbon - test - - - com.netflix.feign - test - feign-slf4j - - - - org.springframework.cloud - spring-cloud-commons - - - org.cloudfoundry - cloudfoundry-client-lib - - - org.springframework.boot - spring-boot-starter-test - test - - + + org.springframework.boot + spring-boot-starter-logging + test + + + com.netflix.feign + feign-core + test + + + com.netflix.feign + feign-ribbon + test + + + com.netflix.feign + test + feign-slf4j + + + org.springframework.boot + spring-boot-starter-test + test + + diff --git a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClient.java b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClient.java index 05a14c0..6643e4b 100644 --- a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClient.java +++ b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClient.java @@ -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}. *

- * 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: *

+ * *

  * @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;
  * }
  * 
*

- * 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 all 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 all spaces and organizations. Use one of the + * {@link CloudFoundryClient#CloudFoundryClient(CloudCredentials, URL, String, String)} + * variants to specify which space and organization to use. *

* * @author Josh Long * @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 serviceInstances = - this.createServiceInstancesFromCloudApplications(Collections.singletonList(application)); - return serviceInstances.size() > 0 ? serviceInstances.iterator().next() : null; - } + @Override + public ServiceInstance getLocalServiceInstance() { + List 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 getInstances(String s) { - CloudApplication applications = this.cloudFoundryClient.getApplication(s); - return this.createServiceInstancesFromCloudApplications( - Collections.singletonList(applications)); - } + @Override + public List 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 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 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 getServices() { - List services = new ArrayList<>(); - List applications = this.cloudFoundryClient.getApplications(); - Set serviceIds = new HashSet<>(); - for (CloudApplication ca : applications) { - if (isRunning(ca)) { - serviceIds.add(ca.getName()); - } - } - services.addAll(serviceIds); - return services; - } + @Override + public List getServices() { + List services = new ArrayList<>(); + List applications = this.cloudFoundryClient.getApplications(); + Set serviceIds = new HashSet<>(); + for (CloudApplication ca : applications) { + if (isRunning(ca)) { + serviceIds.add(ca.getName()); + } + } + services.addAll(serviceIds); + return services; + } - protected List createServiceInstancesFromCloudApplications( - Collection cloudApplications) { - Set serviceInstances = new HashSet<>(); - for (CloudApplication ca : cloudApplications) { - if (isRunning(ca)) { - serviceInstances.add(new CloudFoundryServiceInstance(ca)); - } - } - List instances = new ArrayList<>(); - instances.addAll(serviceInstances); - return instances; - } + protected List createServiceInstancesFromCloudApplications( + Collection cloudApplications) { + Set serviceInstances = new HashSet<>(); + for (CloudApplication ca : cloudApplications) { + if (isRunning(ca)) { + serviceInstances.add(new CloudFoundryServiceInstance(ca)); + } + } + List 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; + } + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientConfiguration.java b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientConfiguration.java index 8e01ace..0afc404 100644 --- a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientConfiguration.java +++ b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientConfiguration.java @@ -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 Josh Long */ @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(); + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryProperties.java b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryProperties.java index 1aa0f8a..e9a36ef 100644 --- a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryProperties.java +++ b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryProperties.java @@ -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; + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryRibbonClientConfiguration.java b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryRibbonClientConfiguration.java index 2e77484..89056ad 100644 --- a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryRibbonClientConfiguration.java +++ b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryRibbonClientConfiguration.java @@ -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; + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServer.java b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServer.java index 99a440c..f41cece 100644 --- a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServer.java +++ b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServer.java @@ -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; + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerList.java b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerList.java index 94dd134..66f1275 100644 --- a/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerList.java +++ b/spring-cloud-cloudfoundry-discovery/src/main/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerList.java @@ -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 { - 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 getInitialListOfServers() { - return this.cloudFoundryServers(); - } + @Override + public void initWithNiwsConfig(IClientConfig iClientConfig) { + this.serviceId = iClientConfig.getClientName(); + } - @Override - public List getUpdatedListOfServers() { - return this.cloudFoundryServers(); - } + @Override + public List getInitialListOfServers() { + return this.cloudFoundryServers(); + } - protected List cloudFoundryServers() { - CloudApplication cloudApplications = this.cloudFoundryClient.getApplication(this.serviceId); - return Collections.singletonList(new CloudFoundryServer(cloudApplications)); - } + @Override + public List getUpdatedListOfServers() { + return this.cloudFoundryServers(); + } + + protected List 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(); + } + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryAutoConfigurationTest.java b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryAutoConfigurationTest.java index 6c79845..80dfc99 100644 --- a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryAutoConfigurationTest.java +++ b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryAutoConfigurationTest.java @@ -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); + } } diff --git a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientTest.java b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientTest.java index 5c88da8..2946804 100644 --- a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientTest.java +++ b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryDiscoveryClientTest.java @@ -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 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 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 serviceNames = this.cloudFoundryDiscoveryClient.getServices(); + @Test + public void testServiceResolution() { + List 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 instances = this.cloudFoundryDiscoveryClient.getInstances( - this.hiServiceServiceId); - assertEquals(instances.size(), 1); - } + @Test + public void testInstances() { + List 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); + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerListTest.java b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerListTest.java index 1df7822..c79347c 100644 --- a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerListTest.java +++ b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerListTest.java @@ -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>() { - @Override - public List 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>() { + @Override + public List 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 initialListOfServers = this.cloudFoundryServerList.getInitialListOfServers(); - List updatedListOfServers = this.cloudFoundryServerList.getUpdatedListOfServers(); - Assert.assertEquals(updatedListOfServers, initialListOfServers); - Assert.assertTrue(initialListOfServers.size() == 1); - } + @Test + public void testListOfServers() { + List initialListOfServers = this.cloudFoundryServerList + .getInitialListOfServers(); + List 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 initialListOfServers = this.cloudFoundryServerList + .getInitialListOfServers(); + Assert.assertTrue(initialListOfServers.size() == 0); + } + + @Test + public void testInit() { + Assert.assertEquals(this.cloudFoundryServerList.serviceId, this.serviceId); + } } diff --git a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerTest.java b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerTest.java index a9487bb..a92ac95 100644 --- a/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerTest.java +++ b/spring-cloud-cloudfoundry-discovery/src/test/java/org/springframework/cloud/cloudfoundry/discovery/CloudFoundryServerTest.java @@ -33,26 +33,26 @@ import static org.mockito.BDDMockito.mock; */ public class CloudFoundryServerTest { - private CloudFoundryServer cloudFoundryServer; - private List urls = Arrays.asList("a-url.com", "b-url.com"); - private String serverName = "server-name"; + private CloudFoundryServer cloudFoundryServer; + private List 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)); + } } diff --git a/spring-cloud-cloudfoundry-sample/pom.xml b/spring-cloud-cloudfoundry-sample/pom.xml index d2ecc0c..1d3b1b6 100644 --- a/spring-cloud-cloudfoundry-sample/pom.xml +++ b/spring-cloud-cloudfoundry-sample/pom.xml @@ -1,61 +1,81 @@ - - 4.0.0 + + 4.0.0 - spring-cloud-cloudfoundry-sample - jar + spring-cloud-cloudfoundry-sample + jar - - org.springframework.cloud - spring-cloud-cloudfoundry - 1.0.2.BUILD-SNAPSHOT - .. - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - - maven-deploy-plugin - - true - - - - - - - com.netflix.feign - feign-core - - - com.netflix.feign - feign-ribbon - - - com.netflix.feign - feign-slf4j - - - org.springframework.cloud - spring-cloud-cloudfoundry-discovery - - - org.springframework.boot - spring-boot-starter-test - test - - + + org.springframework.cloud + spring-cloud-cloudfoundry + 1.0.0.BUILD-SNAPSHOT + .. + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + + maven-deploy-plugin + + true + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.cloud + spring-cloud-netflix-core + + + commons-lang + commons-lang + 2.6 + + + com.netflix.ribbon + ribbon-loadbalancer + + + com.netflix.ribbon + ribbon-httpclient + + + com.netflix.feign + feign-core + + + com.netflix.feign + feign-ribbon + + + com.netflix.feign + feign-slf4j + + + org.springframework.cloud + spring-cloud-cloudfoundry-discovery + + + org.springframework.boot + spring-boot-starter-test + test + + diff --git a/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/DemoApplication.java b/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/DemoApplication.java index 68b34f5..db42992 100644 --- a/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/DemoApplication.java +++ b/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/DemoApplication.java @@ -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 Cloud Foundry - * 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 Cloud Foundry 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 Josh Long * @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 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 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 hi(@PathVariable("name") String name); + @RequestMapping(value = "/hi/{name}", method = RequestMethod.GET) + Map hi(@PathVariable("name") String name); } - diff --git a/spring-cloud-cloudfoundry-sample/src/main/resources/application.properties b/spring-cloud-cloudfoundry-sample/src/main/resources/application.properties index aaa99e9..a197c9a 100644 --- a/spring-cloud-cloudfoundry-sample/src/main/resources/application.properties +++ b/spring-cloud-cloudfoundry-sample/src/main/resources/application.properties @@ -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} \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-web/pom.xml b/spring-cloud-cloudfoundry-web/pom.xml index e856923..c8a14a2 100644 --- a/spring-cloud-cloudfoundry-web/pom.xml +++ b/spring-cloud-cloudfoundry-web/pom.xml @@ -10,7 +10,7 @@ org.springframework.cloud spring-cloud-cloudfoundry - 1.0.2.BUILD-SNAPSHOT + 1.0.0.BUILD-SNAPSHOT ..