diff --git a/spring-web/src/main/java/org/springframework/web/service/registry/HttpServiceProxyRegistryFactoryBean.java b/spring-web/src/main/java/org/springframework/web/service/registry/HttpServiceProxyRegistryFactoryBean.java index d4272156528..ba95d1d3481 100644 --- a/spring-web/src/main/java/org/springframework/web/service/registry/HttpServiceProxyRegistryFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/web/service/registry/HttpServiceProxyRegistryFactoryBean.java @@ -221,7 +221,7 @@ public final class HttpServiceProxyRegistryFactoryBean @Override public String toString() { - return getClass().getSimpleName() + "[id=" + name() + "]"; + return getClass().getSimpleName() + "[name=" + name() + "]"; } } @@ -234,21 +234,24 @@ public final class HttpServiceProxyRegistryFactoryBean private final Set groups; + private final Predicate defaultFilter; + private Predicate filter; DefaultGroups(Set groups, HttpServiceGroup.ClientType clientType) { this.groups = groups; - this.filter = group -> group.clientType().equals(clientType); + this.defaultFilter = (group -> group.clientType().equals(clientType)); + this.filter = this.defaultFilter; } @Override public HttpServiceGroupConfigurer.Groups filterByName(String... groupNames) { - return filter(group -> Arrays.stream(groupNames).anyMatch(id -> id.equals(group.name()))); + return filter(group -> Arrays.stream(groupNames).anyMatch(name -> name.equals(group.name()))); } @Override public HttpServiceGroupConfigurer.Groups filter(Predicate predicate) { - this.filter = this.filter.or(predicate); + this.filter = this.filter.and(predicate); return this; } @@ -274,8 +277,11 @@ public final class HttpServiceProxyRegistryFactoryBean BiConsumer clientConfigurer, BiConsumer proxyFactoryConfigurer) { - this.groups.stream().filter(this.filter).forEach(group -> - group.apply(clientConfigurer, proxyFactoryConfigurer)); + this.groups.stream().filter(this.filter) + .forEach(group -> group.apply(clientConfigurer, proxyFactoryConfigurer)); + + // Reset filter + this.filter = this.defaultFilter; } } diff --git a/spring-web/src/test/java/org/springframework/web/service/registry/HttpServiceProxyRegistryFactoryBeanTests.java b/spring-web/src/test/java/org/springframework/web/service/registry/HttpServiceProxyRegistryFactoryBeanTests.java new file mode 100644 index 00000000000..694d6b83edb --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/service/registry/HttpServiceProxyRegistryFactoryBeanTests.java @@ -0,0 +1,99 @@ +/* + * Copyright 2002-2025 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. + */ + +package org.springframework.web.service.registry; + +import java.util.List; +import java.util.function.Predicate; + +import org.junit.jupiter.api.Test; + +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClient; +import org.springframework.web.client.support.RestClientHttpServiceGroupConfigurer; +import org.springframework.web.service.registry.echo.EchoA; +import org.springframework.web.service.registry.echo.EchoB; +import org.springframework.web.service.registry.greeting.GreetingA; +import org.springframework.web.service.registry.greeting.GreetingB; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Unit tests for {@link HttpServiceProxyRegistryFactoryBean}. + * @author Rossen Stoyanchev + */ +public class HttpServiceProxyRegistryFactoryBeanTests { + + @Test + void twoGroups() { + + GroupsMetadata groupsMetadata = new GroupsMetadata(); + + String echoName = "echo"; + String greetingName = "greeting"; + + groupsMetadata.getOrCreateGroup(echoName, HttpServiceGroup.ClientType.REST_CLIENT) + .httpServiceTypeNames().addAll(List.of(EchoA.class.getName(), EchoB.class.getName())); + + groupsMetadata.getOrCreateGroup(greetingName, HttpServiceGroup.ClientType.REST_CLIENT) + .httpServiceTypeNames().addAll(List.of(GreetingA.class.getName(), GreetingB.class.getName())); + + Predicate echoFilter = group -> group.name().equals(echoName); + Predicate greetingFilter = group -> group.name().equals(greetingName); + + TestConfigurer testConfigurer = new TestConfigurer(List.of(echoFilter, greetingFilter)); + + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); + applicationContext.registerBean(TestConfigurer.class, () -> testConfigurer); + applicationContext.refresh(); + + HttpServiceProxyRegistryFactoryBean factoryBean = new HttpServiceProxyRegistryFactoryBean(groupsMetadata); + factoryBean.setApplicationContext(applicationContext); + factoryBean.setBeanClassLoader(getClass().getClassLoader()); + factoryBean.afterPropertiesSet(); + + HttpServiceProxyRegistry registry = factoryBean.getObject(); + assertThat(registry.getGroupNames()).containsExactlyInAnyOrder(echoName, greetingName); + assertThat(registry.getClientTypesInGroup(echoName)).containsExactlyInAnyOrder(EchoA.class, EchoB.class); + assertThat(registry.getClientTypesInGroup(greetingName)).containsExactlyInAnyOrder(GreetingA.class, GreetingB.class); + + assertThat(testConfigurer.invocations) + .containsKeys(echoFilter, greetingFilter) + .containsEntry(echoFilter, List.of(echoName)) + .containsEntry(greetingFilter, List.of(greetingName)); + } + + + private static class TestConfigurer implements RestClientHttpServiceGroupConfigurer { + + private final List> filters; + + private final MultiValueMap, String> invocations = new LinkedMultiValueMap<>(); + + TestConfigurer(List> filters) { + this.filters = filters; + } + + @Override + public void configureGroups(Groups groups) { + filters.forEach(filter -> groups.filter(filter) + .configureClient((group, builder) -> invocations.add(filter, group.name()))); + } + } + +}