forked from Adven27/grpc-wiremock
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.gradle
126 lines (111 loc) · 5.36 KB
/
build.gradle
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
plugins {
id 'org.springframework.boot' version '2.6.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'com.google.protobuf' version '0.8.16'
}
group = 'io.adven.grpc.wiremock'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
def grpcVersion = '1.43.2'
def wiremockVersion = '2.32.0'
def protobufVersion = '3.16.0'
def protocVersion = protobufVersion
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation "io.grpc:grpc-all:$grpcVersion"
implementation "com.github.tomakehurst:wiremock-jre8-standalone:$wiremockVersion"
implementation 'org.xerial.snappy:snappy-java:1.1.8.4'
}
protobuf {
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
plugins { grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } }
generateProtoTasks { all()*.plugins { grpc { outputSubDir = 'java' } } }
generatedFilesBaseDir = 'src'
}
clean {
delete fileTree(dir: "src/main/java", exclude: "io/adven/grpc/wiremock")
delete "src/main/java/io/adven/grpc/wiremock/Translator.java"
}
sourceSets.main.proto.srcDir '/proto'
/*
sourceSets {
main {
resources {
srcDir 'example'
}
proto {
srcDir 'example/proto'
}
}
}
*/
task generateJava(type: Copy) {
def decorate_services = ""
def import_services = ""
def services = ""
doFirst {
def callDecoratorTemplate = """
private final Map<String, Class> @fullServiceName@RespTypes = new HashMap<>(){{
@resp_types@
}};
private final Map<String, String> @fullServiceName@MethodTypes = new HashMap<>(){{
@method_types@
}};
@Around("execution(* @package@.@serviceName@Grpc.@serviceName@ImplBase.*(..))")
public void redirect@fullServiceName@(ProceedingJoinPoint jp) throws Throwable { redirect(jp, "@serviceName@", @fullServiceName@RespTypes, @fullServiceName@MethodTypes); }
"""
def importServiceTemplate = "import @package@.@serviceName@Grpc;\n"
def serviceTemplate = "@Service class @fullServiceName@ extends @package@.@serviceName@Grpc.@serviceName@ImplBase {}\n"
new FileNameFinder().getFileNames("$projectDir/src/main/java", '**/*Grpc.java').forEach {
def file = new File(it)
def relativePath = file.path.split("src/main/java/")[1]
def pkg = relativePath.substring(0, relativePath.lastIndexOf("/")).replace("/", ".")
def serviceName = relativePath.substring(relativePath.lastIndexOf("/") + 1).replace("Grpc.java", "")
def fullServiceName = pkg.replaceAll( "([\\._])([A-Za-z0-9])", { Object[] s -> s[2].toUpperCase() } ).capitalize() + serviceName
println "Found $relativePath: "
println "Parsed package = [$pkg], serviceName = [$serviceName] and fullServiceName = [$fullServiceName]"
def text = file.text
// Even though the file name looked like a grpc service class, dont process it
// if you dont find a reference to an abstract class.
if (text.indexOf('public static abstract class') == -1) {
println "Skipping processing $file.path because its not a Service class."
return
}
def rpcMethodAnnotation = "@io.grpc.stub.annotations.RpcMethod("
Map<String, String> respTypes = new HashMap<>()
Map<String, String> methodTypes = new HashMap<>()
while (text.indexOf(rpcMethodAnnotation) >= 0) {
def rest = text.substring(text.indexOf(rpcMethodAnnotation) + rpcMethodAnnotation.length())
def descriptor = rest.substring(0, rest.indexOf(")")).split(',').inject([:]) { map, token ->
token.split('=').with { map[it[0].trim()] = it[1].trim() }
map
}
def method = descriptor.fullMethodName.substring("SERVICE_NAME + '/' + \"".length(), descriptor.fullMethodName.length() - 1)
respTypes[method] = descriptor.responseType
methodTypes[method] = descriptor.methodType.tokenize('.').last()
text = rest
}
decorate_services += callDecoratorTemplate
.replace("@package@", pkg)
.replace("@serviceName@", serviceName)
.replace("@fullServiceName@", fullServiceName)
.replace("@resp_types@", respTypes.collect { k, v -> "put(\"${k.toLowerCase()}\", $v);" }.join("\n"))
.replace("@method_types@", methodTypes.collect { k, v -> "put(\"${k.toLowerCase()}\", \"$v\");" }.join("\n"))
import_services += importServiceTemplate.replace("@package@", pkg).replace("@serviceName@", serviceName)
services += serviceTemplate
.replace("@package@", pkg)
.replace("@serviceName@", serviceName)
.replace("@fullServiceName@", fullServiceName)
}
}
from "src/template/java"
into "src/main/java/io/adven/grpc/wiremock"
filter { it.replace("@import_services@", import_services).replace("@services@", services).replace("@decorate_services@", decorate_services) }
}
compileJava.dependsOn 'generateJava'
generateJava.dependsOn 'generateProto'