diff --git a/config-client/pom.xml b/config-client/pom.xml new file mode 100644 index 0000000..73480da --- /dev/null +++ b/config-client/pom.xml @@ -0,0 +1,93 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-sample-config-client + 1.0.1.BUILD-SNAPSHOT + jar + + spring-cloud-samples-config-client + Demo project for Spring Cloud + + + org.springframework.cloud + spring-cloud-starter-parent + 1.0.1.BUILD-SNAPSHOT + + + + + UTF-8 + 1.7 + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-starter-config + + + org.projectlombok + lombok + true + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + diff --git a/config-client/src/main/java/demo/StandaloneClientApplication.java b/config-client/src/main/java/demo/StandaloneClientApplication.java new file mode 100644 index 0000000..5e1a142 --- /dev/null +++ b/config-client/src/main/java/demo/StandaloneClientApplication.java @@ -0,0 +1,15 @@ +package demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * @author Dave Syer + */ +@SpringBootApplication +public class StandaloneClientApplication { + + public static void main(String[] args) { + SpringApplication.run(StandaloneClientApplication.class, args); + } +} diff --git a/config-client/src/main/resources/application.yml b/config-client/src/main/resources/application.yml new file mode 100644 index 0000000..ee2a629 --- /dev/null +++ b/config-client/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + application: + name: client diff --git a/config-client/src/main/resources/bootstrap.yml b/config-client/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..a3e7b72 --- /dev/null +++ b/config-client/src/main/resources/bootstrap.yml @@ -0,0 +1 @@ +debug: true \ No newline at end of file diff --git a/config-client/src/test/java/demo/StandaloneClientApplicationTests.java b/config-client/src/test/java/demo/StandaloneClientApplicationTests.java new file mode 100644 index 0000000..e6ce69b --- /dev/null +++ b/config-client/src/test/java/demo/StandaloneClientApplicationTests.java @@ -0,0 +1,25 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = StandaloneClientApplication.class) +@IntegrationTest +@DirtiesContext +public class StandaloneClientApplicationTests { + + @Autowired + private ConfigServicePropertySourceLocator locator; + + @Test + public void contextLoads() throws Exception { + } + +} diff --git a/config-retry/pom.xml b/config-retry/pom.xml new file mode 100644 index 0000000..c830362 --- /dev/null +++ b/config-retry/pom.xml @@ -0,0 +1,111 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-sample-config-retry + 1.0.1.BUILD-SNAPSHOT + jar + + spring-cloud-sample-config-retry + Demo project for Spring Cloud + + + org.springframework.cloud + spring-cloud-starter-parent + 1.0.1.BUILD-SNAPSHOT + + + + + UTF-8 + 1.7 + + + + + + + maven-deploy-plugin + + true + + + + + + + + org.springframework.cloud + spring-cloud-starter-config + + + org.springframework.retry + spring-retry + + + org.springframework.boot + spring-boot-starter-aop + + + org.projectlombok + lombok + true + + + org.springframework.cloud + spring-cloud-config-server + test + + + org.springframework.boot + spring-boot-starter-web + test + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + diff --git a/config-retry/src/main/java/bootstrap/RetryConfiguration.java b/config-retry/src/main/java/bootstrap/RetryConfiguration.java new file mode 100644 index 0000000..8e902ca --- /dev/null +++ b/config-retry/src/main/java/bootstrap/RetryConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014-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 bootstrap; + +import lombok.extern.slf4j.Slf4j; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.retry.interceptor.RetryInterceptorBuilder; +import org.springframework.retry.interceptor.RetryOperationsInterceptor; + +/** + * @author Dave Syer + * + */ +@Slf4j +public class RetryConfiguration { + + @Bean + @ConditionalOnMissingBean(name = "configServerRetryInterceptor") + public RetryOperationsInterceptor configServerRetryInterceptor() { + log.info("Creating custom retry interceptor"); + return RetryInterceptorBuilder.stateless().backOffOptions(3000, 1.5, 10000) + .maxAttempts(10).build(); + } + +} diff --git a/config-retry/src/main/java/demo/StandaloneClientApplication.java b/config-retry/src/main/java/demo/StandaloneClientApplication.java new file mode 100644 index 0000000..7795144 --- /dev/null +++ b/config-retry/src/main/java/demo/StandaloneClientApplication.java @@ -0,0 +1,17 @@ +package demo; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +/** + * @author Spencer Gibb + * @author Dave Syer + */ +@SpringBootApplication +public class StandaloneClientApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(StandaloneClientApplication.class).properties( + "spring.cloud.config.enabled=true").run(args); + } +} diff --git a/config-retry/src/main/resources/META-INF/spring.factories b/config-retry/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..99620c3 --- /dev/null +++ b/config-retry/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.cloud.bootstrap.BootstrapConfiguration=\ +bootstrap.RetryConfiguration \ No newline at end of file diff --git a/config-retry/src/main/resources/application.yml b/config-retry/src/main/resources/application.yml new file mode 100644 index 0000000..ee2a629 --- /dev/null +++ b/config-retry/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + application: + name: client diff --git a/config-retry/src/main/resources/bootstrap.yml b/config-retry/src/main/resources/bootstrap.yml new file mode 100644 index 0000000..c2dedb8 --- /dev/null +++ b/config-retry/src/main/resources/bootstrap.yml @@ -0,0 +1,5 @@ +debug: true +spring: + cloud: + config: + failFast: true \ No newline at end of file diff --git a/config-retry/src/test/java/apps/ConfigServer.java b/config-retry/src/test/java/apps/ConfigServer.java new file mode 100644 index 0000000..b29cf4a --- /dev/null +++ b/config-retry/src/test/java/apps/ConfigServer.java @@ -0,0 +1,45 @@ +/* + * Copyright 2014-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 apps; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.context.ConfigurableApplicationContext; + +/** + * @author Dave Syer + * + */ +@SpringBootApplication +@EnableConfigServer +public class ConfigServer { + + public static void main(String[] args) { + start(args); + } + + public static ConfigurableApplicationContext start(String... args) { + return new SpringApplicationBuilder(ConfigServer.class) + .showBanner(false) + .profiles("native") + .properties("server.port=8888", + "spring.cloud.config.server.native.searchLocation:file:./src/test/resources/config/") + .run(args); + } + +} diff --git a/config-retry/src/test/java/demo/StandaloneClientApplicationTests.java b/config-retry/src/test/java/demo/StandaloneClientApplicationTests.java new file mode 100644 index 0000000..7a0d4c3 --- /dev/null +++ b/config-retry/src/test/java/demo/StandaloneClientApplicationTests.java @@ -0,0 +1,85 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.Executors; + +import org.aopalliance.intercept.MethodInterceptor; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.aop.framework.Advised; +import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor; +import org.springframework.retry.backoff.ExponentialBackOffPolicy; +import org.springframework.retry.interceptor.RetryOperationsInterceptor; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import apps.ConfigServer; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = StandaloneClientApplication.class) +// Explicitly enable config client because test classpath has config server on it +@IntegrationTest({ "spring.cloud.config.enabled=true", + "logging.level.org.springframework.retry=TRACE" }) +@DirtiesContext +public class StandaloneClientApplicationTests { + + @Autowired + private ConfigServicePropertySourceLocator locator; + + private static ConfigurableApplicationContext context; + + @BeforeClass + public static void delayConfigServer() { + Executors.newSingleThreadExecutor().execute(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(2000L); + } + catch (InterruptedException e) { + } + context = ConfigServer.start(); + } + }); + } + + @AfterClass + public static void shutdown() { + if (context!=null) { + context.close(); + } + } + + @Test + public void contextLoads() throws Exception { + assertTrue("ConfigServicePropertySourceLocator is not a proxy (so no retry)", + AopUtils.isAopProxy(locator)); + AnnotationAwareRetryOperationsInterceptor advice = (AnnotationAwareRetryOperationsInterceptor) ((Advised) locator) + .getAdvisors()[0].getAdvice(); + @SuppressWarnings("unchecked") + Map delegates = (Map) ReflectionTestUtils + .getField(advice, "delegates"); + RetryOperationsInterceptor interceptor = (RetryOperationsInterceptor) delegates + .values().iterator().next(); + RetryTemplate retryTemplate = (RetryTemplate) ReflectionTestUtils.getField( + interceptor, "retryOperations"); + ExponentialBackOffPolicy backoff = (ExponentialBackOffPolicy) ReflectionTestUtils + .getField(retryTemplate, "backOffPolicy"); + assertEquals(3000, backoff.getInitialInterval()); + } + +} diff --git a/pom.xml b/pom.xml index 7fdde5f..6695e09 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,8 @@ http://www.spring.io + config-client + config-retry configserver-eureka eureka-first eureka-noweb