mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-3204 - support for non-standard destination path separator
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1078766 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
815b789eeb
commit
008b3e551c
|
@ -61,7 +61,7 @@ public final class AdvisorySupport {
|
|||
public static final String MSG_PROPERTY_DISCARDED_COUNT = "discardedCount";
|
||||
|
||||
public static final ActiveMQTopic TEMP_DESTINATION_COMPOSITE_ADVISORY_TOPIC = new ActiveMQTopic(
|
||||
TEMP_QUEUE_ADVISORY_TOPIC + "," + TEMP_TOPIC_ADVISORY_TOPIC);
|
||||
TEMP_QUEUE_ADVISORY_TOPIC.getPhysicalName() + "," + TEMP_TOPIC_ADVISORY_TOPIC.getPhysicalName());
|
||||
private static final ActiveMQTopic AGENT_TOPIC_DESTINATION = new ActiveMQTopic(AGENT_TOPIC);
|
||||
|
||||
private AdvisorySupport() {
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.apache.activemq.broker.util;
|
||||
|
||||
import org.apache.activemq.broker.BrokerPluginSupport;
|
||||
import org.apache.activemq.broker.ConnectionContext;
|
||||
import org.apache.activemq.broker.ConsumerBrokerExchange;
|
||||
import org.apache.activemq.broker.ProducerBrokerExchange;
|
||||
import org.apache.activemq.broker.region.Destination;
|
||||
import org.apache.activemq.broker.region.Subscription;
|
||||
import org.apache.activemq.command.*;
|
||||
import org.apache.activemq.filter.DestinationPath;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/*
|
||||
* @org.apache.xbean.XBean element="destinationPathSeparatorPlugin"
|
||||
*/
|
||||
|
||||
public class DestinationPathSeparatorBroker extends BrokerPluginSupport {
|
||||
|
||||
String pathSeparator = "/";
|
||||
|
||||
protected ActiveMQDestination convertDestination(ActiveMQDestination destination) {
|
||||
if (destination.getPhysicalName().contains(pathSeparator)) {
|
||||
List<String> l = new ArrayList<String>();
|
||||
StringTokenizer iter = new StringTokenizer(destination.getPhysicalName(), pathSeparator);
|
||||
while (iter.hasMoreTokens()) {
|
||||
String name = iter.nextToken().trim();
|
||||
if (name.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
l.add(name);
|
||||
}
|
||||
|
||||
String newName = DestinationPath.toString(l.toArray(new String[l.size()]));
|
||||
return ActiveMQDestination.createDestination(newName, destination.getDestinationType());
|
||||
} else {
|
||||
return destination;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void acknowledge(ConsumerBrokerExchange consumerExchange, MessageAck ack) throws Exception {
|
||||
ack.setDestination(convertDestination(ack.getDestination()));
|
||||
super.acknowledge(consumerExchange, ack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Subscription addConsumer(ConnectionContext context, ConsumerInfo info) throws Exception {
|
||||
info.setDestination(convertDestination(info.getDestination()));
|
||||
return super.addConsumer(context, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addProducer(ConnectionContext context, ProducerInfo info) throws Exception {
|
||||
info.setDestination(convertDestination(info.getDestination()));
|
||||
super.addProducer(context, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeConsumer(ConnectionContext context, ConsumerInfo info) throws Exception {
|
||||
info.setDestination(convertDestination(info.getDestination()));
|
||||
super.removeConsumer(context, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProducer(ConnectionContext context, ProducerInfo info) throws Exception {
|
||||
info.setDestination(convertDestination(info.getDestination()));
|
||||
super.removeProducer(context, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(ProducerBrokerExchange producerExchange, Message messageSend) throws Exception {
|
||||
messageSend.setDestination(convertDestination(messageSend.getDestination()));
|
||||
super.send(producerExchange, messageSend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Destination addDestination(ConnectionContext context, ActiveMQDestination destination, boolean createIfTemporary) throws Exception {
|
||||
return super.addDestination(context, convertDestination(destination), createIfTemporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
|
||||
super.removeDestination(context, convertDestination(destination), timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDestinationInfo(ConnectionContext context, DestinationInfo info) throws Exception {
|
||||
info.setDestination(convertDestination(info.getDestination()));
|
||||
super.addDestinationInfo(context, info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDestinationInfo(ConnectionContext context, DestinationInfo info) throws Exception {
|
||||
info.setDestination(convertDestination(info.getDestination()));
|
||||
super.removeDestinationInfo(context, info);
|
||||
}
|
||||
|
||||
public void setPathSeparator(String pathSeparator) {
|
||||
this.pathSeparator = pathSeparator;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.apache.activemq.security;
|
||||
|
||||
import junit.framework.Test;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.command.ActiveMQQueue;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
|
||||
public class SimpleAuthenticationPluginSeparatorTest extends SimpleAuthenticationPluginTest {
|
||||
|
||||
public static Test suite() {
|
||||
return suite(SimpleAuthenticationPluginSeparatorTest.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BrokerService createBroker() throws Exception {
|
||||
return createBroker("org/apache/activemq/security/simple-auth-separator.xml");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestUserReceiveFails() {
|
||||
addCombinationValues("userName", new Object[] {"user"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("TEST"), new ActiveMQTopic("TEST"), new ActiveMQQueue("GUEST/BAR"), new ActiveMQTopic("GUEST/BAR")});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestInvalidAuthentication() {
|
||||
addCombinationValues("userName", new Object[] {"user"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestUserReceiveSucceeds() {
|
||||
addCombinationValues("userName", new Object[] {"user"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("USERS/FOO"), new ActiveMQTopic("USERS/FOO")});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestGuestReceiveSucceeds() {
|
||||
addCombinationValues("userName", new Object[] {"guest"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("GUEST/BAR"), new ActiveMQTopic("GUEST/BAR")});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link org.apache.activemq.CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestGuestReceiveFails() {
|
||||
addCombinationValues("userName", new Object[] {"guest"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("TEST"), new ActiveMQTopic("TEST"), new ActiveMQQueue("USERS/FOO"), new ActiveMQTopic("USERS/FOO") });
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link org.apache.activemq.CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestUserSendSucceeds() {
|
||||
addCombinationValues("userName", new Object[] {"user"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("USERS/FOO"), new ActiveMQQueue("GUEST/BAR"), new ActiveMQTopic("USERS/FOO"),
|
||||
new ActiveMQTopic("GUEST/BAR")});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link org.apache.activemq.CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestUserSendFails() {
|
||||
addCombinationValues("userName", new Object[] {"user"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("TEST"), new ActiveMQTopic("TEST")});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link org.apache.activemq.CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestGuestSendFails() {
|
||||
addCombinationValues("userName", new Object[] {"guest"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("TEST"), new ActiveMQTopic("TEST"), new ActiveMQQueue("USERS/FOO"), new ActiveMQTopic("USERS/FOO")});
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link org.apache.activemq.CombinationTestSupport}
|
||||
*/
|
||||
public void initCombosForTestGuestSendSucceeds() {
|
||||
addCombinationValues("userName", new Object[] {"guest"});
|
||||
addCombinationValues("password", new Object[] {"password"});
|
||||
addCombinationValues("destination", new Object[] {new ActiveMQQueue("GUEST/BAR"), new ActiveMQTopic("GUEST/BAR")});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!-- this file can only be parsed using the xbean-spring library -->
|
||||
<!-- START SNIPPET: example -->
|
||||
<beans
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:amq="http://activemq.apache.org/schema/core"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
|
||||
|
||||
<bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
|
||||
<property name="algorithm" value="PBEWithMD5AndDES"/>
|
||||
<property name="password" value="activemq"/>
|
||||
</bean>
|
||||
|
||||
<bean id="propertyConfigurer" class="org.jasypt.spring.properties.EncryptablePropertyPlaceholderConfigurer">
|
||||
<constructor-arg ref="configurationEncryptor" />
|
||||
<property name="location" value="classpath:credentials.properties"/>
|
||||
</bean>
|
||||
|
||||
<broker useJmx="true" persistent="false" xmlns="http://activemq.apache.org/schema/core" populateJMSXUserID="true">
|
||||
|
||||
<destinations>
|
||||
<queue physicalName="TEST.Q" />
|
||||
</destinations>
|
||||
|
||||
<!-- Use a non-default port in case the default port is in use -->
|
||||
<managementContext>
|
||||
<managementContext connectorPort="1199"/>
|
||||
</managementContext>
|
||||
|
||||
<plugins>
|
||||
<simpleAuthenticationPlugin>
|
||||
<users>
|
||||
<authenticationUser username="system" password="${activemq.password}"
|
||||
groups="users,admins"/>
|
||||
<authenticationUser username="user" password="${guest.password}"
|
||||
groups="users"/>
|
||||
<authenticationUser username="guest" password="${guest.password}" groups="guests"/>
|
||||
</users>
|
||||
</simpleAuthenticationPlugin>
|
||||
|
||||
|
||||
<!-- lets configure a destination based authorization mechanism -->
|
||||
<authorizationPlugin>
|
||||
<map>
|
||||
<authorizationMap>
|
||||
<authorizationEntries>
|
||||
<authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
|
||||
<authorizationEntry queue="USERS.>" read="users" write="users" admin="users" />
|
||||
<authorizationEntry queue="GUEST.>" read="guests" write="guests,users" admin="guests,users" />
|
||||
|
||||
<authorizationEntry queue="TEST.Q" read="guests" write="guests" />
|
||||
|
||||
<authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
|
||||
<authorizationEntry topic="USERS.>" read="users" write="users" admin="users" />
|
||||
<authorizationEntry topic="GUEST.>" read="guests" write="guests,users" admin="guests,users" />
|
||||
|
||||
<authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users" admin="guests,users"/>
|
||||
</authorizationEntries>
|
||||
<tempDestinationAuthorizationEntry>
|
||||
<tempDestinationAuthorizationEntry read="admin" write="admin" admin="admin"/>
|
||||
</tempDestinationAuthorizationEntry>
|
||||
</authorizationMap>
|
||||
</map>
|
||||
</authorizationPlugin>
|
||||
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.broker.util.DestinationPathSeparatorBroker"/>
|
||||
</plugins>
|
||||
</broker>
|
||||
|
||||
</beans>
|
Loading…
Reference in New Issue