Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ClientInterceptorsConfigurer implements InitializingBean {

private final ApplicationContext applicationContext;

private List<ClientInterceptor> globalInterceptors;
private List<ClientInterceptor> globalInterceptors = new ArrayList<>();

public ClientInterceptorsConfigurer(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class DefaultGrpcChannelFactory<T extends ManagedChannelBuilder<T>>

private final ClientInterceptorsConfigurer interceptorsConfigurer;

private ClientInterceptorFilter interceptorFilter;
private @Nullable ClientInterceptorFilter interceptorFilter;

private ChannelCredentialsProvider credentials = ChannelCredentialsProvider.INSECURE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.jspecify.annotations.Nullable;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
Expand All @@ -39,6 +42,7 @@
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.grpc.internal.ClasspathScanner;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
Expand All @@ -59,7 +63,7 @@ public class GrpcClientFactory implements ApplicationContextAware {

private Map<Class<?>, StubFactory<?>> factories = new LinkedHashMap<>();

private ApplicationContext context;
private @Nullable ApplicationContext context;

static {
DEFAULT_FACTORIES.add((Class<? extends StubFactory<?>>) BlockingStubFactory.class);
Expand All @@ -74,6 +78,10 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
this.context = applicationContext;
}

private ApplicationContext requireNonNullContext() {
return Objects.requireNonNull(this.context, "ApplicationContext is required");
}

public <T> T getClient(String target, Class<T> type, Class<?> factory) {
@SuppressWarnings("unchecked")
StubFactory<T> stubs = (StubFactory<T>) findFactory(factory, type);
Expand All @@ -84,7 +92,7 @@ public <T> T getClient(String target, Class<T> type, Class<?> factory) {
private StubFactory<?> findFactory(Class<?> factoryType, Class<?> type) {
if (this.factories.isEmpty()) {
List<StubFactory<?>> factories = new ArrayList<>();
for (StubFactory<?> factory : this.context.getBeansOfType(StubFactory.class).values()) {
for (StubFactory<?> factory : this.requireNonNullContext().getBeansOfType(StubFactory.class).values()) {
factories.add(factory);
}
AnnotationAwareOrderComparator.sort(factories);
Expand All @@ -96,7 +104,9 @@ private StubFactory<?> findFactory(Class<?> factoryType, Class<?> type) {
continue;
}
this.factories.put(factory,
(StubFactory<?>) this.context.getAutowireCapableBeanFactory().createBean(factory));
(StubFactory<?>) this.requireNonNullContext()
.getAutowireCapableBeanFactory()
.createBean(factory));
}
}
StubFactory<?> factory = findFactory(this.factories, factoryType, type);
Expand All @@ -107,7 +117,8 @@ private StubFactory<?> findFactory(Class<?> factoryType, Class<?> type) {
return factory;
}

private static Class<?> findDefaultFactory(BeanDefinitionRegistry registry, Class<?> factoryType, Class<?> type) {
private static @Nullable Class<?> findDefaultFactory(BeanDefinitionRegistry registry,
@Nullable Class<?> factoryType, Class<?> type) {
if (factoryType != null && factoryType != UnspecifiedStubFactory.class) {
return supports(factoryType, type) ? factoryType : null;
}
Expand All @@ -131,6 +142,8 @@ private static Set<Class<?>> locateFactoryTypes(BeanDefinitionRegistry registry)
beanDefinition = (AbstractBeanDefinition) registry.getBeanDefinition(FACTORIES_BEAN_DEFINITION_NAME);
@SuppressWarnings("unchecked")
Set<Class<?>> factories = (Set<Class<?>>) beanDefinition.getAttribute("factories");
Assert.notEmpty(factories,
"The %s bean requires a 'factories' attribute".formatted(FACTORIES_BEAN_DEFINITION_NAME));
return factories;

}
Expand All @@ -152,7 +165,7 @@ public static HashSet<Class<?>> findStubFactoryTypes(BeanDefinitionRegistry regi
return factories;
}

private static Class<?> resolveBeanClass(BeanDefinition beanDefinition) {
private static @Nullable Class<?> resolveBeanClass(BeanDefinition beanDefinition) {
if (beanDefinition instanceof AbstractBeanDefinition rootBeanDefinition) {
if (rootBeanDefinition.hasBeanClass()) {
return rootBeanDefinition.getBeanClass();
Expand All @@ -161,6 +174,7 @@ private static Class<?> resolveBeanClass(BeanDefinition beanDefinition) {
return null;
}

@SuppressWarnings("NullAway")
private static boolean supports(Class<?> factory, Class<?> type) {
// To avoid needing to instantiate the factory we use reflection to check for a
// static supports() method. If it exists we call it.
Expand All @@ -186,7 +200,7 @@ private static boolean supports(Class<?> factory, Class<?> type) {
return supports;
}

private static StubFactory<?> findFactory(Map<Class<?>, StubFactory<?>> values, Class<?> factoryType,
private static @Nullable StubFactory<?> findFactory(Map<Class<?>, StubFactory<?>> values, Class<?> factoryType,
Class<?> type) {
StubFactory<?> factory = null;
if (factoryType != null && factoryType != UnspecifiedStubFactory.class) {
Expand All @@ -204,7 +218,7 @@ private static StubFactory<?> findFactory(Map<Class<?>, StubFactory<?>> values,
}

private GrpcChannelFactory channels() {
return this.context.getBean(GrpcChannelFactory.class);
return this.requireNonNullContext().getBean(GrpcChannelFactory.class);
}

public static void register(BeanDefinitionRegistry registry, GrpcClientRegistrationSpec spec) {
Expand All @@ -230,8 +244,8 @@ public static void register(BeanDefinitionRegistry registry, GrpcClientRegistrat
}
}

public record GrpcClientRegistrationSpec(String prefix, Class<? extends StubFactory<?>> factory, String target,
Class<?>[] types, String[] packages) {
public record GrpcClientRegistrationSpec(String prefix, @Nullable Class<? extends StubFactory<?>> factory,
String target, Class<?>[] types, String[] packages) {

private static ClasspathScanner SCANNER = new ClasspathScanner();

Expand Down Expand Up @@ -276,7 +290,7 @@ public GrpcClientRegistrationSpec(String prefix, String target, Class<?>[] types
this(prefix, UnspecifiedStubFactory.class, target, types, new String[0]);
}

public GrpcClientRegistrationSpec factory(Class<? extends StubFactory<?>> factory) {
public GrpcClientRegistrationSpec factory(@Nullable Class<? extends StubFactory<?>> factory) {
return new GrpcClientRegistrationSpec(this.prefix, factory, this.target, this.types, this.packages);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2025-present 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.
* You may obtain a copy of the License at
*
* https://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.
*/

/**
* AOT (Ahead-Of-Time) processing for gRPC clients.
*/
@NullMarked
package org.springframework.grpc.client.aot;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2025-present 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.
* You may obtain a copy of the License at
*
* https://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.
*/

/**
* gRPC client interceptors.
*/
@NullMarked
package org.springframework.grpc.client.interceptor;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2025-present 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.
* You may obtain a copy of the License at
*
* https://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.
*/

/**
* Security-related gRPC client interceptors.
*/
@NullMarked
package org.springframework.grpc.client.interceptor.security;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2025-present 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.
* You may obtain a copy of the License at
*
* https://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.
*/

/**
* gRPC client infrastructure.
*/
@NullMarked
package org.springframework.grpc.client;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;

import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.context.ResourceLoaderAware;
Expand All @@ -49,9 +50,9 @@ public class ClasspathScanner implements ResourceLoaderAware {

private String resourcePattern = DEFAULT_RESOURCE_PATTERN;

private ResourcePatternResolver resourcePatternResolver;
private @Nullable ResourcePatternResolver resourcePatternResolver;

private MetadataReaderFactory metadataReaderFactory;
private @Nullable MetadataReaderFactory metadataReaderFactory;

@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2025-present 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.
* You may obtain a copy of the License at
*
* https://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.
*/

/**
* Internal utilities and helpers.
*/
@NullMarked
package org.springframework.grpc.internal;

import org.jspecify.annotations.NullMarked;
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,24 @@ public class DefaultGrpcServerFactory<T extends ServerBuilder<T>> implements Grp

private final List<ServerBuilderCustomizer<T>> serverBuilderCustomizers;

private KeyManagerFactory keyManager;
private @Nullable KeyManagerFactory keyManager;

private TrustManagerFactory trustManager;
private @Nullable TrustManagerFactory trustManager;

private ClientAuth clientAuth;
private @Nullable ClientAuth clientAuth;

private ServerServiceDefinitionFilter serviceFilter;
private @Nullable ServerServiceDefinitionFilter serviceFilter;

private ServerInterceptorFilter interceptorFilter;
private @Nullable ServerInterceptorFilter interceptorFilter;

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

public DefaultGrpcServerFactory(String address, List<ServerBuilderCustomizer<T>> serverBuilderCustomizers,
KeyManagerFactory keyManager, TrustManagerFactory trustManager, ClientAuth clientAuth) {
@Nullable KeyManagerFactory keyManager, @Nullable TrustManagerFactory trustManager,
@Nullable ClientAuth clientAuth) {
this(address, serverBuilderCustomizers);
this.keyManager = keyManager;
this.trustManager = trustManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;

import org.jspecify.annotations.Nullable;

import io.grpc.TlsServerCredentials.ClientAuth;
import io.grpc.netty.NettyServerBuilder;
import io.netty.channel.MultiThreadIoEventLoopGroup;
Expand All @@ -38,8 +40,9 @@
public class NettyGrpcServerFactory extends DefaultGrpcServerFactory<NettyServerBuilder> {

public NettyGrpcServerFactory(String address,
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers, KeyManagerFactory keyManager,
TrustManagerFactory trustManager, ClientAuth clientAuth) {
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers,
@Nullable KeyManagerFactory keyManager, @Nullable TrustManagerFactory trustManager,
@Nullable ClientAuth clientAuth) {
super(address, serverBuilderCustomizers, keyManager, trustManager, clientAuth);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;

import org.jspecify.annotations.Nullable;

import io.grpc.TlsServerCredentials.ClientAuth;
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;
import io.grpc.netty.shaded.io.netty.channel.epoll.EpollEventLoopGroup;
Expand All @@ -37,8 +39,9 @@
public class ShadedNettyGrpcServerFactory extends DefaultGrpcServerFactory<NettyServerBuilder> {

public ShadedNettyGrpcServerFactory(String address,
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers, KeyManagerFactory keyManager,
TrustManagerFactory trustManager, ClientAuth clientAuth) {
List<ServerBuilderCustomizer<NettyServerBuilder>> serverBuilderCustomizers,
@Nullable KeyManagerFactory keyManager, @Nullable TrustManagerFactory trustManager,
@Nullable ClientAuth clientAuth) {
super(address, serverBuilderCustomizers, keyManager, trustManager, clientAuth);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.springframework.grpc.server.exception;

import org.jspecify.annotations.Nullable;

import io.grpc.StatusException;

public class CompositeGrpcExceptionHandler implements GrpcExceptionHandler {
Expand All @@ -27,7 +29,7 @@ public CompositeGrpcExceptionHandler(GrpcExceptionHandler... exceptionHandlers)
}

@Override
public StatusException handleException(Throwable exception) {
public @Nullable StatusException handleException(Throwable exception) {
for (GrpcExceptionHandler exceptionHandler : this.exceptionHandlers) {
StatusException status = exceptionHandler.handleException(exception);
if (status != null) {
Expand Down
Loading
Loading