diff --git a/samples/grpc-server/src/test/java/org/springframework/grpc/sample/YetAnotherApplicationTests.java b/samples/grpc-server/src/test/java/org/springframework/grpc/sample/YetAnotherApplicationTests.java index 9032d22..adb5207 100644 --- a/samples/grpc-server/src/test/java/org/springframework/grpc/sample/YetAnotherApplicationTests.java +++ b/samples/grpc-server/src/test/java/org/springframework/grpc/sample/YetAnotherApplicationTests.java @@ -3,36 +3,44 @@ package org.springframework.grpc.sample; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Lazy; +import org.springframework.grpc.client.GrpcChannelFactory; import org.springframework.grpc.sample.proto.HelloReply; import org.springframework.grpc.sample.proto.HelloRequest; import org.springframework.grpc.sample.proto.SimpleGrpc; +import org.springframework.grpc.test.LocalGrpcPort; import org.springframework.test.annotation.DirtiesContext; -import io.grpc.Grpc; -import io.grpc.InsecureChannelCredentials; - -@SpringBootTest +@SpringBootTest(properties = { "spring.grpc.server.port=0", "spring.grpc.server.address=127.0.0.1" }) @DirtiesContext class YetAnotherApplicationTests { + @Autowired + private SimpleGrpc.SimpleBlockingStub stub; + @Test void contextLoads() { } @Test void serverResponds() { - var channel = Grpc.newChannelBuilderForAddress("0.0.0.0", 9090, InsecureChannelCredentials.create()).build(); - var stub = SimpleGrpc.newBlockingStub(channel); HelloReply response = stub.sayHello(HelloRequest.newBuilder().setName("Alien").build()); assertEquals("Hello ==> Alien", response.getMessage()); - channel.shutdown(); } @TestConfiguration static class ExtraConfiguration { + @Bean + @Lazy + SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels, @LocalGrpcPort int port) { + return SimpleGrpc.newBlockingStub(channels.createChannel("127.0.0.1:" + port).build()); + } + } } diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/server/DefaultGrpcServerFactory.java b/spring-grpc-core/src/main/java/org/springframework/grpc/server/DefaultGrpcServerFactory.java index 1f2ea07..957d311 100644 --- a/spring-grpc-core/src/main/java/org/springframework/grpc/server/DefaultGrpcServerFactory.java +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/server/DefaultGrpcServerFactory.java @@ -33,6 +33,8 @@ import io.grpc.ServerServiceDefinition; public class DefaultGrpcServerFactory> implements GrpcServerFactory { + private static final String ANY_IP_ADDRESS = "*"; + /** Logger available to subclasses. */ protected final Log logger = LogFactory.getLog(getClass()); @@ -71,14 +73,31 @@ public class DefaultGrpcServerFactory> implements Grp */ @SuppressWarnings("unchecked") protected T newServerBuilder() { - if (getAddress() != null) { - if (getAddress().startsWith("unix:")) { - String path = getAddress().substring(5); + String address = getAddress(); + int port = getPort(); + if (address != null) { + if (address.startsWith("unix:")) { + String path = address.substring(5); return unixDomainServerBuilder(path); } + if (!ANY_IP_ADDRESS.equals(address)) { + return inetSocketServerBuilder(address, port); + } // TODO: Add more support for address resolution } - return (T) ServerBuilder.forPort(getPort()); + return (T) ServerBuilder.forPort(port); + } + + @SuppressWarnings("unchecked") + private T inetSocketServerBuilder(String path, int port) { + if (NettyServerFactoryHelper.isAvailable()) { + return (T) NettyServerFactoryHelper.forInetAddress(path, port); + } + else if (ShadedNettyServerFactoryHelper.isAvailable()) { + return (T) ShadedNettyServerFactoryHelper.forInetAddress(path, port); + } + throw new IllegalStateException( + "Netty Epoll not available. Add io.netty:netty-transport-native-epoll:linux-x86_64 to your classpath."); } @SuppressWarnings("unchecked") diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/server/NettyServerFactoryHelper.java b/spring-grpc-core/src/main/java/org/springframework/grpc/server/NettyServerFactoryHelper.java index a86bdda..2b911b1 100644 --- a/spring-grpc-core/src/main/java/org/springframework/grpc/server/NettyServerFactoryHelper.java +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/server/NettyServerFactoryHelper.java @@ -15,8 +15,12 @@ */ package org.springframework.grpc.server; +import java.net.InetSocketAddress; + import org.springframework.util.ClassUtils; +import com.google.common.net.InetAddresses; + import io.grpc.ServerBuilder; import io.grpc.netty.NettyServerBuilder; import io.netty.channel.epoll.Epoll; @@ -40,4 +44,8 @@ class NettyServerFactoryHelper { .workerEventLoopGroup(new EpollEventLoopGroup()); } + public static ServerBuilder forInetAddress(String address, int port) { + return NettyServerBuilder.forAddress(new InetSocketAddress(InetAddresses.forString(address), port)); + } + } diff --git a/spring-grpc-core/src/main/java/org/springframework/grpc/server/ShadedNettyServerFactoryHelper.java b/spring-grpc-core/src/main/java/org/springframework/grpc/server/ShadedNettyServerFactoryHelper.java index aee49d3..ba69f97 100644 --- a/spring-grpc-core/src/main/java/org/springframework/grpc/server/ShadedNettyServerFactoryHelper.java +++ b/spring-grpc-core/src/main/java/org/springframework/grpc/server/ShadedNettyServerFactoryHelper.java @@ -15,8 +15,12 @@ */ package org.springframework.grpc.server; +import java.net.InetSocketAddress; + import org.springframework.util.ClassUtils; +import com.google.common.net.InetAddresses; + import io.grpc.ServerBuilder; import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder; import io.grpc.netty.shaded.io.netty.channel.epoll.Epoll; @@ -40,4 +44,8 @@ class ShadedNettyServerFactoryHelper { .workerEventLoopGroup(new EpollEventLoopGroup()); } + public static ServerBuilder forInetAddress(String address, int port) { + return NettyServerBuilder.forAddress(new InetSocketAddress(InetAddresses.forString(address), port)); + } + }