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

Commit 9c5175b

Browse files
authored
Merge pull request #10 from dtuchs/master
Added support for snappy compression / decompression
2 parents 0fb3cb8 + 987bead commit 9c5175b

File tree

6 files changed

+108
-9
lines changed

6 files changed

+108
-9
lines changed

README.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,27 @@ docker run -e GRPC_SERVER_MAXHEADERLISTSIZE=1000 adven27/grpc-wiremock
9090
In case you don't need to change proto files, you can build your own image with precompiled protos.
9191
See an [example](/example/Dockerfile)
9292

93-
#### 3. Use in load testing
93+
#### 3. Use with snappy compresser/decompresser
94+
95+
Snappy support can be enabled using EXT_CODECS env variable as follows:
96+
```posh
97+
docker run -e EXT_CODECS=snappy adven27/grpc-wiremock
98+
```
99+
Also in docker-compose:
100+
```posh
101+
image: adven27/grpc-wiremock
102+
ports:
103+
- "12085:50000" # grpc port
104+
- "8088:8888" # http serve port
105+
volumes:
106+
- ./example/proto:/proto
107+
environment:
108+
- EXT_CODECS=snappy
109+
```
110+
<sub>*gzip compression supported by default</sub>
111+
112+
113+
#### 4. Use in load testing
94114

95115
To increase performance some Wiremock related options may be tuned either directly or by enabling the "load" profile.
96116
Next two commands are identical:

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dependencies {
2121
implementation 'org.springframework.boot:spring-boot-starter'
2222
implementation 'org.springframework.boot:spring-boot-starter-aop'
2323
implementation "io.grpc:grpc-all:${grpcVersion}"
24+
implementation 'org.xerial.snappy:snappy-java:1.1.8.4'
2425
implementation 'com.github.tomakehurst:wiremock-standalone:2.27.2'
2526
}
2627

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package io.adven.grpc.wiremock;
2+
3+
import io.grpc.Codec;
4+
import io.grpc.CompressorRegistry;
5+
import io.grpc.DecompressorRegistry;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.context.annotation.PropertySource;
8+
import org.springframework.stereotype.Component;
9+
10+
import java.util.List;
11+
import java.util.Map;
12+
13+
@Component
14+
@PropertySource("classpath:application.properties")
15+
public class CodecRegistry {
16+
17+
@Value("#{'${external.codecs}'.split(',')}")
18+
private List<String> externalCodecs;
19+
private Map<String, Codec> codecs;
20+
21+
public CodecRegistry(Map<String, Codec> codecs) {
22+
this.codecs = codecs;
23+
}
24+
25+
public CompressorRegistry compressorRegistry() {
26+
CompressorRegistry compressorRegistry = CompressorRegistry.getDefaultInstance();
27+
for (String codec : externalCodecs) {
28+
Codec codecImpl = codecs.get(codec);
29+
if (codecImpl != null) {
30+
compressorRegistry.register(codecs.get(codec));
31+
}
32+
}
33+
return compressorRegistry;
34+
}
35+
36+
public DecompressorRegistry decompressorRegistry() {
37+
DecompressorRegistry decompressorRegistry = DecompressorRegistry.getDefaultInstance();
38+
for (String codec : externalCodecs) {
39+
Codec codecImpl = codecs.get(codec);
40+
if (codecImpl != null) {
41+
decompressorRegistry = decompressorRegistry.with(codecs.get(codec), true);
42+
}
43+
}
44+
return decompressorRegistry;
45+
}
46+
}

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

+10-7
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,24 @@ public static class GrpcServer {
4040
private final ServerProperties serverProperties;
4141
private final List<BindableService> services;
4242
private Server server;
43+
private CodecRegistry codecRegistry;
4344
private final CountDownLatch latch;
4445

45-
public GrpcServer(ServerProperties serverProperties, List<BindableService> services) {
46+
public GrpcServer(ServerProperties serverProperties, CodecRegistry codecRegistry, List<BindableService> services) {
4647
this.serverProperties = serverProperties;
48+
this.codecRegistry = codecRegistry;
4749
this.services = services;
4850
this.latch = new CountDownLatch(1);
4951
}
5052

5153
public void start(int port) throws IOException {
5254
NettyServerBuilder builder = NettyServerBuilder.forPort(port)
5355
.intercept(new ExceptionHandler())
56+
.compressorRegistry(codecRegistry.compressorRegistry())
57+
.decompressorRegistry(codecRegistry.decompressorRegistry())
5458
.addService(ProtoReflectionService.newInstance());
5559

5660
setProperties(builder);
57-
5861
services.forEach(builder::addService);
5962
server = builder.build().start();
6063
LOG.info(summary(server));
@@ -64,29 +67,29 @@ public void start(int port) throws IOException {
6467
private void setProperties(NettyServerBuilder builder) {
6568
if (serverProperties.getMaxHeaderListSize() != null) {
6669
int val = Math.toIntExact(serverProperties.getMaxHeaderListSize().toBytes());
67-
LOG.info("Set maxHeaderListSize = {}" , val);
70+
LOG.info("Set maxHeaderListSize = {}", val);
6871
builder.maxHeaderListSize(val);
6972
}
7073
if (serverProperties.getMaxMessageSize() != null) {
7174
int val = Math.toIntExact(serverProperties.getMaxMessageSize().toBytes());
72-
LOG.info("Set maxMessageSize = {}" , val);
75+
LOG.info("Set maxMessageSize = {}", val);
7376
builder.maxMessageSize(val);
7477
}
7578
if (serverProperties.getMaxInboundMetadataSize() != null) {
7679
int val = Math.toIntExact(serverProperties.getMaxInboundMetadataSize().toBytes());
77-
LOG.info("Set maxInboundMetadataSize = {}" , val);
80+
LOG.info("Set maxInboundMetadataSize = {}", val);
7881
builder.maxInboundMetadataSize(val);
7982
}
8083
if (serverProperties.getMaxInboundMessageSize() != null) {
8184
int val = Math.toIntExact(serverProperties.getMaxInboundMessageSize().toBytes());
82-
LOG.info("Set maxInboundMessageSize = {}" , val);
85+
LOG.info("Set maxInboundMessageSize = {}", val);
8386
builder.maxInboundMessageSize(val);
8487
}
8588
}
8689

8790
private String summary(Server server) {
8891
return "Started " + server + "\nRegistered services:\n" +
89-
server.getServices().stream().map(s -> " * " + s.getServiceDescriptor().getName()).collect(joining("\n"));
92+
server.getServices().stream().map(s -> " * " + s.getServiceDescriptor().getName()).collect(joining("\n"));
9093
}
9194

9295
private void startDaemonAwaitThread() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.adven.grpc.wiremock.codec;
2+
3+
import io.grpc.Codec;
4+
import org.springframework.stereotype.Component;
5+
import org.xerial.snappy.SnappyFramedInputStream;
6+
import org.xerial.snappy.SnappyFramedOutputStream;
7+
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.io.OutputStream;
11+
12+
@Component("snappy")
13+
public class SnappyCodec implements Codec {
14+
@Override
15+
public String getMessageEncoding() {
16+
return "snappy";
17+
}
18+
19+
@Override
20+
public InputStream decompress(InputStream is) throws IOException {
21+
return new SnappyFramedInputStream(is);
22+
}
23+
24+
@Override
25+
public OutputStream compress(OutputStream os) throws IOException {
26+
return new SnappyFramedOutputStream(os);
27+
}
28+
}

src/main/resources/application.properties

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ wiremock.server.asynchronousResponseEnabled=false
77
wiremock.server.asynchronousResponseThreads=10
88
wiremock.server.stubRequestLoggingDisabled=false
99
wiremock.server.verbose=true
10-
10+
#
11+
external.codecs=${EXT_CODECS:#{""}}
1112
#---
1213
spring.config.activate.on-profile=load
1314
#

0 commit comments

Comments
 (0)