Skip to content

Commit d3d4e8f

Browse files
committed
Make grpc-services.jar optional + remove grpc health service setup
1 parent d2d50ed commit d3d4e8f

16 files changed

+345
-92
lines changed

build.gradle

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ allprojects {
7979
apply plugin: 'com.diffplug.spotless'
8080
apply plugin: 'io.franzbecker.gradle-lombok'
8181

82+
java {
83+
toolchain {
84+
languageVersion = JavaLanguageVersion.of(8)
85+
}
86+
}
87+
8288
compileJava {
8389
sourceCompatibility = JavaVersion.VERSION_1_8
8490
targetCompatibility = JavaVersion.VERSION_1_8
@@ -89,6 +95,13 @@ allprojects {
8995
'-Xlint:all', '-Xlint:-processing'
9096
]
9197

98+
eclipse {
99+
classpath {
100+
downloadJavadoc = true
101+
downloadSources = true
102+
}
103+
}
104+
92105
spotless {
93106
java {
94107
licenseHeaderFile rootProject.file('extra/spotless/mit-license.java')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
6+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
8+
*
9+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
10+
* Software.
11+
*
12+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16+
*/
17+
18+
package net.devh.boot.grpc.server.autoconfigure;
19+
20+
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
21+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
22+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
23+
import org.springframework.context.annotation.Bean;
24+
import org.springframework.context.annotation.Configuration;
25+
26+
import io.grpc.BindableService;
27+
import io.grpc.protobuf.services.ProtoReflectionService;
28+
import net.devh.boot.grpc.server.service.GrpcService;
29+
30+
/**
31+
* Auto configuration that sets up the proto reflection service.
32+
*
33+
* @author Daniel Theuke ([email protected])
34+
*/
35+
@Configuration
36+
@ConditionalOnClass(ProtoReflectionService.class)
37+
@ConditionalOnProperty(prefix = "grpc.server", name = "reflection-service-enabled", matchIfMissing = true)
38+
@AutoConfigureBefore(GrpcServerFactoryAutoConfiguration.class)
39+
public class GrpcReflectionServiceAutoConfiguration {
40+
41+
/**
42+
* Creates a new ProtoReflectionService instance.
43+
*
44+
* @return The newly created bean.
45+
*/
46+
@Bean
47+
@GrpcService
48+
BindableService protoReflectionService() {
49+
return ProtoReflectionService.newInstance();
50+
}
51+
52+
}

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/autoconfigure/GrpcServerAutoConfiguration.java

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import io.grpc.CompressorRegistry;
3434
import io.grpc.DecompressorRegistry;
3535
import io.grpc.Server;
36-
import io.grpc.services.HealthStatusManager;
3736
import net.devh.boot.grpc.common.autoconfigure.GrpcCommonCodecAutoConfiguration;
3837
import net.devh.boot.grpc.server.config.GrpcServerProperties;
3938
import net.devh.boot.grpc.server.interceptor.AnnotationGlobalServerInterceptorConfigurer;
@@ -108,12 +107,6 @@ public GrpcServiceDiscoverer defaultGrpcServiceDiscoverer() {
108107
return new AnnotationGrpcServiceDiscoverer();
109108
}
110109

111-
@ConditionalOnMissingBean
112-
@Bean
113-
public HealthStatusManager healthStatusManager() {
114-
return new HealthStatusManager();
115-
}
116-
117110
@ConditionalOnBean(CompressorRegistry.class)
118111
@Bean
119112
public GrpcServerConfigurer compressionServerConfigurer(final CompressorRegistry registry) {
@@ -135,7 +128,8 @@ public List<GrpcServerConfigurer> defaultServerConfigurers() {
135128
@ConditionalOnMissingBean
136129
@ConditionalOnBean(GrpcServerFactory.class)
137130
@Bean
138-
public GrpcServerLifecycle grpcServerLifecycle(final GrpcServerFactory factory, GrpcServerProperties properties) {
131+
public GrpcServerLifecycle grpcServerLifecycle(final GrpcServerFactory factory,
132+
final GrpcServerProperties properties) {
139133
return new GrpcServerLifecycle(factory, properties.getShutdownGracePeriod());
140134
}
141135

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/autoconfigure/GrpcServerMetricAutoConfiguration.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
import io.grpc.BindableService;
4141
import io.grpc.MethodDescriptor;
4242
import io.grpc.ServiceDescriptor;
43-
import io.grpc.protobuf.services.ProtoReflectionService;
44-
import io.grpc.services.HealthStatusManager;
4543
import io.micrometer.core.instrument.MeterRegistry;
4644
import lombok.extern.slf4j.Slf4j;
4745
import net.devh.boot.grpc.server.config.GrpcServerProperties;
@@ -75,20 +73,15 @@ public MetricCollectingServerInterceptor metricCollectingServerInterceptor(final
7573
@Bean
7674
@Lazy
7775
InfoContributor grpcInfoContributor(final GrpcServerProperties properties,
78-
final Collection<BindableService> grpcServices, final HealthStatusManager healthStatusManager) {
76+
final Collection<BindableService> grpcServices) {
7977
final Map<String, Object> details = new LinkedHashMap<>();
8078
details.put("port", properties.getPort());
8179

8280
if (properties.isReflectionServiceEnabled()) {
8381
// Only expose services via web-info if we do the same via grpc.
8482
final Map<String, List<String>> services = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
8583
details.put("services", services);
86-
final List<BindableService> mutableGrpcServiceList = new ArrayList<>(grpcServices);
87-
mutableGrpcServiceList.add(ProtoReflectionService.newInstance());
88-
if (properties.isHealthServiceEnabled()) {
89-
mutableGrpcServiceList.add(healthStatusManager.getHealthService());
90-
}
91-
for (final BindableService grpcService : mutableGrpcServiceList) {
84+
for (final BindableService grpcService : grpcServices) {
9285
final ServiceDescriptor serviceDescriptor = grpcService.bindService().getServiceDescriptor();
9386

9487
final List<String> methods = collectMethodNamesForService(serviceDescriptor);

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/config/GrpcServerProperties.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,6 @@ public class GrpcServerProperties {
180180
@DataSizeUnit(DataUnit.BYTES)
181181
private DataSize maxInboundMetadataSize = null;
182182

183-
/**
184-
* Whether gRPC health service is enabled or not. Defaults to {@code true}.
185-
*
186-
* @param healthServiceEnabled Whether gRPC health service is enabled.
187-
* @return True, if the health service is enabled. False otherwise.
188-
*/
189-
private boolean healthServiceEnabled = true;
190-
191183
/**
192184
* Whether proto reflection service is enabled or not. Defaults to {@code true}.
193185
*

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/serverfactory/AbstractGrpcServerFactory.java

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,12 @@
2323
import java.util.List;
2424
import java.util.Set;
2525

26-
import org.springframework.beans.factory.annotation.Autowired;
2726
import org.springframework.util.unit.DataSize;
2827

29-
import com.google.common.annotations.VisibleForTesting;
3028
import com.google.common.collect.Lists;
3129

3230
import io.grpc.Server;
3331
import io.grpc.ServerBuilder;
34-
import io.grpc.health.v1.HealthCheckResponse;
35-
import io.grpc.health.v1.HealthGrpc;
36-
import io.grpc.protobuf.services.ProtoReflectionService;
37-
import io.grpc.reflection.v1alpha.ServerReflectionGrpc;
38-
import io.grpc.services.HealthStatusManager;
3932
import lombok.extern.slf4j.Slf4j;
4033
import net.devh.boot.grpc.server.config.GrpcServerProperties;
4134
import net.devh.boot.grpc.server.service.GrpcServiceDefinition;
@@ -56,17 +49,13 @@ public abstract class AbstractGrpcServerFactory<T extends ServerBuilder<T>> impl
5649
protected final GrpcServerProperties properties;
5750
protected final List<GrpcServerConfigurer> serverConfigurers;
5851

59-
@Autowired
60-
@VisibleForTesting
61-
HealthStatusManager healthStatusManager;
62-
6352
/**
6453
* Creates a new server factory with the given properties.
6554
*
6655
* @param properties The properties used to configure the server.
6756
* @param serverConfigurers The server configurers to use. Can be empty.
6857
*/
69-
public AbstractGrpcServerFactory(final GrpcServerProperties properties,
58+
protected AbstractGrpcServerFactory(final GrpcServerProperties properties,
7059
final List<GrpcServerConfigurer> serverConfigurers) {
7160
this.properties = requireNonNull(properties, "properties");
7261
this.serverConfigurers = requireNonNull(serverConfigurers, "serverConfigurers");
@@ -110,17 +99,6 @@ protected void configure(final T builder) {
11099
protected void configureServices(final T builder) {
111100
final Set<String> serviceNames = new LinkedHashSet<>();
112101

113-
// support health check
114-
if (this.properties.isHealthServiceEnabled()) {
115-
builder.addService(this.healthStatusManager.getHealthService());
116-
serviceNames.add(HealthGrpc.getServiceDescriptor().getName());
117-
}
118-
// gRPC reflection
119-
if (this.properties.isReflectionServiceEnabled()) {
120-
builder.addService(ProtoReflectionService.newInstance());
121-
serviceNames.add(ServerReflectionGrpc.getServiceDescriptor().getName());
122-
}
123-
124102
for (final GrpcServiceDefinition service : this.serviceList) {
125103
final String serviceName = service.getDefinition().getServiceDescriptor().getName();
126104
if (!serviceNames.add(serviceName)) {
@@ -129,7 +107,6 @@ protected void configureServices(final T builder) {
129107
log.info("Registered gRPC service: " + serviceName + ", bean: " + service.getBeanName() + ", class: "
130108
+ service.getBeanClazz().getName());
131109
builder.addService(service.getDefinition());
132-
this.healthStatusManager.setStatus(serviceName, HealthCheckResponse.ServingStatus.SERVING);
133110
}
134111
}
135112

@@ -186,12 +163,4 @@ public void addService(final GrpcServiceDefinition service) {
186163
this.serviceList.add(service);
187164
}
188165

189-
@Override
190-
public void destroy() {
191-
for (final GrpcServiceDefinition grpcServiceDefinition : this.serviceList) {
192-
final String serviceName = grpcServiceDefinition.getDefinition().getServiceDescriptor().getName();
193-
this.healthStatusManager.clearStatus(serviceName);
194-
}
195-
}
196-
197166
}

grpc-server-spring-boot-autoconfigure/src/main/java/net/devh/boot/grpc/server/serverfactory/GrpcServerFactory.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717

1818
package net.devh.boot.grpc.server.serverfactory;
1919

20-
import org.springframework.beans.factory.DisposableBean;
21-
2220
import io.grpc.Server;
2321
import net.devh.boot.grpc.server.service.GrpcServiceDefinition;
2422

@@ -28,7 +26,7 @@
2826
* @author Michael ([email protected])
2927
* @since 5/17/16
3028
*/
31-
public interface GrpcServerFactory extends DisposableBean {
29+
public interface GrpcServerFactory {
3230

3331
/**
3432
* Creates a new grpc server with the stored options. The entire lifecycle management of the server should be
@@ -64,10 +62,4 @@ public interface GrpcServerFactory extends DisposableBean {
6462
*/
6563
void addService(GrpcServiceDefinition service);
6664

67-
/**
68-
* Destroys this factory. This does not destroy or shutdown any server that was created using this factory.
69-
*/
70-
@Override
71-
void destroy();
72-
7365
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# AutoConfiguration
22
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
3+
net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration,\
34
net.devh.boot.grpc.server.autoconfigure.GrpcMetadataConsulConfiguration,\
45
net.devh.boot.grpc.server.autoconfigure.GrpcMetadataEurekaConfiguration,\
56
net.devh.boot.grpc.server.autoconfigure.GrpcMetadataNacosConfiguration,\
67
net.devh.boot.grpc.server.autoconfigure.GrpcMetadataZookeeperConfiguration,\
8+
net.devh.boot.grpc.server.autoconfigure.GrpcReflectionServiceAutoConfiguration,\
79
net.devh.boot.grpc.server.autoconfigure.GrpcServerAutoConfiguration,\
810
net.devh.boot.grpc.server.autoconfigure.GrpcServerFactoryAutoConfiguration,\
9-
net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration,\
1011
net.devh.boot.grpc.server.autoconfigure.GrpcServerMetricAutoConfiguration,\
11-
net.devh.boot.grpc.server.autoconfigure.GrpcServerTraceAutoConfiguration,\
12-
net.devh.boot.grpc.server.autoconfigure.GrpcAdviceAutoConfiguration
12+
net.devh.boot.grpc.server.autoconfigure.GrpcServerSecurityAutoConfiguration,\
13+
net.devh.boot.grpc.server.autoconfigure.GrpcServerTraceAutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) 2016-2021 Michael Zhang <[email protected]>
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5+
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
6+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7+
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
8+
*
9+
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
10+
* Software.
11+
*
12+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13+
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16+
*/
17+
18+
package net.devh.boot.grpc.server.autoconfigure;
19+
20+
import java.util.ArrayList;
21+
import java.util.List;
22+
import java.util.concurrent.CountDownLatch;
23+
24+
import io.grpc.stub.StreamObserver;
25+
26+
class AwaitableStreamObserver<V> implements StreamObserver<V> {
27+
28+
private final CountDownLatch doneLatch = new CountDownLatch(1);
29+
private final List<V> results = new ArrayList<>();
30+
private volatile Throwable error;
31+
32+
@Override
33+
public void onNext(final V value) {
34+
this.results.add(value);
35+
}
36+
37+
@Override
38+
public void onError(final Throwable t) {
39+
this.error = t;
40+
this.doneLatch.countDown();
41+
}
42+
43+
@Override
44+
public void onCompleted() {
45+
this.doneLatch.countDown();
46+
}
47+
48+
public V getFirst() throws InterruptedException {
49+
this.doneLatch.await();
50+
if (this.error != null) {
51+
throw new IllegalStateException("Request failed with unexpected error", this.error);
52+
}
53+
if (this.results.isEmpty()) {
54+
throw new IllegalStateException("Requested completed without response");
55+
}
56+
return this.results.get(0);
57+
}
58+
59+
public V getSingle() throws InterruptedException {
60+
this.doneLatch.await();
61+
if (this.error != null) {
62+
throw new IllegalStateException("Request failed with unexpected error", this.error);
63+
}
64+
if (this.results.isEmpty()) {
65+
throw new IllegalStateException("Requested completed without response");
66+
}
67+
if (this.results.size() != 1) {
68+
throw new IllegalStateException(
69+
"Request completed with more than one response - Got " + this.results.size());
70+
}
71+
return this.results.get(0);
72+
}
73+
74+
public List<V> getAll() throws InterruptedException {
75+
this.doneLatch.await();
76+
if (this.error != null) {
77+
throw new IllegalStateException("Request failed with unexpected error", this.error);
78+
}
79+
return this.results;
80+
}
81+
82+
public Throwable getError() throws InterruptedException {
83+
this.doneLatch.await();
84+
if (this.error == null) {
85+
throw new IllegalStateException("Request completed without error");
86+
}
87+
return this.error;
88+
}
89+
90+
}

0 commit comments

Comments
 (0)