Skip to content

Commit ef8a9d9

Browse files
author
Alexander Furer
committed
closes #55, added inprocess server support
1 parent a9cf8a7 commit ef8a9d9

File tree

9 files changed

+201
-34
lines changed

9 files changed

+201
-34
lines changed

ReleaseNotes.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
== Version 2.1.0
2+
- gRPC version upgraded to 1.6.1
3+
- Spring boot upgraded to 1.5.6
4+
- In process server support
5+
16
== Version 2.0.5
27
- HealthStatusManager exposed as Spring bean
38
- gRPC version upgraded to 1.5.0

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22
buildscript {
33
ext {
4-
springBootVersion = '1.5.2.RELEASE'
5-
grpcVersion = '1.5.0'
4+
springBootVersion = '1.5.6.RELEASE'
5+
grpcVersion = '1.6.1'
66
}
77
repositories {
88
mavenCentral()

grpc-spring-boot-starter-demo/build.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ apply plugin: 'com.google.protobuf'
22
apply plugin: 'org.springframework.boot'
33

44
dependencies {
5-
compile "io.grpc:grpc-stub:${grpcVersion}"
6-
compile "io.grpc:grpc-protobuf:${grpcVersion}"
7-
compile "io.grpc:grpc-netty:${grpcVersion}"
5+
86
compile "org.springframework.boot:spring-boot-starter-actuator"
97
compile 'org.springframework.boot:spring-boot-starter-web'
108

grpc-spring-boot-starter-demo/src/test/java/org/lognet/springboot/grpc/DemoAppTest.java

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535
*/
3636
@RunWith(SpringRunner.class)
3737
@SpringBootTest(classes = {DemoApp.class,TestConfig.class}, webEnvironment = DEFINED_PORT)
38-
public class DemoAppTest {
38+
public class DemoAppTest extends GrpcServerTestBase{
39+
3940

40-
private ManagedChannel channel;
4141

4242
@Rule
4343
public OutputCapture outputCapture = new OutputCapture();
@@ -46,8 +46,7 @@ public class DemoAppTest {
4646
@Qualifier("globalInterceptor")
4747
private ServerInterceptor globalInterceptor;
4848

49-
@Autowired
50-
private ApplicationContext context;
49+
5150

5251

5352
@Before
@@ -62,16 +61,12 @@ public void tearDown() {
6261
channel.shutdown();
6362
}
6463

65-
@Test
66-
public void simpleGreeting() throws ExecutionException, InterruptedException {
6764

6865

69-
String name ="John";
70-
final GreeterGrpc.GreeterFutureStub greeterFutureStub = GreeterGrpc.newFutureStub(channel);
71-
final GreeterOuterClass.HelloRequest helloRequest =GreeterOuterClass.HelloRequest.newBuilder().setName(name).build();
72-
final String reply = greeterFutureStub.sayHello(helloRequest).get().getMessage();
73-
assertNotNull(reply);
74-
assertTrue(String.format("Replay should contain name '%s'",name),reply.contains(name));
66+
@Test
67+
public void disabledServerTest() throws Throwable {
68+
assertNotNull(grpcServerRunner);
69+
assertNull(grpcInprocessServerRunner);
7570

7671
}
7772

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.lognet.springboot.grpc;
2+
3+
import com.google.common.base.Throwables;
4+
import io.grpc.ManagedChannel;
5+
import io.grpc.ManagedChannelBuilder;
6+
import io.grpc.StatusRuntimeException;
7+
import io.grpc.examples.GreeterGrpc;
8+
import io.grpc.examples.GreeterOuterClass;
9+
import io.grpc.inprocess.InProcessChannelBuilder;
10+
import org.apache.tomcat.util.ExceptionUtils;
11+
import org.junit.After;
12+
import org.junit.Before;
13+
import org.junit.Test;
14+
import org.junit.runner.RunWith;
15+
import org.lognet.springboot.grpc.demo.DemoApp;
16+
import org.lognet.springboot.grpc.demo.GreeterService;
17+
import org.springframework.aop.support.AopUtils;
18+
import org.springframework.beans.factory.annotation.Autowired;
19+
import org.springframework.beans.factory.annotation.Qualifier;
20+
import org.springframework.beans.factory.annotation.Value;
21+
import org.springframework.boot.test.context.SpringBootTest;
22+
import org.springframework.core.NestedExceptionUtils;
23+
import org.springframework.test.context.ActiveProfiles;
24+
import org.springframework.test.context.junit4.SpringRunner;
25+
26+
import java.net.ConnectException;
27+
import java.util.Optional;
28+
import java.util.concurrent.ExecutionException;
29+
30+
import static org.junit.Assert.*;
31+
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE;
32+
33+
/**
34+
* Created by alexf on 28-Jan-16.
35+
*/
36+
@RunWith(SpringRunner.class)
37+
@SpringBootTest(classes = {DemoApp.class },webEnvironment = NONE
38+
,properties = {"grpc.enabled=false","grpc.inProcessServerName=testServer"}
39+
)
40+
public class DisabledGrpcServerTest extends GrpcServerTestBase {
41+
42+
43+
44+
45+
46+
47+
@Before
48+
public void setup() {
49+
channel = InProcessChannelBuilder.forName(gRpcServerProperties.getInProcessServerName())
50+
.usePlaintext(true)
51+
.build();
52+
}
53+
54+
@After
55+
public void tearDown() {
56+
channel.shutdown();
57+
}
58+
59+
@Test
60+
public void disabledServerTest() throws Throwable {
61+
assertNull(grpcServerRunner);
62+
assertNotNull(grpcInprocessServerRunner);
63+
64+
}
65+
66+
67+
68+
69+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package org.lognet.springboot.grpc;
2+
3+
import io.grpc.ManagedChannel;
4+
import io.grpc.examples.GreeterGrpc;
5+
import io.grpc.examples.GreeterOuterClass;
6+
import org.junit.Test;
7+
import org.lognet.springboot.grpc.autoconfigure.GRpcServerProperties;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.beans.factory.annotation.Qualifier;
10+
import org.springframework.context.ApplicationContext;
11+
12+
import java.util.concurrent.ExecutionException;
13+
14+
import static org.junit.Assert.assertNotNull;
15+
import static org.junit.Assert.assertTrue;
16+
17+
public abstract class GrpcServerTestBase {
18+
19+
@Autowired(required = false)
20+
@Qualifier("grpcServerRunner")
21+
protected GRpcServerRunner grpcServerRunner;
22+
23+
@Autowired(required = false)
24+
@Qualifier("grpcInprocessServerRunner")
25+
protected GRpcServerRunner grpcInprocessServerRunner;
26+
27+
28+
protected ManagedChannel channel;
29+
30+
@Autowired
31+
protected ApplicationContext context;
32+
33+
@Autowired
34+
protected GRpcServerProperties gRpcServerProperties;
35+
36+
@Test
37+
public void simpleGreeting() throws ExecutionException, InterruptedException {
38+
39+
40+
String name ="John";
41+
final GreeterGrpc.GreeterFutureStub greeterFutureStub = GreeterGrpc.newFutureStub(channel);
42+
final GreeterOuterClass.HelloRequest helloRequest =GreeterOuterClass.HelloRequest.newBuilder().setName(name).build();
43+
final String reply = greeterFutureStub.sayHello(helloRequest).get().getMessage();
44+
assertNotNull(reply);
45+
assertTrue(String.format("Replay should contain name '%s'",name),reply.contains(name));
46+
47+
}
48+
}

grpc-spring-boot-starter/src/main/java/org/lognet/springboot/grpc/GRpcServerRunner.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import io.grpc.*;
44
import io.grpc.health.v1.HealthCheckResponse;
5+
import io.grpc.inprocess.InProcessServerBuilder;
6+
import io.grpc.netty.NettyServerBuilder;
57
import io.grpc.services.HealthStatusManager;
68
import lombok.extern.slf4j.Slf4j;
79
import org.lognet.springboot.grpc.autoconfigure.GRpcServerProperties;
@@ -25,7 +27,7 @@
2527
*/
2628
@Slf4j
2729
public class GRpcServerRunner implements CommandLineRunner, DisposableBean {
28-
private final Set<String> serviceList = new ConcurrentSkipListSet<>();
30+
2931
@Autowired
3032
private HealthStatusManager healthStatusManager;
3133

@@ -40,8 +42,11 @@ public class GRpcServerRunner implements CommandLineRunner, DisposableBean {
4042

4143
private Server server;
4244

43-
public GRpcServerRunner(GRpcServerBuilderConfigurer configurer) {
45+
private final ServerBuilder<?> serverBuilder;
46+
47+
public GRpcServerRunner(GRpcServerBuilderConfigurer configurer,ServerBuilder<?> serverBuilder) {
4448
this.configurer = configurer;
49+
this.serverBuilder = serverBuilder;
4550
}
4651

4752
@Override
@@ -52,7 +57,8 @@ public void run(String... args) throws Exception {
5257
.map(name -> applicationContext.getBeanFactory().getBean(name, ServerInterceptor.class))
5358
.collect(Collectors.toList());
5459

55-
final ServerBuilder<?> serverBuilder = ServerBuilder.forPort(gRpcServerProperties.getPort());
60+
61+
5662

5763
// Adding health service
5864
serverBuilder.addService(healthStatusManager.getHealthService());
@@ -67,14 +73,16 @@ public void run(String... args) throws Exception {
6773
serverBuilder.addService(serviceDefinition);
6874
String serviceName = serviceDefinition.getServiceDescriptor().getName();
6975
healthStatusManager.setStatus(serviceName, HealthCheckResponse.ServingStatus.SERVING);
70-
serviceList.add(serviceName);
76+
7177
log.info("'{}' service has been registered.", srv.getClass().getName());
7278

7379
});
7480

81+
7582
configurer.configure(serverBuilder);
7683
server = serverBuilder.build().start();
77-
log.info("gRPC Server started, listening on port {}.", gRpcServerProperties.getPort());
84+
85+
log.info("gRPC Server started, listening on port {}.", server.getPort());
7886
startDaemonAwaitThread();
7987

8088
}
@@ -119,7 +127,7 @@ private void startDaemonAwaitThread() {
119127
@Override
120128
public void destroy() throws Exception {
121129
log.info("Shutting down gRPC server ...");
122-
serviceList.forEach(s -> healthStatusManager.clearStatus(s));
130+
server.getServices().forEach(def->healthStatusManager.clearStatus(def.getServiceDescriptor().getName()));
123131
Optional.ofNullable(server).ifPresent(Server::shutdown);
124132
log.info("gRPC server stopped.");
125133
}

grpc-spring-boot-starter/src/main/java/org/lognet/springboot/grpc/autoconfigure/GRpcAutoConfiguration.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,61 @@
11
package org.lognet.springboot.grpc.autoconfigure;
22

3+
import io.grpc.ServerBuilder;
4+
import io.grpc.inprocess.InProcessServerBuilder;
35
import io.grpc.services.HealthStatusManager;
6+
import lombok.Getter;
47
import org.lognet.springboot.grpc.GRpcServerBuilderConfigurer;
58
import org.lognet.springboot.grpc.GRpcServerRunner;
69
import org.lognet.springboot.grpc.GRpcService;
10+
import org.springframework.beans.factory.annotation.Autowired;
711
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
812
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
13+
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
914
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
15+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
16+
import org.springframework.boot.context.properties.ConfigurationProperties;
1017
import org.springframework.boot.context.properties.EnableConfigurationProperties;
18+
import org.springframework.context.ApplicationContext;
1119
import org.springframework.context.annotation.Bean;
1220
import org.springframework.context.annotation.Configuration;
21+
import org.springframework.stereotype.Component;
1322

1423
/**
1524
* Created by alexf on 25-Jan-16.
1625
*/
17-
@Configuration
18-
@EnableConfigurationProperties(GRpcServerProperties.class)
26+
1927
@AutoConfigureOrder
28+
@ConditionalOnBean(annotation = GRpcService.class)
29+
@EnableConfigurationProperties(GRpcServerProperties.class)
2030
public class GRpcAutoConfiguration {
2131

32+
33+
34+
@Autowired
35+
private ApplicationContext ctx;
36+
37+
38+
@Getter
39+
@Autowired
40+
private GRpcServerProperties grpcServerProperties;
41+
42+
43+
2244
@Bean
23-
@ConditionalOnBean(annotation = GRpcService.class)
45+
@ConditionalOnProperty(value = "grpc.enabled",havingValue = "true",matchIfMissing = true)
2446
public GRpcServerRunner grpcServerRunner(GRpcServerBuilderConfigurer configurer){
25-
return new GRpcServerRunner(configurer);
47+
return new GRpcServerRunner(configurer, ServerBuilder.forPort(grpcServerProperties.getPort()));
2648
}
2749

2850
@Bean
29-
@ConditionalOnBean(annotation = GRpcService.class)
51+
@ConditionalOnExpression("#{environment.getProperty('grpc.inProcessServerName','')!=''}")
52+
public GRpcServerRunner grpcInprocessServerRunner(GRpcServerBuilderConfigurer configurer){
53+
return new GRpcServerRunner(configurer, InProcessServerBuilder.forName(grpcServerProperties.getInProcessServerName()));
54+
}
55+
56+
57+
58+
@Bean
3059
public HealthStatusManager healthStatusManager() {
3160
return new HealthStatusManager();
3261
}
Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,37 @@
11
package org.lognet.springboot.grpc.autoconfigure;
22

3+
import lombok.Getter;
4+
import lombok.Setter;
35
import org.springframework.boot.context.properties.ConfigurationProperties;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.stereotype.Component;
48

59
/**
610
* Created by alexf on 26-Jan-16.
711
*/
12+
813
@ConfigurationProperties("grpc")
14+
@Getter @Setter
915
public class GRpcServerProperties {
1016
/**
1117
* gRPC server port
18+
*
1219
*/
1320
private int port = 6565;
1421

15-
public int getPort() {
16-
return port;
17-
}
1822

19-
public void setPort(int port) {
20-
this.port = port;
21-
}
23+
/**
24+
* Enables the embedded grpc server.
25+
*/
26+
private boolean enabled = true;
27+
28+
29+
/**
30+
* In process server name.
31+
* If the value is not empty, the embedded in-process server will be created and started.
32+
*
33+
*/
34+
private String inProcessServerName;
35+
36+
2237
}

0 commit comments

Comments
 (0)