Skip to content
This repository was archived by the owner on Sep 22, 2022. It is now read-only.

Commit 24a0388

Browse files
committed
#21 Allow to configure http and grpc ports
1 parent 56b5c18 commit 24a0388

10 files changed

+163
-125
lines changed

README.md

+17-9
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,33 @@ docker run \
110110
```
111111
## How To:
112112

113-
#### 1. Change grpc server properties
113+
#### 1. Configuring gRPC server
114114

115-
Currently, following grpc server properties are supported<sup>*</sup>:
115+
Currently, following grpc server properties are supported:
116116

117117
```properties
118+
GRPC_SERVER_PORT
118119
GRPC_SERVER_MAXHEADERLISTSIZE
119120
GRPC_SERVER_MAXMESSAGESIZE
120121
GRPC_SERVER_MAXINBOUNDMETADATASIZE
121122
GRPC_SERVER_MAXINBOUNDMESSAGESIZE
122123
```
123-
<sub>*The first two are deprecated in favor of the last two</sub>
124124

125125
Could be used like this:
126126

127127
```posh
128128
docker run -e GRPC_SERVER_MAXHEADERLISTSIZE=1000 adven27/grpc-wiremock
129129
```
130130

131+
### 3. Configuring WireMock server
132+
133+
WireMock server may be configured by passing [command line options](http://wiremock.org/docs/running-standalone/)
134+
prefixed by `wiremock_`:
135+
136+
```posh
137+
docker run -e WIREMOCK_DISABLE-REQUEST-LOGGING -e WIREMOCK_PORT=0 adven27/grpc-wiremock
138+
```
139+
131140
#### 2. Speed up container start
132141

133142
In case you don't need to change proto files, you can build your own image with precompiled protos.
@@ -162,10 +171,9 @@ docker run -e SPRING_PROFILES_ACTIVE=load adven27/grpc-wiremock
162171
```
163172
```posh
164173
docker run \
165-
-e WIREMOCK_SERVER_DISABLEREQUESTJOURNAL=true \
166-
-e WIREMOCK_SERVER_ASYNCHRONOUSRESPONSEENABLED=true \
167-
-e WIREMOCK_SERVER_ASYNCHRONOUSRESPONSETHREADS=10 \
168-
-e WIREMOCK_SERVER_STUBREQUESTLOGGINGDISABLED=true \
169-
-e WIREMOCK_SERVER_VERBOSE=false \
170-
adven27/grpc-wiremock
174+
-e WIREMOCK_NO-REQUEST-JOURNAL \
175+
-e WIREMOCK_DISABLE-REQUEST-LOGGING \
176+
-e WIREMOCK_ASYNC-RESPONSE-ENABLED \
177+
-e WIREMOCK_ASYNC-RESPONSE-THREADS=10 \
178+
adven27/grpc-wiremock
171179
```

build.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plugins {
2-
id 'org.springframework.boot' version '2.4.5'
2+
id 'org.springframework.boot' version '2.5.4'
33
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
44
id 'java'
55
id 'com.google.protobuf' version '0.8.16'
@@ -13,7 +13,7 @@ repositories {
1313
mavenCentral()
1414
}
1515

16-
def grpcVersion = '1.37.0'
16+
def grpcVersion = '1.40.1'
1717
def protobufVersion = '3.16.0'
1818
def protocVersion = protobufVersion
1919

@@ -22,7 +22,7 @@ dependencies {
2222
implementation 'org.springframework.boot:spring-boot-starter-aop'
2323
implementation "io.grpc:grpc-all:${grpcVersion}"
2424
implementation 'org.xerial.snappy:snappy-java:1.1.8.4'
25-
implementation 'com.github.tomakehurst:wiremock-jre8-standalone:2.30.1'
25+
implementation 'com.github.tomakehurst:wiremock-jre8-standalone:2.31.0'
2626
}
2727

2828
protobuf {

src/main/java/io/adven/grpc/wiremock/GrpcWiremock.java

+28-29
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.adven.grpc.wiremock;
22

33
import io.adven.grpc.wiremock.properties.GrpcProperties;
4-
import io.adven.grpc.wiremock.properties.WiremockProperties;
54
import io.grpc.BindableService;
65
import io.grpc.Server;
76
import io.grpc.netty.NettyServerBuilder;
@@ -23,18 +22,21 @@
2322
import static java.util.stream.Collectors.joining;
2423

2524
@SpringBootApplication
26-
@EnableConfigurationProperties({GrpcProperties.class, WiremockProperties.class})
25+
@EnableConfigurationProperties({GrpcProperties.class})
2726
public class GrpcWiremock implements CommandLineRunner {
2827
private static final Logger LOG = LoggerFactory.getLogger(GrpcWiremock.class);
2928
private final GrpcServer server;
29+
private final HttpMock httpMock;
3030

31-
public GrpcWiremock(GrpcServer server) {
31+
public GrpcWiremock(GrpcServer server, HttpMock httpMock) {
3232
this.server = server;
33+
this.httpMock = httpMock;
3334
}
3435

3536
@Override
3637
public void run(String... args) throws Exception {
37-
server.start(50000);
38+
httpMock.start();
39+
server.start();
3840
}
3941

4042
@Service
@@ -52,8 +54,8 @@ public GrpcServer(GrpcProperties grpcProperties, CodecRegistry codecRegistry, Li
5254
this.latch = new CountDownLatch(1);
5355
}
5456

55-
public void start(int port) throws IOException {
56-
NettyServerBuilder builder = NettyServerBuilder.forPort(port)
57+
public void start() throws IOException {
58+
NettyServerBuilder builder = NettyServerBuilder.forPort(grpcProperties.getServer().getPort())
5759
.intercept(new ExceptionHandler(grpcProperties.getErrorCodeBy()))
5860
.compressorRegistry(codecRegistry.compressorRegistry())
5961
.decompressorRegistry(codecRegistry.decompressorRegistry())
@@ -68,32 +70,30 @@ public void start(int port) throws IOException {
6870

6971
private void setProperties(NettyServerBuilder builder) {
7072
GrpcProperties.ServerProperties server = grpcProperties.getServer();
71-
if (server != null) {
72-
if (server.getMaxHeaderListSize() != null) {
73-
int val = Math.toIntExact(server.getMaxHeaderListSize().toBytes());
74-
LOG.info("Set maxHeaderListSize = {}", val);
75-
builder.maxHeaderListSize(val);
76-
}
77-
if (server.getMaxMessageSize() != null) {
78-
int val = Math.toIntExact(server.getMaxMessageSize().toBytes());
79-
LOG.info("Set maxMessageSize = {}", val);
80-
builder.maxMessageSize(val);
81-
}
82-
if (server.getMaxInboundMetadataSize() != null) {
83-
int val = Math.toIntExact(server.getMaxInboundMetadataSize().toBytes());
84-
LOG.info("Set maxInboundMetadataSize = {}", val);
85-
builder.maxInboundMetadataSize(val);
86-
}
87-
if (server.getMaxInboundMessageSize() != null) {
88-
int val = Math.toIntExact(server.getMaxInboundMessageSize().toBytes());
89-
LOG.info("Set maxInboundMessageSize = {}", val);
90-
builder.maxInboundMessageSize(val);
91-
}
73+
if (server.getMaxHeaderListSize() != null) {
74+
int val = Math.toIntExact(server.getMaxHeaderListSize().toBytes());
75+
LOG.info("Set maxHeaderListSize = {}", val);
76+
builder.maxHeaderListSize(val);
77+
}
78+
if (server.getMaxMessageSize() != null) {
79+
int val = Math.toIntExact(server.getMaxMessageSize().toBytes());
80+
LOG.info("Set maxMessageSize = {}", val);
81+
builder.maxMessageSize(val);
82+
}
83+
if (server.getMaxInboundMetadataSize() != null) {
84+
int val = Math.toIntExact(server.getMaxInboundMetadataSize().toBytes());
85+
LOG.info("Set maxInboundMetadataSize = {}", val);
86+
builder.maxInboundMetadataSize(val);
87+
}
88+
if (server.getMaxInboundMessageSize() != null) {
89+
int val = Math.toIntExact(server.getMaxInboundMessageSize().toBytes());
90+
LOG.info("Set maxInboundMessageSize = {}", val);
91+
builder.maxInboundMessageSize(val);
9292
}
9393
}
9494

9595
private String summary(Server server) {
96-
return "Started " + server + "\nRegistered services:\n" +
96+
return "gRPC server is started: " + server + "\nRegistered services:\n" +
9797
server.getServices().stream().map(s -> " * " + s.getServiceDescriptor().getName()).collect(joining("\n"));
9898
}
9999

@@ -124,7 +124,6 @@ public void destroy() {
124124
}
125125
LOG.info("gRPC server stopped.");
126126
});
127-
128127
}
129128
}
130129

src/main/java/io/adven/grpc/wiremock/HttpMock.java

+39-25
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,70 @@
11
package io.adven.grpc.wiremock;
22

33
import com.github.tomakehurst.wiremock.WireMockServer;
4-
import com.github.tomakehurst.wiremock.common.Slf4jNotifier;
5-
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
6-
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
4+
import com.github.tomakehurst.wiremock.standalone.CommandLineOptions;
75
import com.google.protobuf.AbstractMessage;
86
import com.google.protobuf.InvalidProtocolBufferException;
97
import com.google.protobuf.Message;
108
import com.google.protobuf.MessageOrBuilder;
119
import com.google.protobuf.util.JsonFormat;
12-
import io.adven.grpc.wiremock.properties.WiremockProperties;
10+
import io.adven.grpc.wiremock.configurer.WiremockConfigurer;
1311
import org.slf4j.Logger;
1412
import org.slf4j.LoggerFactory;
1513
import org.springframework.stereotype.Component;
1614

17-
import javax.annotation.PostConstruct;
1815
import javax.annotation.PreDestroy;
1916
import java.io.IOException;
2017
import java.lang.reflect.InvocationTargetException;
2118
import java.net.URI;
2219
import java.net.http.HttpClient;
2320
import java.net.http.HttpRequest;
2421
import java.net.http.HttpResponse;
25-
26-
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
22+
import java.util.Map;
2723

2824
@Component
2925
public class HttpMock {
3026
private static final Logger LOG = LoggerFactory.getLogger(HttpMock.class);
31-
private final WireMockServer server;
32-
private final HttpClient httpClient;
27+
private static final String PREFIX = "wiremock_";
28+
private final WiremockConfigurer configurer;
29+
private WireMockServer server;
30+
private final HttpClient httpClient = HttpClient.newHttpClient();
31+
32+
public HttpMock(WiremockConfigurer configurer) {
33+
this.configurer = configurer;
34+
}
3335

34-
public HttpMock(WiremockProperties properties) {
35-
WireMockConfiguration config = wireMockConfig()
36-
.usingFilesUnderDirectory("/wiremock")
37-
.extensions(new ResponseTemplateTransformer(true))
38-
.port(8888)
39-
.notifier(new Slf4jNotifier(properties.isVerbose()))
40-
.stubRequestLoggingDisabled(properties.isStubRequestLoggingDisabled())
41-
.asynchronousResponseEnabled(properties.isAsynchronousResponseEnabled())
42-
.asynchronousResponseThreads(properties.getAsynchronousResponseThreads());
36+
public void start() {
37+
String[] args = configurer.configure(envOptions());
38+
LOG.info("Starting WireMock server with options:\n{}", String.join("\n", args));
39+
CommandLineOptions options = new CommandLineOptions(args);
40+
server = new WireMockServer(options);
41+
server.start();
42+
LOG.info("WireMock server is started:\n{}", setActualPort(options));
43+
}
4344

44-
if (properties.isDisableRequestJournal()) {
45-
config.disableRequestJournal();
45+
private CommandLineOptions setActualPort(CommandLineOptions options) {
46+
if (!options.getHttpDisabled()) {
47+
options.setActualHttpPort(server.port());
48+
}
49+
if (options.httpsSettings().enabled()) {
50+
options.setActualHttpsPort(server.httpsPort());
4651
}
47-
server = new WireMockServer(config);
48-
httpClient = HttpClient.newHttpClient();
52+
return options;
4953
}
5054

51-
@PostConstruct
52-
public void init() {
53-
server.start();
55+
private String[] envOptions() {
56+
return System.getenv().entrySet().stream()
57+
.filter(it -> it.getKey().toLowerCase().startsWith(PREFIX))
58+
.map(this::toWiremockOption)
59+
.toArray(String[]::new);
60+
}
61+
62+
private String toWiremockOption(Map.Entry<String, String> it) {
63+
return "--" + it.getKey().toLowerCase().substring(PREFIX.length()) + (nullOrEmpty(it.getValue()) ? "" : "=" + it.getValue());
64+
}
65+
66+
private boolean nullOrEmpty(String value) {
67+
return value == null || value.equals("");
5468
}
5569

5670
@PreDestroy
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.adven.grpc.wiremock.configurer;
2+
3+
import org.springframework.context.annotation.Profile;
4+
import org.springframework.stereotype.Component;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
import static java.util.Arrays.asList;
10+
11+
@Profile("!load")
12+
@Component
13+
public class DefaultWiremockConfigurer implements WiremockConfigurer {
14+
private static final String GLOBAL_RESPONSE_TEMPLATING = "--global-response-templating";
15+
private static final String LOCAL_RESPONSE_TEMPLATING = "--local-response-templating";
16+
private static final String ROOT_DIR = "--root-dir";
17+
private static final String PORT = "--port";
18+
19+
@Override
20+
public String[] configure(String... args) {
21+
List<String> options = new ArrayList<>(asList(args));
22+
if (options.stream().noneMatch(it -> it.equals(GLOBAL_RESPONSE_TEMPLATING) || it.equals(LOCAL_RESPONSE_TEMPLATING))) {
23+
options.add(GLOBAL_RESPONSE_TEMPLATING);
24+
}
25+
if (options.stream().noneMatch(it -> it.startsWith(ROOT_DIR))) {
26+
options.add(ROOT_DIR + "=/wiremock");
27+
}
28+
if (options.stream().noneMatch(it -> it.startsWith(PORT))) {
29+
options.add(PORT + "=8888");
30+
}
31+
return options.toArray(new String[0]);
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.adven.grpc.wiremock.configurer;
2+
3+
import org.springframework.context.annotation.Profile;
4+
import org.springframework.stereotype.Component;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
import static java.util.Arrays.asList;
10+
11+
@Profile("load")
12+
@Component
13+
public class LoadWiremockConfigurer extends DefaultWiremockConfigurer {
14+
private static final String DISABLE_REQUEST_LOGGING = "--disable-request-logging";
15+
private static final String DISABLE_REQUEST_JOURNAL = "--no-request-journal";
16+
private static final String ASYNCHRONOUS_RESPONSE_ENABLED = "--async-response-enabled";
17+
private static final String ASYNCHRONOUS_RESPONSE_THREADS = "--async-response-threads";
18+
19+
@Override
20+
public String[] configure(String... args) {
21+
List<String> options = new ArrayList<>(asList(super.configure(args)));
22+
options.add(DISABLE_REQUEST_LOGGING);
23+
options.add(DISABLE_REQUEST_JOURNAL);
24+
options.add(ASYNCHRONOUS_RESPONSE_ENABLED);
25+
options.add(ASYNCHRONOUS_RESPONSE_THREADS + "=10");
26+
return options.toArray(new String[0]);
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package io.adven.grpc.wiremock.configurer;
2+
3+
public interface WiremockConfigurer {
4+
String[] configure(String... args);
5+
}

src/main/java/io/adven/grpc/wiremock/properties/GrpcProperties.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,24 @@ public ErrorCodeMapping getErrorCodeBy() {
2626
}
2727

2828
public static class ServerProperties {
29+
private final Integer port;
2930
private final DataSize maxHeaderListSize;
3031
private final DataSize maxMessageSize;
3132
private final DataSize maxInboundMetadataSize;
3233
private final DataSize maxInboundMessageSize;
3334

34-
public ServerProperties(DataSize maxHeaderListSize, DataSize maxMessageSize, DataSize maxInboundMetadataSize, DataSize maxInboundMessageSize) {
35+
public ServerProperties(Integer port, DataSize maxHeaderListSize, DataSize maxMessageSize, DataSize maxInboundMetadataSize, DataSize maxInboundMessageSize) {
36+
this.port = port;
3537
this.maxHeaderListSize = maxHeaderListSize;
3638
this.maxMessageSize = maxMessageSize;
3739
this.maxInboundMetadataSize = maxInboundMetadataSize;
3840
this.maxInboundMessageSize = maxInboundMessageSize;
3941
}
4042

43+
public Integer getPort() {
44+
return port;
45+
}
46+
4147
public DataSize getMaxHeaderListSize() {
4248
return maxHeaderListSize;
4349
}

0 commit comments

Comments
 (0)