Use httpbin as docker compose service
Closes gh-184
This commit is contained in:
@@ -1,7 +1,22 @@
|
||||
version: '3'
|
||||
services:
|
||||
httpecho:
|
||||
image: 'mhalbritter/http-echo:2'
|
||||
httpbin:
|
||||
image: 'mccutchen/go-httpbin:v2.10.0'
|
||||
ports:
|
||||
- '80'
|
||||
- '443'
|
||||
- '8080'
|
||||
httpbin_tls:
|
||||
image: 'mccutchen/go-httpbin:v2.10.0'
|
||||
environment:
|
||||
- 'PORT=8443'
|
||||
- 'HTTPS_CERT_FILE=/server-certificate'
|
||||
- 'HTTPS_KEY_FILE=/server-key'
|
||||
configs:
|
||||
- 'server-certificate'
|
||||
- 'server-key'
|
||||
ports:
|
||||
- '8443'
|
||||
configs:
|
||||
server-certificate:
|
||||
file: './server.crt'
|
||||
server-key:
|
||||
file: './server.key'
|
||||
|
||||
15
framework/rest-template/server.crt
Normal file
15
framework/rest-template/server.crt
Normal file
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICQDCCAcagAwIBAgIUJL2NEOsGlUgyKo3jUur8gol3ymowCgYIKoZIzj0EAwIw
|
||||
VjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwT
|
||||
RGVmYXVsdCBDb21wYW55IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTIzMDYy
|
||||
NjA4MzY0NFoYDzIxMjMwNjAyMDgzNjQ0WjBWMQswCQYDVQQGEwJYWDEVMBMGA1UE
|
||||
BwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMRIw
|
||||
EAYDVQQDDAlsb2NhbGhvc3QwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARm10hC6jI0
|
||||
tA5dVYyYLsaS+rDXaFDbtspX/mxHk5VTfklPD06L3sXcNJeve6YQHlOTwdUzLi2y
|
||||
iGuaVcljlA31iOtfQEATeSdbeFxxLjM22U+FZJ94j14XrbemtpspuTujUzBRMB0G
|
||||
A1UdDgQWBBQEfrPdmYvL/w5sLHWL0eVj0f1M0DAfBgNVHSMEGDAWgBQEfrPdmYvL
|
||||
/w5sLHWL0eVj0f1M0DAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA2gAMGUC
|
||||
MHtVMoEKtgkOcv2fhrv0788S/yIRa6PBt8nxMa6d7mDTFGkMhBCIG168pJk9nHE+
|
||||
vgIxAJ1JF2uB5PYV5nYwliOttnb8LMza7hhun1EVsfKuFgvMUD3VTgtZJ9PE4c8I
|
||||
pxq8IA==
|
||||
-----END CERTIFICATE-----
|
||||
9
framework/rest-template/server.key
Normal file
9
framework/rest-template/server.key
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN EC PARAMETERS-----
|
||||
BgUrgQQAIg==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDCVOy3osulJ/8y+ckbBc0dAdSiLFiRcU1SFqWWsmoaCKexSBOgA8/vG
|
||||
DFFqYvummn6gBwYFK4EEACKhZANiAARm10hC6jI0tA5dVYyYLsaS+rDXaFDbtspX
|
||||
/mxHk5VTfklPD06L3sXcNJeve6YQHlOTwdUzLi2yiGuaVcljlA31iOtfQEATeSdb
|
||||
eFxxLjM22U+FZJ94j14XrbemtpspuTs=
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -19,14 +19,16 @@ class RestTemplateApplicationAotTests {
|
||||
void httpWorks(AssertableOutput output) {
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(30))
|
||||
.untilAsserted(() -> assertThat(output).hasSingleLineContaining("http worked:"));
|
||||
.untilAsserted(() -> assertThat(output)
|
||||
.hasLineMatching("http: DataDto\\{url='http:\\/\\/\\w+:\\d+\\/anything', method='GET'\\}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void httpsWorks(AssertableOutput output) {
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(30))
|
||||
.untilAsserted(() -> assertThat(output).hasSingleLineContaining("https worked:"));
|
||||
.untilAsserted(() -> assertThat(output)
|
||||
.hasLineMatching("https: DataDto\\{url='https:\\/\\/\\w+:\\d+\\/anything', method='GET'\\}"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,27 +2,32 @@ package com.example.resttemplate;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Component
|
||||
@RegisterReflectionForBinding(DataDto.class)
|
||||
class CLR implements CommandLineRunner {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
private final String host;
|
||||
private final String httpHost;
|
||||
|
||||
private final int port;
|
||||
private final int httpPort;
|
||||
|
||||
private final int tlsPort;
|
||||
private final String httpsHost;
|
||||
|
||||
private final int httpsPort;
|
||||
|
||||
CLR(RestTemplate restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.host = env("HTTPECHO_HOST", "localhost");
|
||||
this.port = env("HTTPECHO_PORT_80", 8080);
|
||||
this.tlsPort = env("HTTPECHO_PORT_443", 8443);
|
||||
this.httpHost = env("HTTPBIN_HOST", "localhost");
|
||||
this.httpsHost = env("HTTPBIN_TLS_HOST", "localhost");
|
||||
this.httpPort = env("HTTPBIN_PORT_8080", 8080);
|
||||
this.httpsPort = env("HTTPBIN_TLS_PORT_8443", 8443);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,9 +38,9 @@ class CLR implements CommandLineRunner {
|
||||
|
||||
private void http() {
|
||||
try {
|
||||
String response = this.restTemplate
|
||||
.getForObject(URI.create("http://%s:%d/".formatted(this.host, this.port)), String.class);
|
||||
System.out.printf("http worked: %s%n", response);
|
||||
DataDto dto = restTemplate.getForObject(
|
||||
URI.create("http://%s:%d/anything".formatted(this.httpHost, this.httpPort)), DataDto.class);
|
||||
System.out.printf("http: %s%n", dto);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println("http failed:");
|
||||
@@ -45,9 +50,9 @@ class CLR implements CommandLineRunner {
|
||||
|
||||
private void https() {
|
||||
try {
|
||||
String response = this.restTemplate
|
||||
.getForObject(URI.create("https://%s:%d/".formatted(this.host, this.tlsPort)), String.class);
|
||||
System.out.printf("https worked: %s%n", response);
|
||||
DataDto dto = restTemplate.getForObject(
|
||||
URI.create("https://%s:%d/anything".formatted(this.httpsHost, this.httpsPort)), DataDto.class);
|
||||
System.out.printf("https: %s%n", dto);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println("https failed:");
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.example.resttemplate;
|
||||
|
||||
public class DataDto {
|
||||
|
||||
private String url;
|
||||
|
||||
private String method;
|
||||
|
||||
public DataDto() {
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DataDto{" + "url='" + url + '\'' + ", method='" + method + '\'' + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,22 @@
|
||||
version: '3'
|
||||
services:
|
||||
httpecho:
|
||||
image: 'mhalbritter/http-echo:2'
|
||||
httpbin:
|
||||
image: 'mccutchen/go-httpbin:v2.10.0'
|
||||
ports:
|
||||
- '80'
|
||||
- '443'
|
||||
- '8080'
|
||||
httpbin_tls:
|
||||
image: 'mccutchen/go-httpbin:v2.10.0'
|
||||
environment:
|
||||
- 'PORT=8443'
|
||||
- 'HTTPS_CERT_FILE=/server-certificate'
|
||||
- 'HTTPS_KEY_FILE=/server-key'
|
||||
configs:
|
||||
- 'server-certificate'
|
||||
- 'server-key'
|
||||
ports:
|
||||
- '8443'
|
||||
configs:
|
||||
server-certificate:
|
||||
file: './server.crt'
|
||||
server-key:
|
||||
file: './server.key'
|
||||
|
||||
15
framework/webclient/server.crt
Normal file
15
framework/webclient/server.crt
Normal file
@@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICQDCCAcagAwIBAgIUJL2NEOsGlUgyKo3jUur8gol3ymowCgYIKoZIzj0EAwIw
|
||||
VjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwT
|
||||
RGVmYXVsdCBDb21wYW55IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTIzMDYy
|
||||
NjA4MzY0NFoYDzIxMjMwNjAyMDgzNjQ0WjBWMQswCQYDVQQGEwJYWDEVMBMGA1UE
|
||||
BwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMRIw
|
||||
EAYDVQQDDAlsb2NhbGhvc3QwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARm10hC6jI0
|
||||
tA5dVYyYLsaS+rDXaFDbtspX/mxHk5VTfklPD06L3sXcNJeve6YQHlOTwdUzLi2y
|
||||
iGuaVcljlA31iOtfQEATeSdbeFxxLjM22U+FZJ94j14XrbemtpspuTujUzBRMB0G
|
||||
A1UdDgQWBBQEfrPdmYvL/w5sLHWL0eVj0f1M0DAfBgNVHSMEGDAWgBQEfrPdmYvL
|
||||
/w5sLHWL0eVj0f1M0DAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA2gAMGUC
|
||||
MHtVMoEKtgkOcv2fhrv0788S/yIRa6PBt8nxMa6d7mDTFGkMhBCIG168pJk9nHE+
|
||||
vgIxAJ1JF2uB5PYV5nYwliOttnb8LMza7hhun1EVsfKuFgvMUD3VTgtZJ9PE4c8I
|
||||
pxq8IA==
|
||||
-----END CERTIFICATE-----
|
||||
9
framework/webclient/server.key
Normal file
9
framework/webclient/server.key
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN EC PARAMETERS-----
|
||||
BgUrgQQAIg==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MIGkAgEBBDCVOy3osulJ/8y+ckbBc0dAdSiLFiRcU1SFqWWsmoaCKexSBOgA8/vG
|
||||
DFFqYvummn6gBwYFK4EEACKhZANiAARm10hC6jI0tA5dVYyYLsaS+rDXaFDbtspX
|
||||
/mxHk5VTfklPD06L3sXcNJeve6YQHlOTwdUzLi2yiGuaVcljlA31iOtfQEATeSdb
|
||||
eFxxLjM22U+FZJ94j14XrbemtpspuTs=
|
||||
-----END EC PRIVATE KEY-----
|
||||
@@ -17,23 +17,26 @@ class WebClientApplicationAotTests {
|
||||
@Test
|
||||
@DisabledIfEnvironmentVariable(named = "CI", matches = "true", disabledReason = "HTTP is blocked on CI")
|
||||
void httpWorks(AssertableOutput output) {
|
||||
Awaitility.await().atMost(Duration.ofSeconds(30)).untilAsserted(() -> {
|
||||
assertThat(output).hasSingleLineContaining("https worked:");
|
||||
});
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(30))
|
||||
.untilAsserted(() -> assertThat(output)
|
||||
.hasLineMatching("http: DataDto\\{url='http:\\/\\/\\w+:\\d+\\/anything', method='GET'\\}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void httpsWorks(AssertableOutput output) {
|
||||
Awaitility.await().atMost(Duration.ofSeconds(30)).untilAsserted(() -> {
|
||||
assertThat(output).hasSingleLineContaining("https worked:");
|
||||
});
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(30))
|
||||
.untilAsserted(() -> assertThat(output)
|
||||
.hasLineMatching("https: DataDto\\{url='https:\\/\\/\\w+:\\d+\\/anything', method='GET'\\}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void serviceWorks(AssertableOutput output) {
|
||||
Awaitility.await().atMost(Duration.ofSeconds(30)).untilAsserted(() -> {
|
||||
assertThat(output).hasSingleLineContaining("service worked:");
|
||||
});
|
||||
Awaitility.await()
|
||||
.atMost(Duration.ofSeconds(30))
|
||||
.untilAsserted(() -> assertThat(output)
|
||||
.hasLineMatching("service: ExchangeDataDto\\{url='http:\\/\\/\\w+:\\d+\\/anything', method='GET'\\}"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@ package com.example.webclient;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
@Component
|
||||
@RegisterReflectionForBinding(DataDto.class)
|
||||
class CLR implements CommandLineRunner {
|
||||
|
||||
private final WebClient httpWebClient;
|
||||
@@ -32,13 +34,13 @@ class CLR implements CommandLineRunner {
|
||||
|
||||
private void http() {
|
||||
try {
|
||||
String response = this.httpWebClient.get()
|
||||
.uri("/")
|
||||
DataDto dto = this.httpWebClient.get()
|
||||
.uri("/anything")
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.bodyToMono(DataDto.class)
|
||||
.timeout(Duration.ofSeconds(10))
|
||||
.block();
|
||||
System.out.printf("http worked: %s%n", response);
|
||||
System.out.printf("http: %s%n", dto);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println("http failed:");
|
||||
@@ -48,13 +50,13 @@ class CLR implements CommandLineRunner {
|
||||
|
||||
private void https() {
|
||||
try {
|
||||
String response = this.httpsWebClient.get()
|
||||
.uri("/")
|
||||
DataDto dto = this.httpsWebClient.get()
|
||||
.uri("/anything")
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
.bodyToMono(DataDto.class)
|
||||
.timeout(Duration.ofSeconds(10))
|
||||
.block();
|
||||
System.out.printf("https worked: %s%n", response);
|
||||
System.out.printf("https: %s%n", dto);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println("https failed:");
|
||||
@@ -64,8 +66,8 @@ class CLR implements CommandLineRunner {
|
||||
|
||||
private void service() {
|
||||
try {
|
||||
String dto = this.dataService.getData();
|
||||
System.out.printf("service worked: %s%n", dto);
|
||||
ExchangeDataDto dto = this.dataService.getData();
|
||||
System.out.printf("service: %s%n", dto);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
System.out.println("service failed:");
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.example.webclient;
|
||||
|
||||
public class DataDto {
|
||||
|
||||
private String url;
|
||||
|
||||
private String method;
|
||||
|
||||
public DataDto() {
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DataDto{" + "url='" + url + '\'' + ", method='" + method + '\'' + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import org.springframework.web.service.annotation.GetExchange;
|
||||
|
||||
interface DataService {
|
||||
|
||||
@GetExchange("/")
|
||||
String getData();
|
||||
@GetExchange("/anything")
|
||||
ExchangeDataDto getData();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.example.webclient;
|
||||
|
||||
public class ExchangeDataDto {
|
||||
|
||||
private String url;
|
||||
|
||||
private String method;
|
||||
|
||||
public ExchangeDataDto() {
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ExchangeDataDto{" + "url='" + url + '\'' + ", method='" + method + '\'' + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,27 +19,26 @@ import org.springframework.web.service.invoker.HttpServiceProxyFactory;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class WebClientConfiguration {
|
||||
|
||||
@Bean
|
||||
HttpEchoConfig httpEchoConfig() {
|
||||
return HttpEchoConfig.loadFromEnv();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Qualifier("https")
|
||||
WebClient webClientHttps(HttpEchoConfig httpEchoConfig, WebClient.Builder builder) throws SSLException {
|
||||
WebClient webClientHttps(WebClient.Builder builder) throws SSLException {
|
||||
SslContext sslContext = SslContextBuilder.forClient()
|
||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||
.build();
|
||||
HttpClient httpClient = HttpClient.create().secure(t -> t.sslContext(sslContext));
|
||||
return builder.baseUrl(httpEchoConfig.httpsBaseUrl())
|
||||
String host = env("HTTPBIN_TLS_HOST", "localhost");
|
||||
int port = env("HTTPBIN_TLS_PORT_8443", 8443);
|
||||
return builder.baseUrl("https://%s:%d/".formatted(host, port))
|
||||
.clientConnector(new ReactorClientHttpConnector(httpClient))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Qualifier("http")
|
||||
WebClient webClientHttp(HttpEchoConfig httpEchoConfig, WebClient.Builder builder) {
|
||||
return builder.baseUrl(httpEchoConfig.httpBaseUrl()).build();
|
||||
WebClient webClientHttp(WebClient.Builder builder) {
|
||||
String host = env("HTTPBIN_HOST", "localhost");
|
||||
int port = env("HTTPBIN_PORT_8080", 8080);
|
||||
return builder.baseUrl("http://%s:%d/".formatted(host, port)).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -49,31 +48,14 @@ class WebClientConfiguration {
|
||||
return factory.createClient(DataService.class);
|
||||
}
|
||||
|
||||
record HttpEchoConfig(String host, int port, int tlsPort) {
|
||||
public static HttpEchoConfig loadFromEnv() {
|
||||
String host = env("HTTPECHO_HOST", "localhost");
|
||||
int port = env("HTTPECHO_PORT_80", 8080);
|
||||
int tlsPort = env("HTTPECHO_PORT_443", 8443);
|
||||
return new HttpEchoConfig(host, port, tlsPort);
|
||||
}
|
||||
private static String env(String name, String def) {
|
||||
String value = System.getenv(name);
|
||||
return StringUtils.hasLength(value) ? value : def;
|
||||
}
|
||||
|
||||
String httpsBaseUrl() {
|
||||
return "https://%s:%d/".formatted(this.host, this.tlsPort);
|
||||
}
|
||||
|
||||
String httpBaseUrl() {
|
||||
return "http://%s:%d/".formatted(this.host, this.port);
|
||||
}
|
||||
|
||||
private static String env(String name, String def) {
|
||||
String value = System.getenv(name);
|
||||
return StringUtils.hasLength(value) ? value : def;
|
||||
}
|
||||
|
||||
private static int env(String name, int def) {
|
||||
String value = System.getenv(name);
|
||||
return StringUtils.hasLength(value) ? Integer.parseInt(value) : def;
|
||||
}
|
||||
private static int env(String name, int def) {
|
||||
String value = System.getenv(name);
|
||||
return StringUtils.hasLength(value) ? Integer.parseInt(value) : def;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user