grpc-wiremock
/
build.gradle
130 строк · 5.5 Кб
1plugins {
2id 'org.springframework.boot' version '2.6.2'
3id 'io.spring.dependency-management' version '1.0.11.RELEASE'
4id 'java'
5id 'com.google.protobuf' version '0.8.16'
6}
7
8group = 'io.adven.grpc.wiremock'
9version = '0.0.1-SNAPSHOT'
10sourceCompatibility = '17'
11
12repositories {
13mavenCentral()
14}
15
16def grpcVersion = '1.44.1'
17def wiremockVersion = '2.32.0'
18def protobufVersion = '3.16.0'
19def protocVersion = protobufVersion
20
21dependencies {
22implementation 'org.springframework.boot:spring-boot-starter'
23implementation 'org.springframework.boot:spring-boot-starter-aop'
24implementation "io.grpc:grpc-all:$grpcVersion"
25implementation "com.github.tomakehurst:wiremock-jre8-standalone:$wiremockVersion"
26implementation 'org.xerial.snappy:snappy-java:1.1.8.4'
27}
28
29protobuf {
30protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
31plugins { grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } }
32generateProtoTasks { all()*.plugins { grpc { outputSubDir = 'java' } } }
33generatedFilesBaseDir = 'src'
34}
35
36clean {
37delete fileTree(dir: "src/main/java", exclude: "io/adven/grpc/wiremock")
38delete "src/main/java/io/adven/grpc/wiremock/Translator.java"
39}
40
41sourceSets.main.proto.srcDir '/proto'
42/*
43sourceSets {
44main {
45resources {
46srcDir 'example'
47}
48proto {
49srcDir 'example/proto'
50}
51}
52}
53*/
54
55task generateJava(type: Copy) {
56def decorate_services = ""
57def import_services = ""
58def services = ""
59doFirst {
60def callDecoratorTemplate = """
61private final Map<String, Class> @fullServiceName@RespTypes = new HashMap<>(){{
62@resp_types@
63}};
64private final Map<String, String> @fullServiceName@MethodTypes = new HashMap<>(){{
65@method_types@
66}};
67@Around("execution(* @package@.@serviceName@Grpc.@serviceName@ImplBase.*(..))")
68public void redirect@fullServiceName@(ProceedingJoinPoint jp) throws Throwable { redirect(jp, "@serviceName@", @fullServiceName@RespTypes, @fullServiceName@MethodTypes); }
69"""
70
71def importServiceTemplate = "import @package@.@serviceName@Grpc;\n"
72def serviceTemplate = "@Service class @fullServiceName@ extends @package@.@serviceName@Grpc.@serviceName@ImplBase {}\n"
73new FileNameFinder().getFileNames("$projectDir/src/main/java", '**/*Grpc.java').forEach {
74def file = new File(it)
75def relativePath = file.path.split("src/main/java/")[1]
76def pkg = relativePath.substring(0, relativePath.lastIndexOf("/")).replace("/", ".")
77def serviceName = relativePath.substring(relativePath.lastIndexOf("/") + 1).replace("Grpc.java", "")
78def fullServiceName = pkg.replaceAll( "([\\._])([A-Za-z0-9])", { Object[] s -> s[2].toUpperCase() } ).capitalize() + serviceName
79
80println "Found $relativePath: "
81println "Parsed package = [$pkg], serviceName = [$serviceName] and fullServiceName = [$fullServiceName]"
82
83def text = file.text
84
85// Even though the file name looked like a grpc service class, dont process it
86// if you dont find a reference to an abstract class.
87if (text.indexOf('public static abstract class') == -1) {
88println "Skipping processing $file.path because its not a Service class."
89return
90}
91
92def rpcMethodAnnotation = "@io.grpc.stub.annotations.RpcMethod("
93Map<String, String> respTypes = new HashMap<>()
94Map<String, String> methodTypes = new HashMap<>()
95while (text.indexOf(rpcMethodAnnotation) >= 0) {
96def rest = text.substring(text.indexOf(rpcMethodAnnotation) + rpcMethodAnnotation.length())
97def descriptor = rest.substring(0, rest.indexOf(")")).split(',').inject([:]) { map, token ->
98token.split('=').with { map[it[0].trim()] = it[1].trim() }
99map
100}
101def method = descriptor.fullMethodName.substring("SERVICE_NAME + '/' + \"".length(), descriptor.fullMethodName.length() - 1)
102respTypes[method] = descriptor.responseType
103methodTypes[method] = descriptor.methodType.tokenize('.').last()
104text = rest
105}
106decorate_services += callDecoratorTemplate
107.replace("@package@", pkg)
108.replace("@serviceName@", serviceName)
109.replace("@fullServiceName@", fullServiceName)
110.replace("@resp_types@", respTypes.collect { k, v -> "put(\"${k.toLowerCase()}\", $v);" }.join("\n"))
111.replace("@method_types@", methodTypes.collect { k, v -> "put(\"${k.toLowerCase()}\", \"$v\");" }.join("\n"))
112
113import_services += importServiceTemplate.replace("@package@", pkg).replace("@serviceName@", serviceName)
114services += serviceTemplate
115.replace("@package@", pkg)
116.replace("@serviceName@", serviceName)
117.replace("@fullServiceName@", fullServiceName)
118}
119}
120from "src/template/java"
121into "src/main/java/io/adven/grpc/wiremock"
122filter { it.replace("@import_services@", import_services).replace("@services@", services).replace("@decorate_services@", decorate_services) }
123}
124
125compileJava.dependsOn 'generateJava'
126generateJava.dependsOn 'generateProto'
127
128bootRun {
129systemProperty 'jdk.httpclient.allowRestrictedHeaders', 'connection,content-length,expect,host,upgrade'
130}