Support Path Variables in Message Expressions
Extract path variables expressed in SimpDestinationMessageMatcher's pattern. Issue: gh-4469
This commit is contained in:
parent
fcd8a38f0b
commit
f97ac4daa6
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2018 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
|
||||||
|
*
|
||||||
|
* 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 org.springframework.security.messaging.access.expression;
|
||||||
|
|
||||||
|
import org.springframework.expression.EvaluationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
/**
|
||||||
|
* Allows post processing the {@link EvaluationContext}
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This API is intentionally kept package scope as it may evolve over time.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Daniel Bustamante Ospina
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
interface EvaluationContextPostProcessor<I> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows post processing of the {@link EvaluationContext}. Implementations
|
||||||
|
* may return a new instance of {@link EvaluationContext} or modify the
|
||||||
|
* {@link EvaluationContext} that was passed in.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* the original {@link EvaluationContext}
|
||||||
|
* @param invocation
|
||||||
|
* the security invocation object (i.e. Message)
|
||||||
|
* @return the upated context.
|
||||||
|
*/
|
||||||
|
EvaluationContext postProcess(EvaluationContext context, I invocation);
|
||||||
|
}
|
|
@ -48,6 +48,7 @@ public final class ExpressionBasedMessageSecurityMetadataSourceFactory {
|
||||||
* LinkedHashMap<MessageMatcher<?>,String> matcherToExpression = new LinkedHashMap<MessageMatcher<Object>,String>();
|
* LinkedHashMap<MessageMatcher<?>,String> matcherToExpression = new LinkedHashMap<MessageMatcher<Object>,String>();
|
||||||
* matcherToExpression.put(new SimDestinationMessageMatcher("/public/**"), "permitAll");
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/public/**"), "permitAll");
|
||||||
* matcherToExpression.put(new SimDestinationMessageMatcher("/admin/**"), "hasRole('ROLE_ADMIN')");
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/admin/**"), "hasRole('ROLE_ADMIN')");
|
||||||
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/topics/{name}/**"), "@someBean.customLogic(authentication, #name)");
|
||||||
* matcherToExpression.put(new SimDestinationMessageMatcher("/**"), "authenticated");
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/**"), "authenticated");
|
||||||
*
|
*
|
||||||
* MessageSecurityMetadataSource metadataSource = createExpressionMessageMetadataSource(matcherToExpression);
|
* MessageSecurityMetadataSource metadataSource = createExpressionMessageMetadataSource(matcherToExpression);
|
||||||
|
@ -82,6 +83,7 @@ public final class ExpressionBasedMessageSecurityMetadataSourceFactory {
|
||||||
* LinkedHashMap<MessageMatcher<?>,String> matcherToExpression = new LinkedHashMap<MessageMatcher<Object>,String>();
|
* LinkedHashMap<MessageMatcher<?>,String> matcherToExpression = new LinkedHashMap<MessageMatcher<Object>,String>();
|
||||||
* matcherToExpression.put(new SimDestinationMessageMatcher("/public/**"), "permitAll");
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/public/**"), "permitAll");
|
||||||
* matcherToExpression.put(new SimDestinationMessageMatcher("/admin/**"), "hasRole('ROLE_ADMIN')");
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/admin/**"), "hasRole('ROLE_ADMIN')");
|
||||||
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/topics/{name}/**"), "@someBean.customLogic(authentication, #name)");
|
||||||
* matcherToExpression.put(new SimDestinationMessageMatcher("/**"), "authenticated");
|
* matcherToExpression.put(new SimDestinationMessageMatcher("/**"), "authenticated");
|
||||||
*
|
*
|
||||||
* MessageSecurityMetadataSource metadataSource = createExpressionMessageMetadataSource(matcherToExpression);
|
* MessageSecurityMetadataSource metadataSource = createExpressionMessageMetadataSource(matcherToExpression);
|
||||||
|
@ -113,7 +115,7 @@ public final class ExpressionBasedMessageSecurityMetadataSourceFactory {
|
||||||
String rawExpression = entry.getValue();
|
String rawExpression = entry.getValue();
|
||||||
Expression expression = handler.getExpressionParser().parseExpression(
|
Expression expression = handler.getExpressionParser().parseExpression(
|
||||||
rawExpression);
|
rawExpression);
|
||||||
ConfigAttribute attribute = new MessageExpressionConfigAttribute(expression);
|
ConfigAttribute attribute = new MessageExpressionConfigAttribute(expression, matcher);
|
||||||
matcherToAttrs.put(matcher, Arrays.asList(attribute));
|
matcherToAttrs.put(matcher, Arrays.asList(attribute));
|
||||||
}
|
}
|
||||||
return new DefaultMessageSecurityMetadataSource(matcherToAttrs);
|
return new DefaultMessageSecurityMetadataSource(matcherToAttrs);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,32 +15,43 @@
|
||||||
*/
|
*/
|
||||||
package org.springframework.security.messaging.access.expression;
|
package org.springframework.security.messaging.access.expression;
|
||||||
|
|
||||||
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.messaging.Message;
|
import org.springframework.messaging.Message;
|
||||||
import org.springframework.security.access.ConfigAttribute;
|
import org.springframework.security.access.ConfigAttribute;
|
||||||
|
import org.springframework.security.messaging.util.matcher.MessageMatcher;
|
||||||
|
import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple expression configuration attribute for use in {@link Message} authorizations.
|
* Simple expression configuration attribute for use in {@link Message} authorizations.
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
* @author Daniel Bustamante Ospina
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
class MessageExpressionConfigAttribute implements ConfigAttribute {
|
class MessageExpressionConfigAttribute implements ConfigAttribute, EvaluationContextPostProcessor<Message<?>> {
|
||||||
private final Expression authorizeExpression;
|
private final Expression authorizeExpression;
|
||||||
|
private final MessageMatcher<?> matcher;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
*
|
*
|
||||||
* @param authorizeExpression the {@link Expression} to use. Cannot be null
|
* @param authorizeExpression the {@link Expression} to use. Cannot be null
|
||||||
|
* @param matcher the {@link MessageMatcher} used to match the messages.
|
||||||
*/
|
*/
|
||||||
public MessageExpressionConfigAttribute(Expression authorizeExpression) {
|
public MessageExpressionConfigAttribute(Expression authorizeExpression, MessageMatcher<?> matcher) {
|
||||||
Assert.notNull(authorizeExpression, "authorizeExpression cannot be null");
|
Assert.notNull(authorizeExpression, "authorizeExpression cannot be null");
|
||||||
|
Assert.notNull(matcher, "matcher cannot be null");
|
||||||
this.authorizeExpression = authorizeExpression;
|
this.authorizeExpression = authorizeExpression;
|
||||||
|
this.matcher = matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Expression getAuthorizeExpression() {
|
Expression getAuthorizeExpression() {
|
||||||
return authorizeExpression;
|
return authorizeExpression;
|
||||||
}
|
}
|
||||||
|
@ -53,4 +64,15 @@ class MessageExpressionConfigAttribute implements ConfigAttribute {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return authorizeExpression.getExpressionString();
|
return authorizeExpression.getExpressionString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EvaluationContext postProcess(EvaluationContext ctx, Message<?> message) {
|
||||||
|
if (matcher instanceof SimpDestinationMessageMatcher) {
|
||||||
|
final Map<String, String> variables = ((SimpDestinationMessageMatcher) matcher).extractPathVariables(message);
|
||||||
|
for (Map.Entry<String, String> entry : variables.entrySet()){
|
||||||
|
ctx.setVariable(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -35,6 +35,7 @@ import java.util.Collection;
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
* @author Rob Winch
|
* @author Rob Winch
|
||||||
|
* @author Daniel Bustamante Ospina
|
||||||
*/
|
*/
|
||||||
public class MessageExpressionVoter<T> implements AccessDecisionVoter<Message<T>> {
|
public class MessageExpressionVoter<T> implements AccessDecisionVoter<Message<T>> {
|
||||||
private SecurityExpressionHandler<Message<T>> expressionHandler = new DefaultMessageSecurityExpressionHandler<>();
|
private SecurityExpressionHandler<Message<T>> expressionHandler = new DefaultMessageSecurityExpressionHandler<>();
|
||||||
|
@ -53,6 +54,7 @@ public class MessageExpressionVoter<T> implements AccessDecisionVoter<Message<T>
|
||||||
|
|
||||||
EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication,
|
EvaluationContext ctx = expressionHandler.createEvaluationContext(authentication,
|
||||||
message);
|
message);
|
||||||
|
ctx = attr.postProcess(ctx, message);
|
||||||
|
|
||||||
return ExpressionUtils.evaluateAsBoolean(attr.getAuthorizeExpression(), ctx) ? ACCESS_GRANTED
|
return ExpressionUtils.evaluateAsBoolean(attr.getAuthorizeExpression(), ctx) ? ACCESS_GRANTED
|
||||||
: ACCESS_DENIED;
|
: ACCESS_DENIED;
|
||||||
|
|
|
@ -22,6 +22,9 @@ import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.PathMatcher;
|
import org.springframework.util.PathMatcher;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* MessageMatcher which compares a pre-defined pattern against the destination of a
|
* MessageMatcher which compares a pre-defined pattern against the destination of a
|
||||||
|
@ -129,6 +132,14 @@ public final class SimpDestinationMessageMatcher implements MessageMatcher<Objec
|
||||||
return destination != null && matcher.match(pattern, destination);
|
return destination != null && matcher.match(pattern, destination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Map<String, String> extractPathVariables(Message<? extends Object> message){
|
||||||
|
final String destination = SimpMessageHeaderAccessor.getDestination(message
|
||||||
|
.getHeaders());
|
||||||
|
return destination != null ? matcher.extractUriTemplateVariables(pattern, destination)
|
||||||
|
: Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
public MessageMatcher<Object> getMessageTypeMatcher() {
|
public MessageMatcher<Object> getMessageTypeMatcher() {
|
||||||
return messageTypeMatcher;
|
return messageTypeMatcher;
|
||||||
}
|
}
|
||||||
|
@ -175,4 +186,4 @@ public final class SimpDestinationMessageMatcher implements MessageMatcher<Objec
|
||||||
return new SimpDestinationMessageMatcher(pattern, SimpMessageType.MESSAGE,
|
return new SimpDestinationMessageMatcher(pattern, SimpMessageType.MESSAGE,
|
||||||
matcher);
|
matcher);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,26 +20,40 @@ import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.MockitoJUnitRunner;
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
|
import org.springframework.messaging.Message;
|
||||||
|
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
|
||||||
|
import org.springframework.messaging.support.MessageBuilder;
|
||||||
|
import org.springframework.security.messaging.util.matcher.MessageMatcher;
|
||||||
|
import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class MessageExpressionConfigAttributeTests {
|
public class MessageExpressionConfigAttributeTests {
|
||||||
@Mock
|
@Mock
|
||||||
Expression expression;
|
Expression expression;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
MessageMatcher<?> matcher;
|
||||||
|
|
||||||
MessageExpressionConfigAttribute attribute;
|
MessageExpressionConfigAttribute attribute;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
attribute = new MessageExpressionConfigAttribute(expression);
|
attribute = new MessageExpressionConfigAttribute(expression, matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void constructorNullExpression() {
|
public void constructorNullExpression() {
|
||||||
new MessageExpressionConfigAttribute(null);
|
new MessageExpressionConfigAttribute(null, matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void constructorNullMatcher() {
|
||||||
|
new MessageExpressionConfigAttribute(expression, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -58,4 +72,16 @@ public class MessageExpressionConfigAttributeTests {
|
||||||
|
|
||||||
assertThat(attribute.toString()).isEqualTo(expression.getExpressionString());
|
assertThat(attribute.toString()).isEqualTo(expression.getExpressionString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessContext() {
|
||||||
|
SimpDestinationMessageMatcher matcher = new SimpDestinationMessageMatcher("/topics/{topic}/**");
|
||||||
|
Message<?> message = MessageBuilder.withPayload("M").setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "/topics/someTopic/sub1").build();
|
||||||
|
EvaluationContext context = mock(EvaluationContext.class);
|
||||||
|
|
||||||
|
attribute = new MessageExpressionConfigAttribute(expression, matcher);
|
||||||
|
attribute.postProcess(context, message);
|
||||||
|
|
||||||
|
verify(context).setVariable("topic", "someTopic");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2016 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,6 +27,7 @@ import org.springframework.security.access.ConfigAttribute;
|
||||||
import org.springframework.security.access.SecurityConfig;
|
import org.springframework.security.access.SecurityConfig;
|
||||||
import org.springframework.security.access.expression.SecurityExpressionHandler;
|
import org.springframework.security.access.expression.SecurityExpressionHandler;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.messaging.util.matcher.MessageMatcher;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -45,6 +46,8 @@ public class MessageExpressionVoterTests {
|
||||||
@Mock
|
@Mock
|
||||||
Expression expression;
|
Expression expression;
|
||||||
@Mock
|
@Mock
|
||||||
|
MessageMatcher<?> matcher;
|
||||||
|
@Mock
|
||||||
SecurityExpressionHandler<Message> expressionHandler;
|
SecurityExpressionHandler<Message> expressionHandler;
|
||||||
@Mock
|
@Mock
|
||||||
EvaluationContext evaluationContext;
|
EvaluationContext evaluationContext;
|
||||||
|
@ -54,7 +57,7 @@ public class MessageExpressionVoterTests {
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
attributes = Arrays
|
attributes = Arrays
|
||||||
.<ConfigAttribute> asList(new MessageExpressionConfigAttribute(expression));
|
.<ConfigAttribute> asList(new MessageExpressionConfigAttribute(expression, matcher));
|
||||||
|
|
||||||
voter = new MessageExpressionVoter();
|
voter = new MessageExpressionVoter();
|
||||||
}
|
}
|
||||||
|
@ -99,7 +102,7 @@ public class MessageExpressionVoterTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void supportsMessageExpressionConfigAttributeTrue() {
|
public void supportsMessageExpressionConfigAttributeTrue() {
|
||||||
assertThat(voter.supports(new MessageExpressionConfigAttribute(expression)))
|
assertThat(voter.supports(new MessageExpressionConfigAttribute(expression, matcher)))
|
||||||
.isTrue();
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,4 +123,20 @@ public class MessageExpressionVoterTests {
|
||||||
|
|
||||||
verify(expressionHandler).createEvaluationContext(authentication, message);
|
verify(expressionHandler).createEvaluationContext(authentication, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void postProcessEvaluationContext(){
|
||||||
|
final MessageExpressionConfigAttribute configAttribute = mock(MessageExpressionConfigAttribute.class);
|
||||||
|
voter.setExpressionHandler(expressionHandler);
|
||||||
|
when(expressionHandler.createEvaluationContext(authentication, message)).thenReturn(evaluationContext);
|
||||||
|
when(configAttribute.getAuthorizeExpression()).thenReturn(expression);
|
||||||
|
attributes = Arrays.<ConfigAttribute> asList(configAttribute);
|
||||||
|
when(configAttribute.postProcess(evaluationContext, message)).thenReturn(evaluationContext);
|
||||||
|
when(expression.getValue(any(EvaluationContext.class), eq(Boolean.class)))
|
||||||
|
.thenReturn(true);
|
||||||
|
|
||||||
|
assertThat(voter.vote(authentication, message, attributes)).isEqualTo(
|
||||||
|
ACCESS_GRANTED);
|
||||||
|
verify(configAttribute).postProcess(evaluationContext, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,23 @@ public class SimpDestinationMessageMatcherTests {
|
||||||
assertThat(matcher.matches(messageBuilder.build())).isTrue();
|
assertThat(matcher.matches(messageBuilder.build())).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractPathVariablesFromDestination() throws Exception {
|
||||||
|
matcher = new SimpDestinationMessageMatcher("/topics/{topic}/**");
|
||||||
|
|
||||||
|
messageBuilder.setHeader(SimpMessageHeaderAccessor.DESTINATION_HEADER, "/topics/someTopic/sub1");
|
||||||
|
messageBuilder.setHeader(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER,
|
||||||
|
SimpMessageType.MESSAGE);
|
||||||
|
|
||||||
|
assertThat(matcher.extractPathVariables(messageBuilder.build()).get("topic")).isEqualTo("someTopic");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void extractedVariablesAreEmptyInNullDestination() throws Exception {
|
||||||
|
matcher = new SimpDestinationMessageMatcher("/topics/{topic}/**");
|
||||||
|
assertThat(matcher.extractPathVariables(messageBuilder.build())).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void typeConstructorParameterIsTransmitted() throws Exception {
|
public void typeConstructorParameterIsTransmitted() throws Exception {
|
||||||
matcher = SimpDestinationMessageMatcher.createMessageMatcher("/match",
|
matcher = SimpDestinationMessageMatcher.createMessageMatcher("/match",
|
||||||
|
@ -139,4 +156,4 @@ public class SimpDestinationMessageMatcherTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue