Add BindingService.get*Binding(s)(String) API

There are some use-cases when we need to know upfront
if specific binding is really bound.
The goal is to prevent some security vulnerabilities
when too many unexpected dynamic bindings, e.g.
via router based on the `StreamBridge`.
The `BindingService` provides for us `getProducerBindingNames()`
 and `getConsumerBindingNames()` which are not optimal
 for the task to check for binding presence

* Introduce `BindingService.getProducerBinding(String bindingName)`
and `getConsumerBindings(String bindingName)` to cover a use-case
when we need to check for predefined bindings.
This API might be useful in other use-case when we need to get
access to managed bindings

Related to: https://github.com/spring-cloud/stream-applications/issues/330
This commit is contained in:
abilan
2023-01-20 15:15:34 -05:00
committed by Oleg Zhurakousky
parent 82a863d0f0
commit 64aef347e4
2 changed files with 21 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2022 the original author or authors.
* Copyright 2015-2023 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.
@@ -89,6 +89,7 @@ import static org.mockito.Mockito.when;
* @author Soby Chacko
* @author Michael Michailidis
* @author Chris Bono
* @author Artem Bilan
*/
public class BindingServiceTests {
@@ -123,12 +124,12 @@ public class BindingServiceTests {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
void testMultipleConsumerBindings() throws Exception {
void testMultipleConsumerBindings() {
BindingServiceProperties properties = new BindingServiceProperties();
Map<String, BindingProperties> bindingProperties = new HashMap<>();
BindingProperties props = new BindingProperties();
props.setDestination("foo,bar");
final String inputChannelName = "input";
String inputChannelName = "input";
bindingProperties.put(inputChannelName, props);
properties.setBindings(bindingProperties);
@@ -158,6 +159,8 @@ public class BindingServiceTests {
assertThat(binding1).isSameAs(mockBinding1);
assertThat(binding2).isSameAs(mockBinding2);
assertThat(service.getConsumerBindings("input")).containsSequence(bindings);
service.unbindConsumers("input");
verify(binder).bindConsumer(eq("foo"), isNull(), same(inputChannel),
@@ -522,6 +525,9 @@ public class BindingServiceTests {
delegate = TestUtils.getPropertyValue(binding, "delegate", Binding.class);
}
assertThat(delegate).isSameAs(mockBinding);
assertThat(service.getProducerBinding("output")).isSameAs(binding);
service.unbindProducers(outputChannelName);
verify(binder, times(2)).bindProducer(eq("foo"), same(outputChannel),
any(ProducerProperties.class));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2022 the original author or authors.
* Copyright 2015-2023 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.
@@ -55,12 +55,13 @@ import org.springframework.validation.DataBinder;
* @author Mark Fisher
* @author Dave Syer
* @author Marius Bogoevici
* @author Ilayaperumal Gopinathan`
* @author Ilayaperumal Gopinathan
* @author Gary Russell
* @author Janne Valkealahti
* @author Soby Chacko
* @author Michael Michailidis
* @author Chris Bono
* @author Artem Bilan
*/
public class BindingService {
@@ -320,10 +321,19 @@ public class BindingService {
return this.producerBindings.keySet().toArray(new String[] {});
}
@Nullable
public Binding<?> getProducerBinding(String bindingName) {
return this.producerBindings.get(bindingName);
}
public String[] getConsumerBindingNames() {
return this.consumerBindings.keySet().toArray(new String[] {});
}
public List<Binding<?>> getConsumerBindings(String bindingName) {
return this.consumerBindings.getOrDefault(bindingName, Collections.emptyList());
}
public <T> Binding<T> doBindProducer(T output, String bindingTarget,
Binder<T, ?, ProducerProperties> binder,
ProducerProperties producerProperties) {