From 7a285cf65d87eb842e2f979545daca02aaf46252 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 11 Mar 2014 13:54:30 +0000 Subject: [PATCH] Convert all sample tests to @IntegrationTest where appropriate Makes them a lot more readable IMO, and also enables @Autowiring from the context into the test case (sweeet). I added @DirtiesContext to all of them as well to be on the safe side, but possbly that can be optimized in some way as well. --- .../log4j/SampleActuatorApplicationTests.java | 64 +- .../SampleActuatorNoWebApplicationTests.java | 47 +- .../SampleActuatorUiApplicationPortTests.java | 82 +-- .../ui/SampleActuatorUiApplicationTests.java | 72 +- .../application-management-port.properties | 2 + ...pertiesSampleActuatorApplicationTests.java | 111 +-- ...gementAddressActuatorApplicationTests.java | 76 +++ ...AddressSampleActuatorApplicationTests.java | 164 ----- ...entPortSampleActuatorApplicationTests.java | 112 +++ ...agementSampleActuatorApplicationTests.java | 102 --- ...agementSampleActuatorApplicationTests.java | 111 +-- .../SampleActuatorApplicationTests.java | 128 +--- ...hutdownSampleActuatorApplicationTests.java | 103 +-- ...agementSampleActuatorApplicationTests.java | 73 +- ...nsecureSampleActuatorApplicationTests.java | 69 +- .../application-endpoints.properties | 2 + .../application-management-address.properties | 4 + .../application-management-port.properties | 2 + .../application-nomanagement.properties | 1 + ...application-unsecure-management.properties | 1 + .../resources/application-unsecure.properties | 1 + .../jetty/SampleJettyApplicationTests.java | 63 +- .../spring-boot-sample-secure/pom.xml | 1 - .../spring-boot-sample-servlet/pom.xml | 1 - .../SampleServletApplicationTests.java | 104 +-- ...pringTestSampleSimpleApplicationTests.java | 5 +- ...igurationSampleTomcatApplicationTests.java | 63 +- .../tomcat/SampleTomcatApplicationTests.java | 63 +- .../SampleTraditionalApplicationTests.java | 67 +- .../jsp/SampleWebJspApplicationTests.java | 65 +- .../pom.xml | 3 - .../SampleMethodSecurityApplicationTests.java | 74 +- .../spring-boot-sample-web-secure/pom.xml | 2 - .../secure/SampleSecureApplicationTests.java | 68 +- .../spring-boot-sample-web-static/pom.xml | 1 - .../ui/SampleWebStaticApplicationTests.java | 67 +- .../ui/SampleWebUiApplicationTests.java | 72 +- .../SampleWebSocketsApplicationTests.java | 43 +- .../org/springframework/boot/test/Base64.java | 646 ++++++++++++++++++ .../boot/test/RestTemplates.java | 92 +++ 40 files changed, 1327 insertions(+), 1500 deletions(-) create mode 100644 spring-boot-samples/spring-boot-sample-actuator-ui/src/test/resources/application-management-port.properties create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressActuatorApplicationTests.java delete mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressSampleActuatorApplicationTests.java create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementPortSampleActuatorApplicationTests.java delete mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementSampleActuatorApplicationTests.java create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-endpoints.properties create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-address.properties create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-port.properties create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-nomanagement.properties create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure-management.properties create mode 100644 spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure.properties create mode 100644 spring-boot/src/main/java/org/springframework/boot/test/Base64.java create mode 100644 spring-boot/src/main/java/org/springframework/boot/test/RestTemplates.java diff --git a/spring-boot-samples/spring-boot-sample-actuator-log4j/src/test/java/sample/actuator/log4j/SampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator-log4j/src/test/java/sample/actuator/log4j/SampleActuatorApplicationTests.java index 27a1b680c4..e322d74c6a 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-log4j/src/test/java/sample/actuator/log4j/SampleActuatorApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator-log4j/src/test/java/sample/actuator/log4j/SampleActuatorApplicationTests.java @@ -16,60 +16,37 @@ package sample.actuator.log4j; -import java.io.IOException; +import static org.junit.Assert.assertEquals; + import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for service demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleActuatorApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleActuatorApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -77,15 +54,4 @@ public class SampleActuatorApplicationTests { assertEquals("Hello Phil", body.get("message")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-actuator-noweb/src/test/java/sample/actuator/SampleActuatorNoWebApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator-noweb/src/test/java/sample/actuator/SampleActuatorNoWebApplicationTests.java index a79a625001..7f33581d9a 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-noweb/src/test/java/sample/actuator/SampleActuatorNoWebApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator-noweb/src/test/java/sample/actuator/SampleActuatorNoWebApplicationTests.java @@ -16,53 +16,32 @@ package sample.actuator; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertNotNull; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.endpoint.MetricsEndpoint; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.junit.Assert.assertNotNull; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * Basic integration tests for service demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorNoWebApplication.class) +@DirtiesContext public class SampleActuatorNoWebApplicationTests { - - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleActuatorNoWebApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } + + @Autowired + private MetricsEndpoint endpoint; @Test public void endpointsExist() throws Exception { - assertNotNull(context.getBean(MetricsEndpoint.class)); + assertNotNull(endpoint); } } diff --git a/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationPortTests.java b/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationPortTests.java index 2fbbf764f3..a33a7c3523 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationPortTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationPortTests.java @@ -16,64 +16,50 @@ package sample.actuator.ui; -import java.io.IOException; +import static org.junit.Assert.assertEquals; + import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Integration tests for separate management and main service ports. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorUiApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext +@ActiveProfiles("management-port") public class SampleActuatorUiApplicationPortTests { - private static ConfigurableApplicationContext context; + @Autowired + private SecurityProperties security; - private static int port = 9010; - private static int managementPort = 9011; + @Value("${server.port}") + private int port = 9010; - @BeforeClass - public static void start() throws Exception { - final String[] args = new String[] { "--server.port=" + port, - "--management.port=" + managementPort, "--management.address=127.0.0.1" }; - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication.run( - SampleActuatorUiApplication.class, args); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } + @Value("${management.port}") + private int managementPort = 9011; @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:" + port, String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); } @@ -81,29 +67,17 @@ public class SampleActuatorUiApplicationPortTests { @Test public void testMetrics() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:" + managementPort + "/metrics", Map.class); assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); } @Test public void testHealth() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:" + managementPort + "/health", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals("ok", entity.getBody()); } - private RestTemplate getRestTemplate() { - - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationTests.java index 9947fbc4e2..5c82064575 100644 --- a/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/java/sample/actuator/ui/SampleActuatorUiApplicationTests.java @@ -16,67 +16,44 @@ package sample.actuator.ui; -import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.Arrays; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorUiApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleActuatorUiApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleActuatorUiApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); - ResponseEntity entity = getRestTemplate().exchange( + ResponseEntity entity = RestTemplates.get().exchange( "http://localhost:8080", HttpMethod.GET, new HttpEntity(headers), String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @@ -86,7 +63,7 @@ public class SampleActuatorUiApplicationTests { @Test public void testCss() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/css/bootstrap.min.css", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody().contains("body")); @@ -95,7 +72,7 @@ public class SampleActuatorUiApplicationTests { @Test public void testMetrics() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/metrics", Map.class); assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); } @@ -104,7 +81,7 @@ public class SampleActuatorUiApplicationTests { public void testError() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); - ResponseEntity entity = getRestTemplate().exchange( + ResponseEntity entity = RestTemplates.get().exchange( "http://localhost:8080/error", HttpMethod.GET, new HttpEntity(headers), String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @@ -118,15 +95,4 @@ public class SampleActuatorUiApplicationTests { "Please contact the operator with the above information")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/resources/application-management-port.properties b/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/resources/application-management-port.properties new file mode 100644 index 0000000000..b04a05c04d --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator-ui/src/test/resources/application-management-port.properties @@ -0,0 +1,2 @@ +server.port: 9010 +management.port: 9011 \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java index ddea001fbf..4b2b5a5fec 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/EndpointsPropertiesSampleActuatorApplicationTests.java @@ -18,75 +18,37 @@ package sample.actuator; import static org.junit.Assert.assertEquals; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.After; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpRequest; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.security.crypto.codec.Base64; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Integration tests for endpoints configuration. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext +@ActiveProfiles("endpoints") public class EndpointsPropertiesSampleActuatorApplicationTests { - private ConfigurableApplicationContext context; - - private void start(final Class configuration, final String... args) - throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication.run(configuration, args); - } - }); - this.context = future.get(60, TimeUnit.SECONDS); - } - - @After - public void stop() { - if (this.context != null) { - this.context.close(); - } - } - @Test public void testCustomErrorPath() throws Exception { - start(SampleActuatorApplication.class, "--error.path=/oops"); - testError(); - } - - @Test - public void testCustomContextPath() throws Exception { - start(SampleActuatorApplication.class, "--management.contextPath=/admin"); - testHealth(); - } - - private void testError() { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", "password").getForEntity( + ResponseEntity entity = RestTemplates.get("user", "password").getForEntity( "http://localhost:8080/oops", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -95,49 +57,12 @@ public class EndpointsPropertiesSampleActuatorApplicationTests { assertEquals(999, body.get("status")); } - private void testHealth() { - ResponseEntity entity = getRestTemplate().getForEntity( + @Test + public void testCustomContextPath() throws Exception { + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/admin/health", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); String body = entity.getBody(); assertEquals("ok", body); } - - private RestTemplate getRestTemplate() { - return getRestTemplate(null, null); - } - - private RestTemplate getRestTemplate(final String username, final String password) { - - List interceptors = new ArrayList(); - - if (username != null) { - - interceptors.add(new ClientHttpRequestInterceptor() { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - request.getHeaders().add( - "Authorization", - "Basic " - + new String(Base64 - .encode((username + ":" + password) - .getBytes()))); - return execution.execute(request, body); - } - }); - } - - RestTemplate restTemplate = new RestTemplate( - new InterceptingClientHttpRequestFactory( - new SimpleClientHttpRequestFactory(), interceptors)); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } } diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressActuatorApplicationTests.java new file mode 100644 index 0000000000..8e2b8f8b05 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressActuatorApplicationTests.java @@ -0,0 +1,76 @@ +/* + * Copyright 2012-2013 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 sample.actuator; + +import static org.junit.Assert.assertEquals; + +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +/** + * Integration tests for separate management and main service ports. + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext +@ActiveProfiles("management-address") +public class ManagementAddressActuatorApplicationTests { + + @Autowired + private SecurityProperties security; + + @Value("${server.port}") + private int port = 9010; + + @Value("${management.port}") + private int managementPort = 9011; + + @Test + public void testHome() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity entity = RestTemplates.get().getForEntity( + "http://localhost:" + port, Map.class); + assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); + } + + @Test + public void testHealth() throws Exception { + ResponseEntity entity = RestTemplates.get().getForEntity( + "http://localhost:" + managementPort + "/admin/health", String.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + assertEquals("ok", entity.getBody()); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressSampleActuatorApplicationTests.java deleted file mode 100644 index 1f3e0e7fc6..0000000000 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementAddressSampleActuatorApplicationTests.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2012-2013 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 sample.actuator; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpRequest; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.security.crypto.codec.Base64; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; - -/** - * Integration tests for separate management and main service ports. - * - * @author Dave Syer - */ -public class ManagementAddressSampleActuatorApplicationTests { - - private static ConfigurableApplicationContext context; - - private static int port = 9010; - private static int managementPort = 9011; - - @BeforeClass - public static void start() throws Exception { - final String[] args = new String[] { "--server.port=" + port, - "--management.port=" + managementPort }; - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication.run( - SampleActuatorApplication.class, args); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - - @Test - public void testHome() throws Exception { - @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( - "http://localhost:" + port, Map.class); - assertEquals(HttpStatus.OK, entity.getStatusCode()); - @SuppressWarnings("unchecked") - Map body = entity.getBody(); - assertEquals("Hello Phil", body.get("message")); - } - - @Test - public void testMetrics() throws Exception { - testHome(); // makes sure some requests have been made - @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( - "http://localhost:" + managementPort + "/metrics", Map.class); - assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); - } - - @Test - public void testHealth() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( - "http://localhost:" + managementPort + "/health", String.class); - assertEquals(HttpStatus.OK, entity.getStatusCode()); - assertEquals("ok", entity.getBody()); - } - - @Test - public void testErrorPage() throws Exception { - @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( - "http://localhost:" + managementPort + "/error", Map.class); - assertEquals(HttpStatus.OK, entity.getStatusCode()); - @SuppressWarnings("unchecked") - Map body = entity.getBody(); - assertEquals(999, body.get("status")); - } - - private String getPassword() { - return context.getBean(SecurityProperties.class).getUser().getPassword(); - } - - private RestTemplate getRestTemplate() { - return getRestTemplate(null, null); - } - - private RestTemplate getRestTemplate(final String username, final String password) { - - List interceptors = new ArrayList(); - - if (username != null) { - - interceptors.add(new ClientHttpRequestInterceptor() { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - request.getHeaders().add( - "Authorization", - "Basic " - + new String(Base64 - .encode((username + ":" + password) - .getBytes()))); - return execution.execute(request, body); - } - }); - } - - RestTemplate restTemplate = new RestTemplate( - new InterceptingClientHttpRequestFactory( - new SimpleClientHttpRequestFactory(), interceptors)); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - -} diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementPortSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementPortSampleActuatorApplicationTests.java new file mode 100644 index 0000000000..58555dff12 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementPortSampleActuatorApplicationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2012-2013 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 sample.actuator; + +import static org.junit.Assert.assertEquals; + +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.client.RestTemplate; + +/** + * Integration tests for separate management and main service ports. + * + * @author Dave Syer + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext +@ActiveProfiles("management-port") +public class ManagementPortSampleActuatorApplicationTests { + + @Autowired + private SecurityProperties security; + + @Value("${server.port}") + private int port = 9010; + + @Value("${management.port}") + private int managementPort = 9011; + + @Test + public void testHome() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( + "http://localhost:" + port, Map.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + @SuppressWarnings("unchecked") + Map body = entity.getBody(); + assertEquals("Hello Phil", body.get("message")); + } + + @Test + public void testMetrics() throws Exception { + testHome(); // makes sure some requests have been made + @SuppressWarnings("rawtypes") + ResponseEntity entity = getRestTemplate().getForEntity( + "http://localhost:" + managementPort + "/metrics", Map.class); + assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); + } + + @Test + public void testHealth() throws Exception { + ResponseEntity entity = getRestTemplate().getForEntity( + "http://localhost:" + managementPort + "/health", String.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + assertEquals("ok", entity.getBody()); + } + + @Test + public void testErrorPage() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity entity = getRestTemplate().getForEntity( + "http://localhost:" + managementPort + "/error", Map.class); + assertEquals(HttpStatus.OK, entity.getStatusCode()); + @SuppressWarnings("unchecked") + Map body = entity.getBody(); + assertEquals(999, body.get("status")); + } + + private String getPassword() { + return security.getUser().getPassword(); + } + + private RestTemplate getRestTemplate() { + return RestTemplates.get(); + } + + private RestTemplate getRestTemplate(final String username, final String password) { + return RestTemplates.get(username, password); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementSampleActuatorApplicationTests.java deleted file mode 100644 index bedc7e38b0..0000000000 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ManagementSampleActuatorApplicationTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2012-2013 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 sample.actuator; - -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; - -/** - * Integration tests for separate management and main service ports. - * - * @author Dave Syer - */ -public class ManagementSampleActuatorApplicationTests { - - private static ConfigurableApplicationContext context; - - private static int port = 9010; - private static int managementPort = 9011; - - @BeforeClass - public static void start() throws Exception { - final String[] args = new String[] { "--server.port=" + port, - "--management.port=" + managementPort, "--management.address=127.0.0.1", "--management.contextPath=/admin" }; - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication.run( - SampleActuatorApplication.class, args); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - - @Test - public void testHome() throws Exception { - @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( - "http://localhost:" + port, Map.class); - assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); - } - - @Test - public void testHealth() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( - "http://localhost:" + managementPort + "/admin/health", String.class); - assertEquals(HttpStatus.OK, entity.getStatusCode()); - assertEquals("ok", entity.getBody()); - } - - private RestTemplate getRestTemplate() { - - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - -} diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/NoManagementSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/NoManagementSampleActuatorApplicationTests.java index 0cd75ce210..72781587cb 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/NoManagementSampleActuatorApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/NoManagementSampleActuatorApplicationTests.java @@ -16,73 +16,44 @@ package sample.actuator; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import static org.junit.Assert.assertEquals; + import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpRequest; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.security.crypto.codec.Base64; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.ResourceAccessException; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Integration tests for switching off management endpoints. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext +@ActiveProfiles("nomanagement") public class NoManagementSampleActuatorApplicationTests { - private static ConfigurableApplicationContext context; - - private static int managementPort = 0; - - @BeforeClass - public static void start() throws Exception { - final String[] args = new String[] { "--management.port=" + managementPort }; - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication.run( - SampleActuatorApplication.class, args); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } + @Autowired + private SecurityProperties security; @Test public void testHome() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( + ResponseEntity entity = RestTemplates.get("user", getPassword()).getForEntity( "http://localhost:8080", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -90,51 +61,17 @@ public class NoManagementSampleActuatorApplicationTests { assertEquals("Hello Phil", body.get("message")); } - @Test(expected = ResourceAccessException.class) + @Test public void testMetricsNotAvailable() throws Exception { testHome(); // makes sure some requests have been made @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( - "http://localhost:" + managementPort + "/metrics", Map.class); + ResponseEntity entity = RestTemplates.get("user", getPassword()).getForEntity( + "http://localhost:8080/metrics", Map.class); assertEquals(HttpStatus.NOT_FOUND, entity.getStatusCode()); } private String getPassword() { - return context.getBean(SecurityProperties.class).getUser().getPassword(); - } - - private RestTemplate getRestTemplate(final String username, final String password) { - - List interceptors = new ArrayList(); - - if (username != null) { - - interceptors.add(new ClientHttpRequestInterceptor() { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - request.getHeaders().add( - "Authorization", - "Basic " - + new String(Base64 - .encode((username + ":" + password) - .getBytes()))); - return execution.execute(request, body); - } - }); - } - - RestTemplate restTemplate = new RestTemplate( - new InterceptingClientHttpRequestFactory( - new SimpleClientHttpRequestFactory(), interceptors)); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - + return security.getUser().getPassword(); } } diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/SampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/SampleActuatorApplicationTests.java index a775762b6c..541e2ab258 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/SampleActuatorApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/SampleActuatorApplicationTests.java @@ -16,77 +16,51 @@ package sample.actuator; -import java.io.IOException; -import java.util.ArrayList; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; -import org.springframework.http.HttpRequest; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.security.crypto.codec.Base64; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for service demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleActuatorApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleActuatorApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } + @Autowired + private SecurityProperties security; @Test public void testHomeIsSecure() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", Map.class); assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -99,7 +73,7 @@ public class SampleActuatorApplicationTests { @Test public void testHome() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( + ResponseEntity entity = RestTemplates.get("user", getPassword()).getForEntity( "http://localhost:8080", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -111,7 +85,7 @@ public class SampleActuatorApplicationTests { public void testMetrics() throws Exception { testHome(); // makes sure some requests have been made @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( + ResponseEntity entity = RestTemplates.get("user", getPassword()).getForEntity( "http://localhost:8080/metrics", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -122,7 +96,7 @@ public class SampleActuatorApplicationTests { @Test public void testEnv() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( + ResponseEntity entity = RestTemplates.get("user", getPassword()).getForEntity( "http://localhost:8080/env", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -132,7 +106,7 @@ public class SampleActuatorApplicationTests { @Test public void testHealth() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/health", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals("ok", entity.getBody()); @@ -140,7 +114,7 @@ public class SampleActuatorApplicationTests { @Test public void testErrorPage() throws Exception { - ResponseEntity entity = getRestTemplate("user", getPassword()) + ResponseEntity entity = RestTemplates.get("user", getPassword()) .getForEntity("http://localhost:8080/foo", String.class); assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, entity.getStatusCode()); String body = entity.getBody(); @@ -153,7 +127,7 @@ public class SampleActuatorApplicationTests { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); HttpEntity request = new HttpEntity(headers); - ResponseEntity entity = getRestTemplate("user", getPassword()).exchange( + ResponseEntity entity = RestTemplates.get("user", getPassword()).exchange( "http://localhost:8080/foo", HttpMethod.GET, request, String.class); assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, entity.getStatusCode()); String body = entity.getBody(); @@ -164,9 +138,9 @@ public class SampleActuatorApplicationTests { @Test public void testTrace() throws Exception { - getRestTemplate().getForEntity("http://localhost:8080/health", String.class); + RestTemplates.get().getForEntity("http://localhost:8080/health", String.class); @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()) + ResponseEntity entity = RestTemplates.get("user", getPassword()) .getForEntity("http://localhost:8080/trace", List.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -181,7 +155,7 @@ public class SampleActuatorApplicationTests { @Test public void testErrorPageDirectAccess() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/error", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -193,7 +167,7 @@ public class SampleActuatorApplicationTests { @Test public void testBeans() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()) + ResponseEntity entity = RestTemplates.get("user", getPassword()) .getForEntity("http://localhost:8080/beans", List.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals(1, entity.getBody().size()); @@ -204,45 +178,7 @@ public class SampleActuatorApplicationTests { } private String getPassword() { - return context.getBean(SecurityProperties.class).getUser().getPassword(); - } - - private RestTemplate getRestTemplate() { - return getRestTemplate(null, null); - } - - private RestTemplate getRestTemplate(final String username, final String password) { - - List interceptors = new ArrayList(); - - if (username != null) { - - interceptors.add(new ClientHttpRequestInterceptor() { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - request.getHeaders().add( - "Authorization", - "Basic " - + new String(Base64 - .encode((username + ":" + password) - .getBytes()))); - return execution.execute(request, body); - } - }); - } - - RestTemplate restTemplate = new RestTemplate( - new InterceptingClientHttpRequestFactory( - new SimpleClientHttpRequestFactory(), interceptors)); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - + return security.getUser().getPassword(); } } diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ShutdownSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ShutdownSampleActuatorApplicationTests.java index 3ddc4f45f7..ab29b49df6 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ShutdownSampleActuatorApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/ShutdownSampleActuatorApplicationTests.java @@ -16,70 +16,43 @@ package sample.actuator; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpRequest; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.security.crypto.codec.Base64; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Integration tests for separate management and main service ports. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class ShutdownSampleActuatorApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleActuatorApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } + @Autowired + private SecurityProperties security; @Test public void testHome() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()).getForEntity( + ResponseEntity entity = RestTemplates.get("user", getPassword()).getForEntity( "http://localhost:8080", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -90,7 +63,7 @@ public class ShutdownSampleActuatorApplicationTests { @Test public void testShutdown() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate("user", getPassword()) + ResponseEntity entity = RestTemplates.get("user", getPassword()) .postForEntity("http://localhost:8080/shutdown", null, Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -100,41 +73,7 @@ public class ShutdownSampleActuatorApplicationTests { } private String getPassword() { - return context.getBean(SecurityProperties.class).getUser().getPassword(); - } - - private RestTemplate getRestTemplate(final String username, final String password) { - - List interceptors = new ArrayList(); - - if (username != null) { - - interceptors.add(new ClientHttpRequestInterceptor() { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - request.getHeaders().add( - "Authorization", - "Basic " - + new String(Base64 - .encode((username + ":" + password) - .getBytes()))); - return execution.execute(request, body); - } - }); - } - - RestTemplate restTemplate = new RestTemplate( - new InterceptingClientHttpRequestFactory( - new SimpleClientHttpRequestFactory(), interceptors)); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - + return security.getUser().getPassword(); } } diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureManagementSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureManagementSampleActuatorApplicationTests.java index cc78f571e3..1e79a1266f 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureManagementSampleActuatorApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureManagementSampleActuatorApplicationTests.java @@ -16,27 +16,23 @@ package sample.actuator; -import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Integration tests for unsecured service endpoints (even with Spring Security on @@ -44,36 +40,18 @@ import static org.junit.Assert.assertTrue; * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext +@ActiveProfiles("unsecure-management") public class UnsecureManagementSampleActuatorApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication.run( - SampleActuatorApplication.class, - "--management.security.enabled=false"); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHomeIsSecure() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", Map.class); assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -92,7 +70,7 @@ public class UnsecureManagementSampleActuatorApplicationTests { // ignore; } @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/metrics", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -100,15 +78,4 @@ public class UnsecureManagementSampleActuatorApplicationTests { assertTrue("Wrong body: " + body, body.containsKey("counter.status.401.root")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureSampleActuatorApplicationTests.java b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureSampleActuatorApplicationTests.java index 0eed04cce1..94e310269f 100644 --- a/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureSampleActuatorApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/java/sample/actuator/UnsecureSampleActuatorApplicationTests.java @@ -16,26 +16,22 @@ package sample.actuator; -import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + import java.util.Map; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Integration tests for unsecured service endpoints (even with Spring Security on @@ -43,36 +39,18 @@ import static org.junit.Assert.assertFalse; * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleActuatorApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext +@ActiveProfiles("unsecure") public class UnsecureSampleActuatorApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication.run( - SampleActuatorApplication.class, - "--security.basic.enabled=false"); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { @SuppressWarnings("rawtypes") - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", Map.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @SuppressWarnings("unchecked") @@ -82,15 +60,4 @@ public class UnsecureSampleActuatorApplicationTests { .containsKey("Set-Cookie")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-endpoints.properties b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-endpoints.properties new file mode 100644 index 0000000000..cbb7f9fc5f --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-endpoints.properties @@ -0,0 +1,2 @@ +error.path: /oops +management.contextPath: /admin \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-address.properties b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-address.properties new file mode 100644 index 0000000000..074f16ed18 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-address.properties @@ -0,0 +1,4 @@ +server.port: 9010 +management.port: 9011 +management.address: 127.0.0.1 +management.contextPath: /admin \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-port.properties b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-port.properties new file mode 100644 index 0000000000..b04a05c04d --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-management-port.properties @@ -0,0 +1,2 @@ +server.port: 9010 +management.port: 9011 \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-nomanagement.properties b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-nomanagement.properties new file mode 100644 index 0000000000..835785d0c5 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-nomanagement.properties @@ -0,0 +1 @@ +management.port: -1 \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure-management.properties b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure-management.properties new file mode 100644 index 0000000000..2c4b3e4403 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure-management.properties @@ -0,0 +1 @@ +management.security.enabled: false \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure.properties b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure.properties new file mode 100644 index 0000000000..b536e4db28 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-actuator/src/test/resources/application-unsecure.properties @@ -0,0 +1 @@ +security.basic.enabled: false \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-jetty/src/test/java/sample/jetty/SampleJettyApplicationTests.java b/spring-boot-samples/spring-boot-sample-jetty/src/test/java/sample/jetty/SampleJettyApplicationTests.java index 2548881260..143a57300b 100644 --- a/spring-boot-samples/spring-boot-sample-jetty/src/test/java/sample/jetty/SampleJettyApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-jetty/src/test/java/sample/jetty/SampleJettyApplicationTests.java @@ -16,72 +16,37 @@ package sample.jetty; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleJettyApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleJettyApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleJettyApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals("Hello World", entity.getBody()); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-secure/pom.xml b/spring-boot-samples/spring-boot-sample-secure/pom.xml index f42042e57d..5653cc4a4b 100644 --- a/spring-boot-samples/spring-boot-sample-secure/pom.xml +++ b/spring-boot-samples/spring-boot-sample-secure/pom.xml @@ -16,7 +16,6 @@ org.springframework.boot spring-boot-starter-security - ${project.version} org.springframework.boot diff --git a/spring-boot-samples/spring-boot-sample-servlet/pom.xml b/spring-boot-samples/spring-boot-sample-servlet/pom.xml index 319ef81bfb..2938e1a977 100644 --- a/spring-boot-samples/spring-boot-sample-servlet/pom.xml +++ b/spring-boot-samples/spring-boot-sample-servlet/pom.xml @@ -25,7 +25,6 @@ org.springframework.boot spring-boot-starter-tomcat - ${project.version} provided diff --git a/spring-boot-samples/spring-boot-sample-servlet/src/test/java/sample/servlet/SampleServletApplicationTests.java b/spring-boot-samples/spring-boot-sample-servlet/src/test/java/sample/servlet/SampleServletApplicationTests.java index ca6141cc68..ee15011276 100644 --- a/spring-boot-samples/spring-boot-sample-servlet/src/test/java/sample/servlet/SampleServletApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-servlet/src/test/java/sample/servlet/SampleServletApplicationTests.java @@ -1,117 +1,51 @@ package sample.servlet; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.HttpRequest; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.security.crypto.codec.Base64; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleServletApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleServletApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleServletApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } + @Autowired + private SecurityProperties security; @Test public void testHomeIsSecure() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.UNAUTHORIZED, entity.getStatusCode()); } @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate("user", getPassword()) + ResponseEntity entity = RestTemplates.get("user", getPassword()) .getForEntity("http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals("Hello World", entity.getBody()); } private String getPassword() { - return context.getBean(SecurityProperties.class).getUser().getPassword(); - } - - private RestTemplate getRestTemplate() { - return getRestTemplate(null, null); - } - - private RestTemplate getRestTemplate(final String username, final String password) { - - List interceptors = new ArrayList(); - - if (username != null) { - - interceptors.add(new ClientHttpRequestInterceptor() { - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, - ClientHttpRequestExecution execution) throws IOException { - request.getHeaders().add( - "Authorization", - "Basic " - + new String(Base64 - .encode((username + ":" + password) - .getBytes()))); - return execution.execute(request, body); - } - }); - } - - RestTemplate restTemplate = new RestTemplate( - new InterceptingClientHttpRequestFactory( - new SimpleClientHttpRequestFactory(), interceptors)); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - + return security.getUser().getPassword(); } } diff --git a/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SpringTestSampleSimpleApplicationTests.java b/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SpringTestSampleSimpleApplicationTests.java index 708ad70957..a37e3fba59 100644 --- a/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SpringTestSampleSimpleApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-simple/src/test/java/sample/simple/SpringTestSampleSimpleApplicationTests.java @@ -18,8 +18,7 @@ package sample.simple; import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.SpringApplicationContextLoader; -import org.springframework.test.context.ContextConfiguration; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** @@ -28,7 +27,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * @author Dave Syer */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = SampleSimpleApplication.class, loader = SpringApplicationContextLoader.class) +@SpringApplicationConfiguration(classes = SampleSimpleApplication.class) public class SpringTestSampleSimpleApplicationTests { @Test diff --git a/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java b/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java index 0074ce6033..6cffc01747 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/NonAutoConfigurationSampleTomcatApplicationTests.java @@ -16,15 +16,10 @@ package sample.tomcat; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; import org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration; @@ -32,30 +27,34 @@ import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoCo import org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration; import org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration; import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; -import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import sample.tomcat.NonAutoConfigurationSampleTomcatApplicationTests.NonAutoConfigurationSampleTomcatApplication; import sample.tomcat.service.HelloWorldService; import sample.tomcat.web.SampleController; -import static org.junit.Assert.assertEquals; - /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=NonAutoConfigurationSampleTomcatApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class NonAutoConfigurationSampleTomcatApplicationTests { - private static ConfigurableApplicationContext context; - @Configuration @Import({ EmbeddedServletContainerAutoConfiguration.class, DispatcherServletAutoConfiguration.class, @@ -71,44 +70,12 @@ public class NonAutoConfigurationSampleTomcatApplicationTests { } - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(NonAutoConfigurationSampleTomcatApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals("Hello World", entity.getBody()); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/SampleTomcatApplicationTests.java b/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/SampleTomcatApplicationTests.java index 21ce0198e0..1063eb6d7d 100644 --- a/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/SampleTomcatApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-tomcat/src/test/java/sample/tomcat/SampleTomcatApplicationTests.java @@ -16,72 +16,37 @@ package sample.tomcat; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleTomcatApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleTomcatApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleTomcatApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals("Hello World", entity.getBody()); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-traditional/src/test/java/sample/traditional/SampleTraditionalApplicationTests.java b/spring-boot-samples/spring-boot-sample-traditional/src/test/java/sample/traditional/SampleTraditionalApplicationTests.java index 40a02b7549..589d7c4e65 100644 --- a/spring-boot-samples/spring-boot-sample-traditional/src/test/java/sample/traditional/SampleTraditionalApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-traditional/src/test/java/sample/traditional/SampleTraditionalApplicationTests.java @@ -16,59 +16,35 @@ package sample.traditional; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleTraditionalApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleTraditionalApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleTraditionalApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHomeJsp() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); String body = entity.getBody(); @@ -78,7 +54,7 @@ public class SampleTraditionalApplicationTests { @Test public void testStaticPage() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/index.html", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); String body = entity.getBody(); @@ -86,15 +62,4 @@ public class SampleTraditionalApplicationTests { assertTrue("Wrong body:\n" + body, body.contains("

Hello

")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-web-jsp/src/test/java/sample/jsp/SampleWebJspApplicationTests.java b/spring-boot-samples/spring-boot-sample-web-jsp/src/test/java/sample/jsp/SampleWebJspApplicationTests.java index 7385bb8899..d4af97806e 100644 --- a/spring-boot-samples/spring-boot-sample-web-jsp/src/test/java/sample/jsp/SampleWebJspApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-web-jsp/src/test/java/sample/jsp/SampleWebJspApplicationTests.java @@ -1,73 +1,38 @@ package sample.jsp; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for JSP application. * * @author Phillip Webb */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleWebJspApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleWebJspApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleWebJspApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testJspWithEl() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody().contains("/resources/text.txt")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-web-method-security/pom.xml b/spring-boot-samples/spring-boot-sample-web-method-security/pom.xml index afe0c0775f..954b585fed 100644 --- a/spring-boot-samples/spring-boot-sample-web-method-security/pom.xml +++ b/spring-boot-samples/spring-boot-sample-web-method-security/pom.xml @@ -16,17 +16,14 @@ org.springframework.boot spring-boot-starter-actuator - ${project.version} org.springframework.boot spring-boot-starter-security - ${project.version} org.springframework.boot spring-boot-starter-thymeleaf - ${project.version} org.springframework.boot diff --git a/spring-boot-samples/spring-boot-sample-web-method-security/src/test/java/sample/ui/method/SampleMethodSecurityApplicationTests.java b/spring-boot-samples/spring-boot-sample-web-method-security/src/test/java/sample/ui/method/SampleMethodSecurityApplicationTests.java index 2ae169ffc1..e30f640583 100644 --- a/spring-boot-samples/spring-boot-sample-web-method-security/src/test/java/sample/ui/method/SampleMethodSecurityApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-web-method-security/src/test/java/sample/ui/method/SampleMethodSecurityApplicationTests.java @@ -16,70 +16,47 @@ package sample.ui.method; -import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.Arrays; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleMethodSecurityApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleMethodSecurityApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleMethodSecurityApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); - ResponseEntity entity = getRestTemplate().exchange( + ResponseEntity entity = RestTemplates.get().exchange( "http://localhost:8080", HttpMethod.GET, new HttpEntity(headers), String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @@ -95,7 +72,7 @@ public class SampleMethodSecurityApplicationTests { form.set("username", "admin"); form.set("password", "admin"); getCsrf(form, headers); - ResponseEntity entity = getRestTemplate().exchange( + ResponseEntity entity = RestTemplates.get().exchange( "http://localhost:8080/login", HttpMethod.POST, new HttpEntity>(form, headers), String.class); @@ -112,14 +89,14 @@ public class SampleMethodSecurityApplicationTests { form.set("username", "user"); form.set("password", "user"); getCsrf(form, headers); - ResponseEntity entity = getRestTemplate().exchange( + ResponseEntity entity = RestTemplates.get().exchange( "http://localhost:8080/login", HttpMethod.POST, new HttpEntity>(form, headers), String.class); assertEquals(HttpStatus.FOUND, entity.getStatusCode()); String cookie = entity.getHeaders().getFirst("Set-Cookie"); headers.set("Cookie", cookie); - ResponseEntity page = getRestTemplate().exchange( + ResponseEntity page = RestTemplates.get().exchange( entity.getHeaders().getLocation(), HttpMethod.GET, new HttpEntity(headers), String.class); assertEquals(HttpStatus.FORBIDDEN, page.getStatusCode()); @@ -128,7 +105,7 @@ public class SampleMethodSecurityApplicationTests { } private void getCsrf(MultiValueMap form, HttpHeaders headers) { - ResponseEntity page = getRestTemplate().getForEntity( + ResponseEntity page = RestTemplates.get().getForEntity( "http://localhost:8080/login", String.class); String cookie = page.getHeaders().getFirst("Set-Cookie"); headers.set("Cookie", cookie); @@ -139,15 +116,4 @@ public class SampleMethodSecurityApplicationTests { form.set("_csrf", matcher.group(1)); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-web-secure/pom.xml b/spring-boot-samples/spring-boot-sample-web-secure/pom.xml index 5c2e4aec94..3702796fb2 100644 --- a/spring-boot-samples/spring-boot-sample-web-secure/pom.xml +++ b/spring-boot-samples/spring-boot-sample-web-secure/pom.xml @@ -16,12 +16,10 @@ org.springframework.boot spring-boot-starter-security - ${project.version} org.springframework.boot spring-boot-starter-thymeleaf - ${project.version} org.springframework.boot diff --git a/spring-boot-samples/spring-boot-sample-web-secure/src/test/java/sample/ui/secure/SampleSecureApplicationTests.java b/spring-boot-samples/spring-boot-sample-web-secure/src/test/java/sample/ui/secure/SampleSecureApplicationTests.java index 6abaf7c761..1aa6674b59 100644 --- a/spring-boot-samples/spring-boot-sample-web-secure/src/test/java/sample/ui/secure/SampleSecureApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-web-secure/src/test/java/sample/ui/secure/SampleSecureApplicationTests.java @@ -16,66 +16,43 @@ package sample.ui.secure; -import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import java.util.Arrays; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleSecureApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleSecureApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleSecureApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); - ResponseEntity entity = getRestTemplate().exchange( + ResponseEntity entity = RestTemplates.get().exchange( "http://localhost:8080", HttpMethod.GET, new HttpEntity(headers), String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @@ -85,21 +62,10 @@ public class SampleSecureApplicationTests { @Test public void testCss() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/css/bootstrap.min.css", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody().contains("body")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-web-static/pom.xml b/spring-boot-samples/spring-boot-sample-web-static/pom.xml index a0fdffdad2..1d95ec09f6 100644 --- a/spring-boot-samples/spring-boot-sample-web-static/pom.xml +++ b/spring-boot-samples/spring-boot-sample-web-static/pom.xml @@ -24,7 +24,6 @@ org.springframework.boot spring-boot-starter-tomcat - ${project.version} provided diff --git a/spring-boot-samples/spring-boot-sample-web-static/src/test/java/sample/ui/SampleWebStaticApplicationTests.java b/spring-boot-samples/spring-boot-sample-web-static/src/test/java/sample/ui/SampleWebStaticApplicationTests.java index 50120af9dc..deca6ef7db 100644 --- a/spring-boot-samples/spring-boot-sample-web-static/src/test/java/sample/ui/SampleWebStaticApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-web-static/src/test/java/sample/ui/SampleWebStaticApplicationTests.java @@ -1,59 +1,35 @@ package sample.ui; -import java.io.IOException; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleWebStaticApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleWebStaticApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleWebStaticApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body (title doesn't match):\n" + entity.getBody(), entity @@ -62,7 +38,7 @@ public class SampleWebStaticApplicationTests { @Test public void testCss() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/webjars/bootstrap/3.0.3/css/bootstrap.min.css", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); @@ -71,15 +47,4 @@ public class SampleWebStaticApplicationTests { MediaType.valueOf("text/css"), entity.getHeaders().getContentType()); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-web-ui/src/test/java/sample/ui/SampleWebUiApplicationTests.java b/spring-boot-samples/spring-boot-sample-web-ui/src/test/java/sample/ui/SampleWebUiApplicationTests.java index 2343708167..dffd518e34 100644 --- a/spring-boot-samples/spring-boot-sample-web-ui/src/test/java/sample/ui/SampleWebUiApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-web-ui/src/test/java/sample/ui/SampleWebUiApplicationTests.java @@ -1,62 +1,39 @@ package sample.ui; -import java.io.IOException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.net.URI; -import java.util.concurrent.Callable; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.ConfigurableApplicationContext; +import org.junit.runner.RunWith; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.RestTemplates; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.DefaultResponseErrorHandler; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; /** * Basic integration tests for demo application. * * @author Dave Syer */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleWebUiApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleWebUiApplicationTests { - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleWebUiApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void testHome() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body (title doesn't match):\n" + entity.getBody(), entity @@ -70,28 +47,17 @@ public class SampleWebUiApplicationTests { MultiValueMap map = new LinkedMultiValueMap(); map.set("text", "FOO text"); map.set("summary", "FOO"); - URI location = getRestTemplate().postForLocation("http://localhost:8080", map); + URI location = RestTemplates.get().postForLocation("http://localhost:8080", map); assertTrue("Wrong location:\n" + location, location.toString().contains("localhost:8080")); } @Test public void testCss() throws Exception { - ResponseEntity entity = getRestTemplate().getForEntity( + ResponseEntity entity = RestTemplates.get().getForEntity( "http://localhost:8080/css/bootstrap.min.css", String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody().contains("body")); } - private RestTemplate getRestTemplate() { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { - @Override - public void handleError(ClientHttpResponse response) throws IOException { - } - }); - return restTemplate; - - } - } diff --git a/spring-boot-samples/spring-boot-sample-websocket/src/test/java/samples/websocket/echo/SampleWebSocketsApplicationTests.java b/spring-boot-samples/spring-boot-sample-websocket/src/test/java/samples/websocket/echo/SampleWebSocketsApplicationTests.java index 788e015f3f..96da6682ed 100644 --- a/spring-boot-samples/spring-boot-sample-websocket/src/test/java/samples/websocket/echo/SampleWebSocketsApplicationTests.java +++ b/spring-boot-samples/spring-boot-sample-websocket/src/test/java/samples/websocket/echo/SampleWebSocketsApplicationTests.java @@ -16,22 +16,25 @@ package samples.websocket.echo; -import java.util.concurrent.Callable; +import static org.junit.Assert.assertEquals; + import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.web.socket.client.WebSocketConnectionManager; import org.springframework.web.socket.client.standard.StandardWebSocketClient; @@ -40,37 +43,17 @@ import samples.websocket.client.SimpleClientWebSocketHandler; import samples.websocket.client.SimpleGreetingService; import samples.websocket.config.SampleWebSocketsApplication; -import static org.junit.Assert.assertEquals; - +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes=SampleWebSocketsApplication.class) +@WebAppConfiguration +@IntegrationTest +@DirtiesContext public class SampleWebSocketsApplicationTests { private static Log logger = LogFactory.getLog(SampleWebSocketsApplicationTests.class); private static final String WS_URI = "ws://localhost:8080/echo/websocket"; - private static ConfigurableApplicationContext context; - - @BeforeClass - public static void start() throws Exception { - Future future = Executors - .newSingleThreadExecutor().submit( - new Callable() { - @Override - public ConfigurableApplicationContext call() throws Exception { - return SpringApplication - .run(SampleWebSocketsApplication.class); - } - }); - context = future.get(60, TimeUnit.SECONDS); - } - - @AfterClass - public static void stop() { - if (context != null) { - context.close(); - } - } - @Test public void runAndWait() throws Exception { ConfigurableApplicationContext context = SpringApplication.run( diff --git a/spring-boot/src/main/java/org/springframework/boot/test/Base64.java b/spring-boot/src/main/java/org/springframework/boot/test/Base64.java new file mode 100644 index 0000000000..94e56ae892 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/test/Base64.java @@ -0,0 +1,646 @@ +/* + * Copyright 2012-2013 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.boot.test; + +/** + * @author dsyer + */ +/** + * Copied from Spring Security Crypto. + * + * @author Luke Taylor + */ +final class Base64 { + + /** No options specified. Value is zero. */ + public final static int NO_OPTIONS = 0; + + /** Specify encoding in first bit. Value is one. */ + public final static int ENCODE = 1; + + /** Specify decoding in first bit. Value is zero. */ + public final static int DECODE = 0; + + /** Do break lines when encoding. Value is 8. */ + public final static int DO_BREAK_LINES = 8; + + /** + * Encode using Base64-like encoding that is URL- and Filename-safe as described in + * Section 4 of RFC3548: http://www.faqs + * .org/rfcs/rfc3548.html. It is important to note that data encoded this way is + * not officially valid Base64, or at the very least should not be called + * Base64 without also specifying that is was encoded using the URL- and Filename-safe + * dialect. + */ + public final static int URL_SAFE = 16; + + /** + * Encode using the special "ordered" dialect of Base64 described here: http://www.faqs.org/qa/rfcc-1940.html. + */ + public final static int ORDERED = 32; + + /** Maximum line length (76) of Base64 output. */ + private final static int MAX_LINE_LENGTH = 76; + + /** The equals sign (=) as a byte. */ + private final static byte EQUALS_SIGN = (byte) '='; + + /** The new line character (\n) as a byte. */ + private final static byte NEW_LINE = (byte) '\n'; + + private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding + private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding + + /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ + + /** The 64 valid Base64 values. */ + /* Host platform me be something funny like EBCDIC, so we hardcode these values. */ + private final static byte[] _STANDARD_ALPHABET = { (byte) 'A', (byte) 'B', + (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', + (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', + (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', + (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', + (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', + (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', + (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', + (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', + (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', + (byte) '+', (byte) '/' }; + + /** + * Translates a Base64 value to either its 6-bit reconstruction value or a negative + * number indicating some other meaning. + **/ + private final static byte[] _STANDARD_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, + -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9, -9, -9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + /* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ + + /** + * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: http://www.faqs.org/rfcs/rfc3548.html. + * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" + * and "slash." + */ + private final static byte[] _URL_SAFE_ALPHABET = { (byte) 'A', (byte) 'B', + (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', + (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', + (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', + (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', + (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', + (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', + (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', + (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', + (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', + (byte) '-', (byte) '_' }; + + /** + * Used in decoding URL- and Filename-safe dialects of Base64. + */ + private final static byte[] _URL_SAFE_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, + -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 62, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, // Decimal 91 - 94 + 63, // Underscore at decimal 95 + -9, // Decimal 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + /* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ + + /** + * I don't get the point of this technique, but someone requested it, and it is + * described here: http://www.faqs.org/ + * qa/rfcc-1940.html. + */ + private final static byte[] _ORDERED_ALPHABET = { (byte) '-', (byte) '0', (byte) '1', + (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', + (byte) '8', (byte) '9', (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', + (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', + (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', + (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', + (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) '_', (byte) 'a', + (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', + (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', + (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', + (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', + (byte) 'z' }; + + /** + * Used in decoding the "ordered" dialect of Base64. + */ + private final static byte[] _ORDERED_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, + -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 0, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // Letters 'A' through 'M' + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, // Letters 'N' through 'Z' + -9, -9, -9, -9, // Decimal 91 - 94 + 37, // Underscore at decimal 95 + -9, // Decimal 96 + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, // Letters 'a' through 'm' + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + public static byte[] decode(byte[] bytes) { + return decode(bytes, 0, bytes.length, NO_OPTIONS); + } + + public static byte[] encode(byte[] bytes) { + return encodeBytesToBytes(bytes, 0, bytes.length, NO_OPTIONS); + } + + public static boolean isBase64(byte[] bytes) { + try { + decode(bytes); + } + catch (InvalidBase64CharacterException e) { + return false; + } + return true; + } + + /** + * Returns one of the _SOMETHING_ALPHABET byte arrays depending on the options + * specified. It's possible, though silly, to specify ORDERED and URLSAFE in + * which case one of them will be picked, though there is no guarantee as to which one + * will be picked. + */ + private static byte[] getAlphabet(int options) { + if ((options & URL_SAFE) == URL_SAFE) { + return _URL_SAFE_ALPHABET; + } + else if ((options & ORDERED) == ORDERED) { + return _ORDERED_ALPHABET; + } + else { + return _STANDARD_ALPHABET; + } + } + + /** + * Returns one of the _SOMETHING_DECODABET byte arrays depending on the options + * specified. It's possible, though silly, to specify ORDERED and URL_SAFE in which + * case one of them will be picked, though there is no guarantee as to which one will + * be picked. + */ + private static byte[] getDecodabet(int options) { + if ((options & URL_SAFE) == URL_SAFE) { + return _URL_SAFE_DECODABET; + } + else if ((options & ORDERED) == ORDERED) { + return _ORDERED_DECODABET; + } + else { + return _STANDARD_DECODABET; + } + } + + /* ******** E N C O D I N G M E T H O D S ******** */ + + /** + *

+ * Encodes up to three bytes of the array source and writes the resulting + * four Base64 bytes to destination. The source and destination arrays can + * be manipulated anywhere along their length by specifying srcOffset and + * destOffset. This method does not check to make sure your arrays are + * large enough to accomodate srcOffset + 3 for the source array + * or destOffset + 4 for the destination array. The actual + * number of significant bytes in your array is given by numSigBytes. + *

+ *

+ * This is the lowest level of the encoding methods with all possible parameters. + *

+ * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param numSigBytes the number of significant bytes in your array + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @return the destination array + * @since 1.3 + */ + private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, + byte[] destination, int destOffset, int options) { + + byte[] ALPHABET = getAlphabet(options); + + // 1 2 3 + // 01234567890123456789012345678901 Bit position + // --------000000001111111122222222 Array position from threeBytes + // --------| || || || | Six bit groups to index ALPHABET + // >>18 >>12 >> 6 >> 0 Right shift necessary + // 0x3f 0x3f 0x3f Additional AND + + // Create buffer with zero-padding if there are only one or two + // significant bytes passed in the array. + // We have to shift left 24 in order to flush out the 1's that appear + // when Java treats a value as negative that is cast from a byte to an int. + int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) + | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) + | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); + + switch (numSigBytes) { + case 3: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f]; + return destination; + + case 2: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + case 1: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = EQUALS_SIGN; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + default: + return destination; + } + } + + /** + * + * @param source The data to convert + * @param off Offset in array where conversion should begin + * @param len Length of data to convert + * @param options Specified options + * @return The Base64-encoded data as a String + * @see Base64#DO_BREAK_LINES + * @throws java.io.IOException if there is an error + * @throws NullPointerException if source array is null + * @throws IllegalArgumentException if source array, offset, or length are invalid + * @since 2.3.1 + */ + private static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options) { + + if (source == null) { + throw new NullPointerException("Cannot serialize a null array."); + } // end if: null + + if (off < 0) { + throw new IllegalArgumentException("Cannot have negative offset: " + off); + } // end if: off < 0 + + if (len < 0) { + throw new IllegalArgumentException("Cannot have length offset: " + len); + } // end if: len < 0 + + if (off + len > source.length) { + throw new IllegalArgumentException(String.format( + "Cannot have offset of %d and length of %d with array of length %d", + off, len, source.length)); + } // end if: off < 0 + + boolean breakLines = (options & DO_BREAK_LINES) > 0; + + // int len43 = len * 4 / 3; + // byte[] outBuff = new byte[ ( len43 ) // Main 4:3 + // + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding + // + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines + // Try to determine more precisely how big the array needs to be. + // If we get it right, we don't have to do an array copy, and + // we save a bunch of memory. + int encLen = (len / 3) * 4 + (len % 3 > 0 ? 4 : 0); // Bytes needed for actual + // encoding + if (breakLines) { + encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters + } + byte[] outBuff = new byte[encLen]; + + int d = 0; + int e = 0; + int len2 = len - 2; + int lineLength = 0; + for (; d < len2; d += 3, e += 4) { + encode3to4(source, d + off, 3, outBuff, e, options); + + lineLength += 4; + if (breakLines && lineLength >= MAX_LINE_LENGTH) { + outBuff[e + 4] = NEW_LINE; + e++; + lineLength = 0; + } // end if: end of line + } // en dfor: each piece of array + + if (d < len) { + encode3to4(source, d + off, len - d, outBuff, e, options); + e += 4; + } // end if: some padding needed + + // Only resize array if we didn't guess it right. + if (e <= outBuff.length - 1) { + byte[] finalOut = new byte[e]; + System.arraycopy(outBuff, 0, finalOut, 0, e); + // System.err.println("Having to resize array from " + outBuff.length + " to " + // + e ); + return finalOut; + } + else { + // System.err.println("No need to resize array."); + return outBuff; + } + } + + /* ******** D E C O D I N G M E T H O D S ******** */ + + /** + * Decodes four bytes from array source and writes the resulting bytes (up + * to three of them) to destination. The source and destination arrays can + * be manipulated anywhere along their length by specifying srcOffset and + * destOffset. This method does not check to make sure your arrays are + * large enough to accomodate srcOffset + 4 for the source array + * or destOffset + 3 for the destination array. This method + * returns the actual number of bytes that were converted from the Base64 encoding. + *

+ * This is the lowest level of the decoding methods with all possible parameters. + *

+ * + * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @param options alphabet type is pulled from this (standard, url-safe, ordered) + * @return the number of decoded bytes converted + * @throws NullPointerException if source or destination arrays are null + * @throws IllegalArgumentException if srcOffset or destOffset are invalid or there is + * not enough room in the array. + * @since 1.3 + */ + private static int decode4to3(final byte[] source, final int srcOffset, + final byte[] destination, final int destOffset, final int options) { + + // Lots of error checking and exception throwing + if (source == null) { + throw new NullPointerException("Source array was null."); + } // end if + if (destination == null) { + throw new NullPointerException("Destination array was null."); + } // end if + if (srcOffset < 0 || srcOffset + 3 >= source.length) { + throw new IllegalArgumentException( + String.format( + "Source array with length %d cannot have offset of %d and still process four bytes.", + source.length, srcOffset)); + } // end if + if (destOffset < 0 || destOffset + 2 >= destination.length) { + throw new IllegalArgumentException( + String.format( + "Destination array with length %d cannot have offset of %d and still store three bytes.", + destination.length, destOffset)); + } // end if + + byte[] DECODABET = getDecodabet(options); + + // Example: Dk== + if (source[srcOffset + 2] == EQUALS_SIGN) { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12); + + destination[destOffset] = (byte) (outBuff >>> 16); + return 1; + } + + // Example: DkL= + else if (source[srcOffset + 3] == EQUALS_SIGN) { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6); + + destination[destOffset] = (byte) (outBuff >>> 16); + destination[destOffset + 1] = (byte) (outBuff >>> 8); + return 2; + } + + // Example: DkLE + else { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) + // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) + | ((DECODABET[source[srcOffset + 3]] & 0xFF)); + + destination[destOffset] = (byte) (outBuff >> 16); + destination[destOffset + 1] = (byte) (outBuff >> 8); + destination[destOffset + 2] = (byte) (outBuff); + + return 3; + } + } + + /** + * Low-level access to decoding ASCII characters in the form of a byte array. + * Ignores GUNZIP option, if it's set. This is not generally a + * recommended method, although it is used internally as part of the decoding process. + * Special case: if len = 0, an empty array is returned. Still, if you need more speed + * and reduced memory footprint (and aren't gzipping), consider this method. + * + * @param source The Base64 encoded data + * @param off The offset of where to begin decoding + * @param len The length of characters to decode + * @param options Can specify options such as alphabet type to use + * @return decoded data + * @throws IllegalArgumentException If bogus characters exist in source data + */ + private static byte[] decode(final byte[] source, final int off, final int len, + final int options) { + + // Lots of error checking and exception throwing + if (source == null) { + throw new NullPointerException("Cannot decode null source array."); + } // end if + if (off < 0 || off + len > source.length) { + throw new IllegalArgumentException( + String.format( + "Source array with length %d cannot have offset of %d and process %d bytes.", + source.length, off, len)); + } // end if + + if (len == 0) { + return new byte[0]; + } + else if (len < 4) { + throw new IllegalArgumentException( + "Base64-encoded string must have at least four characters, but length specified was " + + len); + } // end if + + byte[] DECODABET = getDecodabet(options); + + int len34 = len * 3 / 4; // Estimate on array size + byte[] outBuff = new byte[len34]; // Upper limit on size of output + int outBuffPosn = 0; // Keep track of where we're writing + + byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space + int b4Posn = 0; // Keep track of four byte input buffer + int i = 0; // Source array counter + byte sbiDecode = 0; // Special value from DECODABET + + for (i = off; i < off + len; i++) { // Loop through source + + sbiDecode = DECODABET[source[i] & 0xFF]; + + // White space, Equals sign, or legit Base64 character + // Note the values such as -5 and -9 in the + // DECODABETs at the top of the file. + if (sbiDecode >= WHITE_SPACE_ENC) { + if (sbiDecode >= EQUALS_SIGN_ENC) { + b4[b4Posn++] = source[i]; // Save non-whitespace + if (b4Posn > 3) { // Time to decode? + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options); + b4Posn = 0; + + // If that was the equals sign, break out of 'for' loop + if (source[i] == EQUALS_SIGN) { + break; + } + } + } + } + else { + // There's a bad input character in the Base64 stream. + throw new InvalidBase64CharacterException(String.format( + "Bad Base64 input character decimal %d in array position %d", + (source[i]) & 0xFF, i)); + } + } + + byte[] out = new byte[outBuffPosn]; + System.arraycopy(outBuff, 0, out, 0, outBuffPosn); + return out; + } +} + +@SuppressWarnings("serial") +class InvalidBase64CharacterException extends IllegalArgumentException { + + InvalidBase64CharacterException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/springframework/boot/test/RestTemplates.java b/spring-boot/src/main/java/org/springframework/boot/test/RestTemplates.java new file mode 100644 index 0000000000..6a4db40d28 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/test/RestTemplates.java @@ -0,0 +1,92 @@ +/* + * Copyright 2012-2013 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.boot.test; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.http.HttpRequest; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.client.InterceptingClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.RestTemplate; + +/** + * Convenient static factory for {@link RestTemplate} instances that are suitable for + * integration tests. They are fault tolerant, ignore cookies, and optionally can carry + * Basic authentication headers. + * + * @author Dave Syer + */ +public class RestTemplates { + + /** + * Basic factory method for a RestTemplate that does not follow redirects, ignores + * cookies and does not throw exceptions on server side errors. + * + * @return a basic RestTemplate with no authentication + */ + public static RestTemplate get() { + return get(null, null); + } + + /** + * Factory method for a secure RestTemplate with Basic authentication that does not + * follow redirects, ignores cookies and does not throw exceptions on server side + * errors. + * + * @return a basic RestTemplate with Basic authentication + */ + public static RestTemplate get(final String username, final String password) { + + List interceptors = new ArrayList(); + + if (username != null) { + + interceptors.add(new ClientHttpRequestInterceptor() { + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, + ClientHttpRequestExecution execution) throws IOException { + request.getHeaders().add( + "Authorization", + "Basic " + + new String(Base64 + .encode((username + ":" + password) + .getBytes()))); + return execution.execute(request, body); + } + }); + } + + RestTemplate restTemplate = new RestTemplate( + new InterceptingClientHttpRequestFactory( + new SimpleClientHttpRequestFactory(), interceptors)); + restTemplate.setErrorHandler(new DefaultResponseErrorHandler() { + @Override + public void handleError(ClientHttpResponse response) throws IOException { + } + }); + return restTemplate; + + } + +}