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

Commit a9e0aba

Browse files
committed
#20 headers support
1 parent 36a77d5 commit a9e0aba

File tree

6 files changed

+55
-12
lines changed

6 files changed

+55
-12
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ curl -X POST http://localhost:8888/__admin/mappings \
2424
"request": {
2525
"method": "POST",
2626
"url": "/BalanceService/getUserBalance",
27+
"headers": {"withAmount": {"matches": "\\d+\\.*\\d*"} },
2728
"bodyPatterns" : [ {
2829
"equalToJson" : { "id": "1", "currency": "EUR" }
2930
} ]
@@ -32,7 +33,7 @@ curl -X POST http://localhost:8888/__admin/mappings \
3233
"status": 200,
3334
"jsonBody": {
3435
"balance": {
35-
"amount": { "value": { "decimal" : "100.0" }, "value_present": true },
36+
"amount": { "value": { "decimal" : "{{request.headers.withAmount}}" }, "value_present": true },
3637
"currency": { "value": "EUR", "value_present": true }
3738
}
3839
}
@@ -42,7 +43,7 @@ curl -X POST http://localhost:8888/__admin/mappings \
4243

4344
3) Check
4445
```json
45-
grpcurl -plaintext -d '{"id": 1, "currency": "EUR"}' localhost:50000 api.wallet.BalanceService/getUserBalance
46+
grpcurl -H 'withAmount: 100.0' -plaintext -d '{"id": 1, "currency": "EUR"}' localhost:50000 api.wallet.BalanceService/getUserBalance
4647
```
4748

4849
Should get response:

build.gradle

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

16-
def grpcVersion = '1.40.1'
16+
def grpcVersion = '1.41.0'
17+
def wiremockVersion = '2.31.0'
1718
def protobufVersion = '3.16.0'
1819
def protocVersion = protobufVersion
1920

2021
dependencies {
2122
implementation 'org.springframework.boot:spring-boot-starter'
2223
implementation 'org.springframework.boot:spring-boot-starter-aop'
23-
implementation "io.grpc:grpc-all:${grpcVersion}"
24+
implementation "io.grpc:grpc-all:$grpcVersion"
25+
implementation "com.github.tomakehurst:wiremock-jre8-standalone:$wiremockVersion"
2426
implementation 'org.xerial.snappy:snappy-java:1.1.8.4'
25-
implementation 'com.github.tomakehurst:wiremock-jre8-standalone:2.31.0'
2627
}
2728

2829
protobuf {

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

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

33
public class BadHttpResponseException extends RuntimeException {
4-
private int statusCode;
4+
private final int statusCode;
55

66
public BadHttpResponseException(int statusCode, String errorMessage) {
77
super(errorMessage);

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Optional;
2020
import java.util.concurrent.CountDownLatch;
2121

22+
import static io.grpc.ServerInterceptors.intercept;
2223
import static java.util.stream.Collectors.joining;
2324

2425
@SpringBootApplication
@@ -62,7 +63,7 @@ public void start() throws IOException {
6263
.addService(ProtoReflectionService.newInstance());
6364

6465
setProperties(builder);
65-
services.forEach(builder::addService);
66+
services.forEach(s -> builder.addService(intercept(s, new HeaderPropagationInterceptor())));
6667
server = builder.build().start();
6768
LOG.info(summary(server));
6869
startDaemonAwaitThread();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.adven.grpc.wiremock;
2+
3+
import io.grpc.Context;
4+
import io.grpc.Contexts;
5+
import io.grpc.Metadata;
6+
import io.grpc.ServerCall;
7+
import io.grpc.ServerCallHandler;
8+
import io.grpc.ServerInterceptor;
9+
10+
import java.util.Map;
11+
12+
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
13+
import static io.grpc.Metadata.Key.of;
14+
import static java.util.function.Function.identity;
15+
import static java.util.stream.Collectors.toMap;
16+
17+
public class HeaderPropagationInterceptor implements ServerInterceptor {
18+
public static final Context.Key<Map<String, String>> HEADERS = Context.key("GRPC_WIREMOCK_HEADERS");
19+
20+
@Override
21+
public <Req, Resp> ServerCall.Listener<Req> interceptCall(ServerCall<Req, Resp> call, final Metadata headers, ServerCallHandler<Req, Resp> next) {
22+
return Contexts.interceptCall(
23+
Context.current().withValue(HEADERS, asMap(headers)),
24+
call,
25+
headers,
26+
next
27+
);
28+
}
29+
30+
private Map<String, String> asMap(Metadata headers) {
31+
return headers.keys().stream().collect(toMap(identity(), k -> headers.get(of(k, ASCII_STRING_MARSHALLER))));
32+
}
33+
}

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

+11-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import java.net.http.HttpRequest;
2121
import java.net.http.HttpResponse;
2222
import java.util.Map;
23+
import java.util.stream.Stream;
24+
25+
import static io.adven.grpc.wiremock.HeaderPropagationInterceptor.HEADERS;
2326

2427
@Component
2528
public class HttpMock {
@@ -73,13 +76,17 @@ public void destroy() {
7376
}
7477

7578
public Message send(Object message, String path, Class<?> aClass) throws IOException, InterruptedException {
76-
return ProtoJsonUtil.fromJson(request(path, message).body(), aClass);
79+
return ProtoJsonUtil.fromJson(request(path, message, HEADERS.get()).body(), aClass);
7780
}
7881

79-
private HttpResponse<String> request(String path, Object message) throws IOException, InterruptedException {
80-
LOG.info("Grpc request {}:\n{}", path, message);
82+
private HttpResponse<String> request(String path, Object message, Map<String, String> headers) throws IOException, InterruptedException {
83+
LOG.info("Grpc request {}:\nHeaders: {}\nMessage:\n{}", path, headers, message);
8184
final HttpResponse<String> response = httpClient.send(
82-
HttpRequest.newBuilder().uri(URI.create(server.baseUrl() + "/" + path)).POST(asJson(message)).build(),
85+
HttpRequest.newBuilder()
86+
.uri(URI.create(server.baseUrl() + "/" + path))
87+
.POST(asJson(message))
88+
.headers(headers.entrySet().stream().flatMap(e -> Stream.of(e.getKey(), e.getValue())).toArray(String[]::new))
89+
.build(),
8390
HttpResponse.BodyHandlers.ofString()
8491
);
8592
if (response.statusCode() != 200) {

0 commit comments

Comments
 (0)