From bdd196bda3c205d46cecdbd778f3fac6a5c0f808 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 18 Apr 2016 11:57:27 +0100 Subject: [PATCH] Remove netflix dependencies There's no need to depend on netflix libraries but the sample was using Ribbon, so we took that out so that the release can be independent. --- .../CloudFoundryDiscoveryClient.java | 21 +-- ...udFoundryDiscoveryClientConfiguration.java | 18 ++- .../CloudFoundryDiscoveryProperties.java | 26 ++++ spring-cloud-cloudfoundry-sample/pom.xml | 17 --- .../sample/CloudFoundryApplication.java | 77 ++++++++++ .../cloudfoundry/sample/DemoApplication.java | 131 ------------------ .../sample/CloudFoundryApplicationTests.java | 41 ++++++ spring-cloud-cloudfoundry-web/pom.xml | 27 ---- .../session/StickyFilterConfiguration.java | 48 +++---- .../spring-cloud-cloudfoundry.properties | 2 + 10 files changed, 192 insertions(+), 216 deletions(-) create mode 100644 spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplication.java delete mode 100644 spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/DemoApplication.java create mode 100644 spring-cloud-cloudfoundry-sample/src/test/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplicationTests.java create mode 100644 spring-cloud-cloudfoundry-web/src/main/resources/spring-cloud-cloudfoundry.properties 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 6643e4b..c1606ae 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 @@ -58,8 +58,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; * 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 cloudFoundryClient = new CloudFoundryClient(cc, + * URI.create(api).toURL()); * cloudFoundryClient.login(); * return cloudFoundryClient; * } @@ -123,23 +123,22 @@ public class CloudFoundryDiscoveryClient implements DiscoveryClient { try { CloudApplication application = this.cloudFoundryClient .getApplication(this.vcapApplicationName); - serviceInstances = this - .createServiceInstancesFromCloudApplications(Collections - .singletonList(application)); + 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; + 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)); + return this.createServiceInstancesFromCloudApplications( + Collections.singletonList(applications)); } private boolean isRunning(CloudApplication ca) { @@ -192,7 +191,9 @@ public class CloudFoundryDiscoveryClient implements DiscoveryClient { } public CloudFoundryServiceInstance(CloudApplication ca) { - super(ca.getName(), ca.getUris().iterator().next(), 80, false); + super(ca.getName(), + ca.getUris().isEmpty() ? "localhost" : ca.getUris().iterator().next(), + 80, false); this.cloudApplication = ca; } 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 880b7f6..054ab66 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 @@ -40,21 +40,29 @@ import org.springframework.core.env.Environment; public class CloudFoundryDiscoveryClientConfiguration { @Autowired - private CloudFoundryDiscoveryProperties cloudFoundryDiscoveryProperties; + private CloudFoundryDiscoveryProperties discovery; @Bean @ConditionalOnMissingBean(CloudCredentials.class) public CloudCredentials cloudCredentials() { - return new CloudCredentials(this.cloudFoundryDiscoveryProperties.getEmail(), - this.cloudFoundryDiscoveryProperties.getPassword()); + return new CloudCredentials(this.discovery.getEmail(), + this.discovery.getPassword()); } @Bean @ConditionalOnMissingBean(CloudFoundryClient.class) public CloudFoundryClient cloudFoundryClient(CloudCredentials cc) throws MalformedURLException { - CloudFoundryClient cloudFoundryClient = new CloudFoundryClient(cc, URI.create( - this.cloudFoundryDiscoveryProperties.getUrl()).toURL()); + CloudFoundryClient cloudFoundryClient; + if (discovery.getOrg() != null && discovery.getSpace() != null) { + cloudFoundryClient = new CloudFoundryClient(cc, + URI.create(this.discovery.getUrl()).toURL(), discovery.getOrg(), + discovery.getSpace()); + } + else { + cloudFoundryClient = new CloudFoundryClient(cc, + URI.create(this.discovery.getUrl()).toURL()); + } cloudFoundryClient.login(); return cloudFoundryClient; } 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 93e3102..b0fc55d 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 @@ -39,6 +39,16 @@ public class CloudFoundryDiscoveryProperties { */ private String password; + /** + * Organization name to authenticate with (default to user's default). + */ + private String org; + + /** + * Space name to authenticate with (default to user's default). + */ + private String space; + /** * Flag to indicate that discovery is enabled. */ @@ -75,4 +85,20 @@ public class CloudFoundryDiscoveryProperties { public void setPassword(String password) { this.password = password; } + + public String getOrg() { + return org; + } + + public void setOrg(String org) { + this.org = org; + } + + public String getSpace() { + return space; + } + + public void setSpace(String space) { + this.space = space; + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-sample/pom.xml b/spring-cloud-cloudfoundry-sample/pom.xml index ed4b716..2fbeb82 100644 --- a/spring-cloud-cloudfoundry-sample/pom.xml +++ b/spring-cloud-cloudfoundry-sample/pom.xml @@ -39,27 +39,10 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.cloud - spring-cloud-netflix-core - org.springframework.cloud spring-cloud-commons - - commons-lang - commons-lang - 2.6 - - - org.springframework.cloud - spring-cloud-starter-ribbon - - - org.springframework.cloud - spring-cloud-starter-feign - org.springframework.cloud spring-cloud-cloudfoundry-discovery diff --git a/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplication.java b/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplication.java new file mode 100644 index 0000000..109508f --- /dev/null +++ b/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplication.java @@ -0,0 +1,77 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.cloudfoundry.sample; + +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +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.cloudfoundry.discovery.CloudFoundryDiscoveryClient; +import org.springframework.cloud.cloudfoundry.discovery.EnableCloudFoundryClient; +import org.springframework.context.annotation.Bean; + +/** + * 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 +@EnableCloudFoundryClient +public class CloudFoundryApplication { + + public static void main(String[] args) { + SpringApplication.run(CloudFoundryApplication.class, args); + } + + private Log log = LogFactory.getLog(getClass()); + + @Bean + CommandLineRunner consume(final CloudFoundryDiscoveryClient discoveryClient) { + + return new CommandLineRunner() { + @Override + public void run(String... args) throws Exception { + + // 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" + si); + } + } + + log.info("====================================="); + log.info("local: "); + log.info("\t" + discoveryClient.getLocalServiceInstance()); + + } + }; + } +} 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 deleted file mode 100644 index db42992..0000000 --- a/spring-cloud-cloudfoundry-sample/src/main/java/org/springframework/cloud/cloudfoundry/sample/DemoApplication.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013-2015 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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; -import org.apache.commons.logging.LogFactory; -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.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.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.client.RestTemplate; - -/** - * 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 -@EnableCloudFoundryClient -@EnableFeignClients -public class DemoApplication { - - public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); - } - - private Log log = LogFactory.getLog(getClass()); - - @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 { - - 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)); - } - } - - log.info("====================================="); - log.info("local: "); - log.info("\t" - + ReflectionToStringBuilder.reflectionToString( - discoveryClient.getLocalServiceInstance(), - ToStringStyle.MULTI_LINE_STYLE)); - - 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"); - 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); - -} diff --git a/spring-cloud-cloudfoundry-sample/src/test/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplicationTests.java b/spring-cloud-cloudfoundry-sample/src/test/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplicationTests.java new file mode 100644 index 0000000..a8b82a7 --- /dev/null +++ b/spring-cloud-cloudfoundry-sample/src/test/java/org/springframework/cloud/cloudfoundry/sample/CloudFoundryApplicationTests.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.cloudfoundry.sample; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +/** + * @author Dave Syer + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = CloudFoundryApplication.class) +@IntegrationTest +@WebAppConfiguration +@Ignore("Need to configure spring.cloud.cloudfoundry.discovery.email/password") +public class CloudFoundryApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/spring-cloud-cloudfoundry-web/pom.xml b/spring-cloud-cloudfoundry-web/pom.xml index 0e9b507..33efebf 100644 --- a/spring-cloud-cloudfoundry-web/pom.xml +++ b/spring-cloud-cloudfoundry-web/pom.xml @@ -20,22 +20,6 @@ spring-boot-configuration-processor true - - org.springframework.cloud - spring-cloud-netflix-core - true - - - org.springframework.cloud - spring-cloud-netflix-eureka-server - true - - - spring-boot-starter-log4j - org.springframework.boot - - - org.springframework.boot @@ -47,17 +31,6 @@ true - - org.projectlombok - lombok - compile - true - - - com.netflix.eureka - eureka-core - true - org.springframework.boot spring-boot-starter-test diff --git a/spring-cloud-cloudfoundry-web/src/main/java/org/springframework/cloud/cloudfoundry/session/StickyFilterConfiguration.java b/spring-cloud-cloudfoundry-web/src/main/java/org/springframework/cloud/cloudfoundry/session/StickyFilterConfiguration.java index f15011b..8776f64 100644 --- a/spring-cloud-cloudfoundry-web/src/main/java/org/springframework/cloud/cloudfoundry/session/StickyFilterConfiguration.java +++ b/spring-cloud-cloudfoundry-web/src/main/java/org/springframework/cloud/cloudfoundry/session/StickyFilterConfiguration.java @@ -16,7 +16,6 @@ package org.springframework.cloud.cloudfoundry.session; import java.io.IOException; -import java.util.UUID; import javax.servlet.FilterChain; import javax.servlet.ServletException; @@ -24,11 +23,11 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.embedded.FilterRegistrationBean; -import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; import org.springframework.core.Ordered; import org.springframework.web.filter.OncePerRequestFilter; @@ -36,31 +35,28 @@ import org.springframework.web.filter.OncePerRequestFilter; * @author Dave Syer */ @Configuration +@PropertySource("spring-cloud-cloudfoundry.properties") public class StickyFilterConfiguration { - private String cookie = UUID.randomUUID().toString(); + @Value("${spring.cloud.cloudfoundry.web.cookie}") + private String cookie; - @Autowired - public void init(EurekaInstanceConfigBean eurekaInstance) { - eurekaInstance.getMetadataMap().put("cookie", cookie); - } - - @Bean - public FilterRegistrationBean stickyCloudFoundryFilter() { - FilterRegistrationBean filter = new FilterRegistrationBean(); - filter.setOrder(Ordered.LOWEST_PRECEDENCE); - filter.setFilter(new OncePerRequestFilter() { - @Override - protected void doFilterInternal(HttpServletRequest request, - HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException { - if (!response.containsHeader("Set-Cookie")) { - response.addCookie(new Cookie("JSESSIONID", cookie)); - } - filterChain.doFilter(request, response); - } - }); - return filter; - } + @Bean + public FilterRegistrationBean stickyCloudFoundryFilter() { + FilterRegistrationBean filter = new FilterRegistrationBean(); + filter.setOrder(Ordered.LOWEST_PRECEDENCE); + filter.setFilter(new OncePerRequestFilter() { + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException { + if (!response.containsHeader("Set-Cookie")) { + response.addCookie(new Cookie("JSESSIONID", cookie)); + } + filterChain.doFilter(request, response); + } + }); + return filter; + } } \ No newline at end of file diff --git a/spring-cloud-cloudfoundry-web/src/main/resources/spring-cloud-cloudfoundry.properties b/spring-cloud-cloudfoundry-web/src/main/resources/spring-cloud-cloudfoundry.properties new file mode 100644 index 0000000..3e84a60 --- /dev/null +++ b/spring-cloud-cloudfoundry-web/src/main/resources/spring-cloud-cloudfoundry.properties @@ -0,0 +1,2 @@ +spring.cloud.cloudfoundry.web.cookie=${random} +eureka.instance.metadata-map.cookie=${spring.cloud.cloudfoundry.web.cookie} \ No newline at end of file