Skip to content

Commit c1d514d

Browse files
authored
Merge pull request #64 from wiremock/feature/issue-62-https-and-http
feat: HTTP and HTTPS in same mock (refs #62)
2 parents 9a1684b + 6806588 commit c1d514d

File tree

7 files changed

+407
-155
lines changed

7 files changed

+407
-155
lines changed

src/main/java/org/wiremock/spring/ConfigureWireMock.java

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,24 @@
1515
public @interface ConfigureWireMock {
1616

1717
/**
18-
* Port on which WireMock server is going to listen. {@code 0} means WireMock will pick random
19-
* port.
18+
* Port on which WireMock server is going to listen.
19+
*
20+
* <p>{@code -1} means disabled.
21+
*
22+
* <p>{@code 0} means WireMock will pick random available port.
23+
*
24+
* <p>{@code >0} means that static port will be used.
2025
*
2126
* @return WireMock server port
2227
*/
2328
int port() default 0;
2429

2530
/**
26-
* @return true for HTTPS, else false.
31+
* Same as {@link #port()} but for HTTPS.
32+
*
33+
* @return HTTPS port to use.
2734
*/
28-
boolean useHttps() default false;
35+
int httpsPort() default -1;
2936

3037
/**
3138
* The name of WireMock server.
@@ -49,13 +56,27 @@
4956
*/
5057
String[] portProperties() default {"wiremock.server.port"};
5158

59+
/**
60+
* Names of Spring properties to inject the {@link WireMockServer#httpsPort()}
61+
*
62+
* @return names of Spring properties to inject the {@link WireMockServer#httpsPort()}
63+
*/
64+
String[] httpsPortProperties() default {"wiremock.server.httpsPort"};
65+
5266
/**
5367
* Names of Spring properties to inject the {@link WireMockServer#baseUrl()}.
5468
*
5569
* @return names of Spring properties to inject the {@link WireMockServer#baseUrl()}.
5670
*/
5771
String[] baseUrlProperties() default {"wiremock.server.baseUrl"};
5872

73+
/**
74+
* Names of Spring properties to inject the {@link WireMockServer#baseUrl()}.
75+
*
76+
* @return names of Spring properties to inject the {@link WireMockServer#baseUrl()}.
77+
*/
78+
String[] httpsBaseUrlProperties() default {"wiremock.server.httpsBaseUrl"};
79+
5980
/**
6081
* Classpaths to pass to {@link WireMockConfiguration#usingFilesUnderClasspath(String)}. First one
6182
* that is found will be used. If a {@link #name()} is supplied, it will first look for {@link

src/main/java/org/wiremock/spring/internal/WireMockContextCustomizerFactory.java

Lines changed: 103 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.List;
77
import java.util.Set;
88
import java.util.stream.Collectors;
9+
910
import org.springframework.core.annotation.AnnotationUtils;
1011
import org.springframework.test.context.ContextConfigurationAttributes;
1112
import org.springframework.test.context.ContextCustomizer;
@@ -15,80 +16,110 @@
1516
import org.wiremock.spring.EnableWireMock;
1617

1718
/**
18-
* Creates {@link WireMockContextCustomizer} for test classes annotated with {@link EnableWireMock}.
19+
* Creates {@link WireMockContextCustomizer} for test classes annotated with
20+
* {@link EnableWireMock}.
1921
*
2022
* @author Maciej Walkowiak
2123
*/
2224
public class WireMockContextCustomizerFactory implements ContextCustomizerFactory {
23-
static final ConfigureWireMock DEFAULT_CONFIGURE_WIREMOCK =
24-
DefaultConfigureWireMock.class.getAnnotation(ConfigureWireMock.class);
25-
26-
@ConfigureWireMock(name = "wiremock")
27-
private static class DefaultConfigureWireMock {}
28-
29-
static ConfigureWireMock[] getConfigureWireMocksOrDefault(
30-
final ConfigureWireMock... configureWireMock) {
31-
if (configureWireMock == null || configureWireMock.length == 0) {
32-
return new ConfigureWireMock[] {WireMockContextCustomizerFactory.DEFAULT_CONFIGURE_WIREMOCK};
33-
}
34-
return configureWireMock;
35-
}
36-
37-
@Override
38-
public ContextCustomizer createContextCustomizer(
39-
final Class<?> testClass, final List<ContextConfigurationAttributes> configAttributes) {
40-
// scan class and all enclosing classes if the test class is @Nested
41-
final ConfigureWiremockHolder holder = new ConfigureWiremockHolder();
42-
this.parseDefinitions(testClass, holder);
43-
44-
if (holder.isEmpty()) {
45-
return null;
46-
} else {
47-
return new WireMockContextCustomizer(holder.asArray());
48-
}
49-
}
50-
51-
private void parseDefinitions(final Class<?> testClass, final ConfigureWiremockHolder parser) {
52-
parser.parse(testClass);
53-
if (TestContextAnnotationUtils.searchEnclosingClass(testClass)) {
54-
this.parseDefinitions(testClass.getEnclosingClass(), parser);
55-
}
56-
}
57-
58-
private static class ConfigureWiremockHolder {
59-
private final List<ConfigureWireMock> annotations = new ArrayList<>();
60-
61-
void add(final ConfigureWireMock... annotations) {
62-
this.annotations.addAll(Arrays.asList(annotations));
63-
this.sanityCheckDuplicateNames(this.annotations);
64-
}
65-
66-
void parse(final Class<?> clazz) {
67-
final EnableWireMock annotation = AnnotationUtils.findAnnotation(clazz, EnableWireMock.class);
68-
if (annotation != null) {
69-
this.add(getConfigureWireMocksOrDefault(annotation.value()));
70-
}
71-
}
72-
73-
private void sanityCheckDuplicateNames(final List<ConfigureWireMock> check) {
74-
final List<String> names = check.stream().map(it -> it.name()).toList();
75-
final Set<String> dublicateNames =
76-
names.stream()
77-
.filter(it -> Collections.frequency(names, it) > 1)
78-
.collect(Collectors.toSet());
79-
if (!dublicateNames.isEmpty()) {
80-
throw new IllegalStateException(
81-
"Names of mocks must be unique, found duplicates of: "
82-
+ dublicateNames.stream().sorted().collect(Collectors.joining(",")));
83-
}
84-
}
85-
86-
boolean isEmpty() {
87-
return this.annotations.isEmpty();
88-
}
89-
90-
ConfigureWireMock[] asArray() {
91-
return this.annotations.toArray(new ConfigureWireMock[] {});
92-
}
93-
}
25+
static final ConfigureWireMock DEFAULT_CONFIGURE_WIREMOCK = DefaultConfigureWireMock.class
26+
.getAnnotation(ConfigureWireMock.class);
27+
28+
@ConfigureWireMock(name = "wiremock")
29+
private static class DefaultConfigureWireMock {
30+
}
31+
32+
static ConfigureWireMock[] getConfigureWireMocksOrDefault(final ConfigureWireMock... configureWireMock) {
33+
if (configureWireMock == null || configureWireMock.length == 0) {
34+
return new ConfigureWireMock[] { WireMockContextCustomizerFactory.DEFAULT_CONFIGURE_WIREMOCK };
35+
}
36+
return configureWireMock;
37+
}
38+
39+
@Override
40+
public ContextCustomizer createContextCustomizer(final Class<?> testClass,
41+
final List<ContextConfigurationAttributes> configAttributes) {
42+
// scan class and all enclosing classes if the test class is @Nested
43+
final ConfigureWiremockHolder holder = new ConfigureWiremockHolder();
44+
this.parseDefinitions(testClass, holder);
45+
46+
if (holder.isEmpty()) {
47+
return null;
48+
} else {
49+
return new WireMockContextCustomizer(holder.asArray());
50+
}
51+
}
52+
53+
private void parseDefinitions(final Class<?> testClass, final ConfigureWiremockHolder parser) {
54+
parser.parse(testClass);
55+
if (TestContextAnnotationUtils.searchEnclosingClass(testClass)) {
56+
this.parseDefinitions(testClass.getEnclosingClass(), parser);
57+
}
58+
}
59+
60+
private static class ConfigureWiremockHolder {
61+
private final List<ConfigureWireMock> annotations = new ArrayList<>();
62+
63+
void add(final ConfigureWireMock... annotations) {
64+
this.annotations.addAll(Arrays.asList(annotations));
65+
this.sanityCheckDuplicateNames(this.annotations);
66+
this.sanityCheckHttpOrHttpsMustBeEnabled(this.annotations);
67+
this.sanityCheckHttpAndHttpsMustUseDifferentPorts(this.annotations);
68+
this.sanityCheckUniquePorts(this.annotations);
69+
}
70+
71+
void parse(final Class<?> clazz) {
72+
final EnableWireMock annotation = AnnotationUtils.findAnnotation(clazz, EnableWireMock.class);
73+
if (annotation != null) {
74+
this.add(getConfigureWireMocksOrDefault(annotation.value()));
75+
}
76+
}
77+
78+
private void sanityCheckDuplicateNames(final List<ConfigureWireMock> check) {
79+
final List<String> names = check.stream().map(it -> it.name()).toList();
80+
final Set<String> dublicateNames = names.stream().filter(it -> Collections.frequency(names, it) > 1)
81+
.collect(Collectors.toSet());
82+
if (!dublicateNames.isEmpty()) {
83+
throw new IllegalStateException("Names of mocks must be unique, found duplicates of: "
84+
+ dublicateNames.stream().sorted().collect(Collectors.joining(",")));
85+
}
86+
}
87+
88+
private void sanityCheckHttpOrHttpsMustBeEnabled(final List<ConfigureWireMock> check) {
89+
for (final ConfigureWireMock configureWireMock : check) {
90+
if (configureWireMock.port() == -1 && configureWireMock.httpsPort() == -1) {
91+
throw new IllegalStateException("ConfigureWireMock " + configureWireMock.name()
92+
+ " has both HTTP and HTTPS disabled. It is an invalid configuration.");
93+
}
94+
}
95+
}
96+
97+
private void sanityCheckUniquePorts(final List<ConfigureWireMock> check) {
98+
final List<Integer> ports = check.stream().map(it -> List.of(it.port(), it.httpsPort())).toList().stream()
99+
.collect(ArrayList::new, List::addAll, List::addAll);
100+
final Set<Integer> dublicatePors = ports.stream().filter(it -> it > 0)
101+
.filter(it -> Collections.frequency(ports, it) > 1).collect(Collectors.toSet());
102+
if (!dublicatePors.isEmpty()) {
103+
throw new IllegalStateException("Some statically configured ports are being used mor than once: "
104+
+ dublicatePors.stream().sorted().map(it -> it.toString()).collect(Collectors.joining(",")));
105+
}
106+
}
107+
108+
private void sanityCheckHttpAndHttpsMustUseDifferentPorts(final List<ConfigureWireMock> check) {
109+
for (final ConfigureWireMock configureWireMock : check) {
110+
if (configureWireMock.port() > 0 && configureWireMock.port() == configureWireMock.httpsPort()) {
111+
throw new IllegalStateException("ConfigureWireMock " + configureWireMock.name() + " uses same port "
112+
+ configureWireMock.port() + " for HTTP and HTTPS.");
113+
}
114+
}
115+
}
116+
117+
boolean isEmpty() {
118+
return this.annotations.isEmpty();
119+
}
120+
121+
ConfigureWireMock[] asArray() {
122+
return this.annotations.toArray(new ConfigureWireMock[] {});
123+
}
124+
}
94125
}

0 commit comments

Comments
 (0)