/
GrpcConnectivityTest.kt
146 lines (131 loc) · 4.59 KB
/
GrpcConnectivityTest.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package misk.grpc
import com.google.inject.Guice
import com.google.inject.Provides
import com.squareup.protos.test.grpc.HelloReply
import com.squareup.protos.test.grpc.HelloRequest
import com.squareup.wire.Service
import com.squareup.wire.WireRpc
import misk.MiskTestingServiceModule
import misk.client.HttpClientEndpointConfig
import misk.client.HttpClientModule
import misk.client.HttpClientSSLConfig
import misk.client.HttpClientsConfig
import misk.inject.KAbstractModule
import misk.inject.getInstance
import misk.security.ssl.SslLoader
import misk.security.ssl.TrustStoreConfig
import misk.testing.MiskTest
import misk.testing.MiskTestModule
import misk.web.WebActionModule
import misk.web.WebTestingModule
import misk.web.actions.WebAction
import misk.web.jetty.JettyService
import misk.web.mediatype.MediaTypes
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okio.BufferedSink
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import javax.inject.Inject
import javax.inject.Singleton
/**
* This test gets Misk running as a GRPC server and then acts as a basic GRPC client to send a
* request. It's intended to be interoperable with with the
* [GRPC 'hello world' sample](https://github.com/grpc/grpc-java/tree/master/examples).
*
* That sample includes a client and a server that connect to each other. You can also connect this
* test's client to that sample server, or that sample client to this test's server.
*/
@MiskTest(startService = true)
class GrpcConnectivityTest {
@MiskTestModule
val module = TestModule()
@Inject
private lateinit var jetty: JettyService
private lateinit var client: OkHttpClient
@BeforeEach
fun createClient() {
val clientInjector = Guice.createInjector(ClientModule(jetty))
client = clientInjector.getInstance()
}
@Test
fun happyPath() {
val request = Request.Builder()
.url(jetty.httpsServerUrl!!.resolve("/helloworld.Greeter/SayHello")!!)
.addHeader("grpc-trace-bin", "")
.addHeader("grpc-accept-encoding", "gzip")
.addHeader("grpc-encoding", "gzip")
.post(object : RequestBody() {
override fun contentType(): MediaType? {
return MediaTypes.APPLICATION_GRPC_MEDIA_TYPE
}
override fun writeTo(sink: BufferedSink) {
val writer = GrpcMessageSink(sink, HelloRequest.ADAPTER, "gzip")
writer.write(HelloRequest("jesse!"))
}
})
.build()
val call = client.newCall(request)
val response = call.execute()
for (i in 0 until response.headers.size) {
println("${response.headers.name(i)}: ${response.headers.value(i)}")
}
val reader = GrpcMessageSource(response.body!!.source(), HelloReply.ADAPTER,
response.header("grpc-encoding"))
while (true) {
val message = reader.read() ?: break
println(message)
}
}
class HelloRpcAction @Inject constructor() : WebAction, GreeterSayHello {
override fun sayHello(request: HelloRequest): HelloReply {
return HelloReply.Builder()
.message("howdy, ${request.name}")
.build()
}
}
interface GreeterSayHello : Service {
@WireRpc(
path = "/helloworld.Greeter/SayHello",
requestAdapter = "com.squareup.protos.test.grpc.HelloRequest.ADAPTER",
responseAdapter = "com.squareup.protos.test.grpc.HelloReply.ADAPTER"
)
fun sayHello(request: HelloRequest): HelloReply
}
class TestModule : KAbstractModule() {
override fun configure() {
install(WebTestingModule(webConfig = WebTestingModule.TESTING_WEB_CONFIG.copy(
http2 = true
)))
install(WebActionModule.create<HelloRpcAction>())
}
}
// NB: The server doesn't get a port until after it starts so we create the client module
// _after_ we start the services
class ClientModule(val jetty: JettyService) : KAbstractModule() {
override fun configure() {
install(MiskTestingServiceModule())
install(HttpClientModule("default"))
}
@Provides
@Singleton
fun provideHttpClientsConfig(): HttpClientsConfig {
return HttpClientsConfig(
endpoints = mapOf(
"default" to HttpClientEndpointConfig(
"http://example.com/",
ssl = HttpClientSSLConfig(
cert_store = null,
trust_store = TrustStoreConfig(
resource = "classpath:/ssl/server_cert.pem",
format = SslLoader.FORMAT_PEM
)
)
)
)
)
}
}
}