Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

netty: implement UdsNameResolver and UdsNettyChannelProvider #9113

Merged
merged 11 commits into from May 2, 2022
Merged
5 changes: 5 additions & 0 deletions api/src/main/java/io/grpc/ManagedChannelRegistry.java
Expand Up @@ -145,6 +145,11 @@ static List<Class<?>> getHardCodedClasses() {
} catch (ClassNotFoundException e) {
logger.log(Level.FINE, "Unable to find NettyChannelProvider", e);
}
try {
list.add(Class.forName("io.grpc.netty.UdsNettyChannelProvider"));
} catch (ClassNotFoundException e) {
logger.log(Level.FINE, "Unable to find UdsNettyChannelProvider", e);
}
return Collections.unmodifiableList(list);
}

Expand Down
6 changes: 3 additions & 3 deletions netty/build.gradle
Expand Up @@ -17,7 +17,8 @@ evaluationDependsOn(project(':grpc-core').path)

dependencies {
api project(':grpc-core'),
libraries.netty
libraries.netty,
libraries.netty_epoll
ejona86 marked this conversation as resolved.
Show resolved Hide resolved
implementation libraries.netty_proxy_handler,
libraries.guava,
libraries.errorprone,
Expand All @@ -29,8 +30,7 @@ dependencies {
project(':grpc-testing'),
project(':grpc-testing-proto')
testRuntimeOnly libraries.netty_tcnative,
libraries.conscrypt,
libraries.netty_epoll
libraries.conscrypt
signature "org.codehaus.mojo.signature:java17:1.0@signature"
alpnagent libraries.jetty_alpn_agent
}
Expand Down
66 changes: 66 additions & 0 deletions netty/src/main/java/io/grpc/netty/UdsNameResolver.java
@@ -0,0 +1,66 @@
/*
* Copyright 2022 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.grpc.netty;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Preconditions;
import io.grpc.EquivalentAddressGroup;
import io.grpc.NameResolver;
import io.netty.channel.unix.DomainSocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

final class UdsNameResolver extends NameResolver {
private NameResolver.Listener2 listener;
private final String authority;

UdsNameResolver(String authority, String targetPath) {
checkArgument(authority == null, "non-null authority not supported");
this.authority = targetPath;
}

@Override
public String getServiceAuthority() {
return this.authority;
}

@Override
public void start(Listener2 listener) {
Preconditions.checkState(this.listener == null, "already started");
this.listener = checkNotNull(listener, "listener");
resolve();
}

@Override
public void refresh() {
resolve();
}

private void resolve() {
ResolutionResult.Builder resolutionResultBuilder = ResolutionResult.newBuilder();
List<EquivalentAddressGroup> servers = new ArrayList<>(1);
servers.add(new EquivalentAddressGroup(new DomainSocketAddress(authority)));
resolutionResultBuilder.setAddresses(Collections.unmodifiableList(servers));
listener.onResult(resolutionResultBuilder.build());
}

@Override
public void shutdown() {}
}
71 changes: 71 additions & 0 deletions netty/src/main/java/io/grpc/netty/UdsNameResolverProvider.java
@@ -0,0 +1,71 @@
/*
* Copyright 2022 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.grpc.netty;

import com.google.common.base.Preconditions;
import io.grpc.Internal;
import io.grpc.NameResolver;
import io.grpc.NameResolverProvider;
import io.netty.channel.unix.DomainSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;

@Internal
public final class UdsNameResolverProvider extends NameResolverProvider {

private static final String SCHEME = "unix";

@Override
public UdsNameResolver newNameResolver(URI targetUri, NameResolver.Args args) {
if (SCHEME.equals(targetUri.getScheme())) {
return new UdsNameResolver(targetUri.getAuthority(), getTargetPathFromUri(targetUri));
} else {
return null;
}
}

static String getTargetPathFromUri(URI targetUri) {
Preconditions.checkArgument(SCHEME.equals(targetUri.getScheme()), "scheme must be " + SCHEME);
String targetPath = targetUri.getPath();
if (targetPath == null) {
targetPath = Preconditions.checkNotNull(targetUri.getSchemeSpecificPart(), "targetPath");
ejona86 marked this conversation as resolved.
Show resolved Hide resolved
}
return targetPath;
}

@Override
public String getDefaultScheme() {
return SCHEME;
}

@Override
protected boolean isAvailable() {
return true;
}

@Override
protected int priority() {
return 3;
}

@Override
protected Collection<Class<? extends SocketAddress>> getProducedSocketAddressTypes() {
return Collections.singleton(DomainSocketAddress.class);
}
}
91 changes: 91 additions & 0 deletions netty/src/main/java/io/grpc/netty/UdsNettyChannelProvider.java
@@ -0,0 +1,91 @@
/*
* Copyright 2015 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.grpc.netty;

import io.grpc.CallCredentials;
import io.grpc.ChannelCredentials;
import io.grpc.InsecureChannelCredentials;
import io.grpc.Internal;
import io.grpc.ManagedChannelProvider;
import io.grpc.internal.SharedResourcePool;
import io.netty.channel.epoll.EpollDomainSocketChannel;
import io.netty.channel.unix.DomainSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;

/** Provider for {@link NettyChannelBuilder} instances for UDS channels. */
@Internal
public final class UdsNettyChannelProvider extends ManagedChannelProvider {

@Override
public boolean isAvailable() {
return true;
}

@Override
public int priority() {
return 3;
}

@Override
public NettyChannelBuilder builderForAddress(String name, int port) {
throw new UnsupportedOperationException("host:port not supported");
}

@Override
public NettyChannelBuilder builderForTarget(String target) {
ChannelCredentials creds = InsecureChannelCredentials.create();
ProtocolNegotiators.FromChannelCredentialsResult result = ProtocolNegotiators.from(creds);
if (result.error != null) {
throw new RuntimeException(result.error);
}
return getNettyChannelBuilder(target, creds, null, result.negotiator);
}

@Override
public NewChannelBuilderResult newChannelBuilder(String target, ChannelCredentials creds) {
ProtocolNegotiators.FromChannelCredentialsResult result = ProtocolNegotiators.from(creds);
if (result.error != null) {
return NewChannelBuilderResult.error(result.error);
}
return NewChannelBuilderResult.channelBuilder(
getNettyChannelBuilder(target, creds, result.callCredentials, result.negotiator));
}

private static NettyChannelBuilder getNettyChannelBuilder(
String target,
ChannelCredentials creds,
CallCredentials callCredentials,
ProtocolNegotiator.ClientFactory negotiator) {
String targetPath = UdsNameResolverProvider.getTargetPathFromUri(URI.create(target));
NettyChannelBuilder builder =
new NettyChannelBuilder(
new DomainSocketAddress(targetPath), creds, callCredentials, negotiator);
builder =
builder
.eventLoopGroupPool(SharedResourcePool.forResource(Utils.UDS_CHANNELS_EVENT_LOOP_GROUP))
.channelType(EpollDomainSocketChannel.class);
sanjaypujare marked this conversation as resolved.
Show resolved Hide resolved
return builder;
}

@Override
protected Collection<Class<? extends SocketAddress>> getSupportedSocketAddressTypes() {
return Collections.singleton(DomainSocketAddress.class);
}
}
5 changes: 5 additions & 0 deletions netty/src/main/java/io/grpc/netty/Utils.java
Expand Up @@ -44,6 +44,7 @@
import io.netty.channel.EventLoopGroup;
import io.netty.channel.ReflectiveChannelFactory;
import io.netty.channel.ServerChannel;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
Expand Down Expand Up @@ -89,6 +90,10 @@ class Utils {
= new DefaultEventLoopGroupResource(1, "grpc-nio-boss-ELG", EventLoopGroupType.NIO);
public static final Resource<EventLoopGroup> NIO_WORKER_EVENT_LOOP_GROUP
= new DefaultEventLoopGroupResource(0, "grpc-nio-worker-ELG", EventLoopGroupType.NIO);
public static final Resource<EventLoopGroup> UDS_CHANNELS_EVENT_LOOP_GROUP =
Epoll.isAvailable() ? new DefaultEventLoopGroupResource(1, "UdsChannels",
ejona86 marked this conversation as resolved.
Show resolved Hide resolved
EventLoopGroupType.EPOLL) : null;

public static final Resource<EventLoopGroup> DEFAULT_BOSS_EVENT_LOOP_GROUP;
public static final Resource<EventLoopGroup> DEFAULT_WORKER_EVENT_LOOP_GROUP;

Expand Down
@@ -1 +1,2 @@
io.grpc.netty.NettyChannelProvider
io.grpc.netty.UdsNettyChannelProvider
@@ -0,0 +1 @@
io.grpc.netty.UdsNameResolverProvider