Skip to content

Commit

Permalink
Rename configurer to customizer
Browse files Browse the repository at this point in the history
This commit renames GrpcServerConfigurer to ServerBuilderCustomizer.
  • Loading branch information
onobc authored and dsyer committed Sep 26, 2024
1 parent 5f4fa52 commit e7fa570
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,46 @@
* 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 org.springframework.grpc.server;

import static java.util.Objects.requireNonNull;
package org.springframework.grpc.server;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.common.collect.Lists;

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.ServerServiceDefinition;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
* Default implementation of {@link GrpcServerFactory}.
*
* @param <T> the type of server builder
*/
public class DefaultGrpcServerFactory<T extends ServerBuilder<T>> implements GrpcServerFactory {

private static final String ANY_IP_ADDRESS = "*";

/** Logger available to subclasses. */
// VisibleForSubclass
protected final Log logger = LogFactory.getLog(getClass());

private final List<ServerServiceDefinition> serviceList = Lists.newLinkedList();

private final List<GrpcServerConfigurer> serverConfigurers;

private final String address;

private final int port;

public DefaultGrpcServerFactory(String address, int port, final List<GrpcServerConfigurer> serverConfigurers) {
this.serverConfigurers = requireNonNull(serverConfigurers, "serverConfigurers");
private final List<ServerBuilderCustomizer> serverBuilderCustomizers;

public DefaultGrpcServerFactory(String address, int port, List<ServerBuilderCustomizer> serverBuilderCustomizers) {
this.address = address;
this.port = port;
this.serverBuilderCustomizers = Objects.requireNonNull(serverBuilderCustomizers, "serverBuilderCustomizers");
}

protected String getAddress() {
Expand All @@ -62,11 +64,16 @@ protected int getPort() {

@Override
public Server createServer() {
final T builder = newServerBuilder();
configure(builder);
T builder = newServerBuilder();
configure(builder, this.serviceList);
return builder.build();
}

@Override
public void addService(ServerServiceDefinition service) {
this.serviceList.add(service);
}

/**
* Creates a new server builder.
* @return The newly created server builder.
Expand Down Expand Up @@ -113,38 +120,35 @@ else if (ShadedNettyServerFactoryHelper.isEpollAvailable()) {
}

/**
* Configures the given server builder. This method can be overwritten to add features
* that are not yet supported by this library or use a {@link GrpcServerConfigurer}
* instead.
* @param builder The server builder to configure.
* Configures the server builder by adding service definitions and applying
* customizers to the builder.
* <p>
* Subclasses can override this to add features that are not yet supported by this
* library.
* @param builder the server builder to configure
* @param serviceDefinitions the service definitions to add to the builder
*/
protected void configure(final T builder) {
configureServices(builder);
for (final GrpcServerConfigurer serverConfigurer : this.serverConfigurers) {
serverConfigurer.accept(builder);
}
protected void configure(T builder, List<ServerServiceDefinition> serviceDefinitions) {
configureServices(builder, serviceDefinitions);
this.serverBuilderCustomizers.forEach((c) -> c.customize(builder));
}

/**
* Configures the services that should be served by the server.
* @param builder The server builder to configure.
* Configure the services to be served by the server.
* @param builder the server builder to add the services to
* @param serviceDefinitions the service definitions to configure and add to the
* builder
*/
protected void configureServices(final T builder) {
final Set<String> serviceNames = new LinkedHashSet<>();

for (final ServerServiceDefinition service : this.serviceList) {
final String serviceName = service.getServiceDescriptor().getName();
protected void configureServices(T builder, List<ServerServiceDefinition> serviceDefinitions) {
Set<String> serviceNames = new LinkedHashSet<>();
serviceDefinitions.forEach((service) -> {
String serviceName = service.getServiceDescriptor().getName();
if (!serviceNames.add(serviceName)) {
throw new IllegalStateException("Found duplicate service implementation: " + serviceName);
}
logger.info("Registered gRPC service: " + serviceName);
builder.addService(service);
}
}

@Override
public void addService(final ServerServiceDefinition service) {
this.serviceList.add(service);
});
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2024 the original author or authors.
* Copyright 2024-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -12,7 +12,7 @@
* 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.
*
*
* Partial copy from net.devh:grpc-spring-boot-starter.
*/

Expand All @@ -21,10 +21,30 @@
import io.grpc.Server;
import io.grpc.ServerServiceDefinition;

import org.springframework.grpc.server.lifecycle.GrpcServerLifecycle;

/**
* Factory interface that can be used to create a {@link Server gRPC Server}.
*
* @author David Syer
* @author Chris Bono
*/
public interface GrpcServerFactory {

/**
* Gets a new fully configured but not started {@link Server} instance. Clients should
* not be able to connect to the returned server until {@link Server#start()} is
* called (which happens when the {@code GrpcServerLifecycle} is started).
* @return a fully configured not started {@link Server}
* @see GrpcServerLifecycle
*/
Server createServer();

/**
* Adds a service definition to the server. Must be called prior to
* {@link Server#start()}.
* @param service the service definition to add
*/
void addService(ServerServiceDefinition service);

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@
*/
package org.springframework.grpc.server;

import java.util.function.Consumer;

import io.grpc.ServerBuilder;

/**
* Callback interface that can be used to customize a {@link ServerBuilder}.
*
* @author Chris Bono
*/
@FunctionalInterface
public interface GrpcServerConfigurer extends Consumer<ServerBuilder<?>> {
public interface ServerBuilderCustomizer {

/**
* Callback to customize a {@link ServerBuilder} instance.
* @param serverBuilder the builder to customize
*/
void customize(ServerBuilder<?> serverBuilder);

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/
package org.springframework.grpc.autoconfigure.server;

import java.util.List;

import io.grpc.BindableService;

import org.springframework.beans.factory.ObjectProvider;
Expand All @@ -29,8 +27,8 @@
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.grpc.server.DefaultGrpcServerFactory;
import org.springframework.grpc.server.GrpcServerConfigurer;
import org.springframework.grpc.server.GrpcServerFactory;
import org.springframework.grpc.server.ServerBuilderCustomizer;
import org.springframework.grpc.server.lifecycle.GrpcServerLifecycle;

/**
Expand All @@ -57,9 +55,9 @@ public class GrpcServerAutoConfiguration {
@ConditionalOnMissingBean(GrpcServerFactory.class)
@Bean
DefaultGrpcServerFactory<?> defaultGrpcServerFactory(ObjectProvider<BindableService> grpcServicesProvider,
List<GrpcServerConfigurer> serverConfigurers) {
ObjectProvider<ServerBuilderCustomizer> builderCustomizersProvider) {
DefaultGrpcServerFactory<?> factory = new DefaultGrpcServerFactory<>(this.properties.getAddress(),
this.properties.getPort(), serverConfigurers);
this.properties.getPort(), builderCustomizersProvider.orderedStream().toList());
grpcServicesProvider.orderedStream().map(BindableService::bindService).forEach(factory::addService);
return factory;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@

import io.grpc.BindableService;
import io.grpc.ServerServiceDefinition;
import io.grpc.ServiceDescriptor;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.FilteredClassLoader;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.grpc.autoconfigure.server.GrpcServerAutoConfiguration;
import org.springframework.grpc.server.lifecycle.GrpcServerLifecycle;

Expand Down Expand Up @@ -89,7 +94,22 @@ void serverFactoryAutoConfiguredAsExpected() {
.run((context) -> assertThat(context).getBean(DefaultGrpcServerFactory.class)
.hasFieldOrPropertyWithValue("address", "myhost")
.hasFieldOrPropertyWithValue("port", 6160)
.hasFieldOrPropertyWithValue("serverConfigurers", List.of()));
.hasFieldOrPropertyWithValue("serverBuilderCustomizers", List.of())
.extracting("serviceList", InstanceOfAssertFactories.list(ServerServiceDefinition.class))
.singleElement()
.extracting(ServerServiceDefinition::getServiceDescriptor)
.extracting(ServiceDescriptor::getName)
.isEqualTo("my-service"));
}

@Test
void serverFactoryAutoConfiguredWithCustomizers() {
this.validContextRunner()
.withUserConfiguration(ServerFactoryCustomizersConfig.class)
.run((context) -> assertThat(context).getBean(DefaultGrpcServerFactory.class)
.extracting("serverBuilderCustomizers", InstanceOfAssertFactories.list(ServerBuilderCustomizer.class))
.containsExactly(ServerFactoryCustomizersConfig.CUSTOMIZER_BAR,
ServerFactoryCustomizersConfig.CUSTOMIZER_FOO));
}

@Test
Expand All @@ -99,4 +119,27 @@ void serverLifecycleAutoConfiguredAsExpected() {
.hasFieldOrPropertyWithValue("factory", context.getBean(DefaultGrpcServerFactory.class)));
}

@Configuration(proxyBeanMethods = false)
static class ServerFactoryCustomizersConfig {

static ServerBuilderCustomizer CUSTOMIZER_FOO = (serverBuilder) -> {
};

static ServerBuilderCustomizer CUSTOMIZER_BAR = (serverBuilder) -> {
};

@Bean
@Order(200)
ServerBuilderCustomizer customizerFoo() {
return CUSTOMIZER_FOO;
}

@Bean
@Order(100)
ServerBuilderCustomizer customizerBar() {
return CUSTOMIZER_BAR;
}

}

}

0 comments on commit e7fa570

Please sign in to comment.