mirror of https://github.com/apache/activemq.git
ClientIdFilterDispatchPolicy dispatches messages in a topic to a given client. Then the message with a PTP_CLIENTID property, can be received by a mqtt client with the same clientId. (#238)
This commit is contained in:
parent
5fcb388741
commit
b6ab868f94
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* 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.region.policy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.broker.region.MessageReference;
|
||||
import org.apache.activemq.broker.region.Subscription;
|
||||
import org.apache.activemq.command.ActiveMQDestination;
|
||||
import org.apache.activemq.filter.MessageEvaluationContext;
|
||||
|
||||
/**
|
||||
* ClientIdFilterDispatchPolicy dispatches messages in a topic to a given
|
||||
* client. Then the message with a "PTP_CLIENTID" property, can be received by a
|
||||
* mqtt client with the same clientId.
|
||||
*
|
||||
* @author kimmking (kimmking@163.com)
|
||||
* @date 2013-12-20
|
||||
* @org.apache.xbean.XBean
|
||||
*/
|
||||
public class ClientIdFilterDispatchPolicy extends SimpleDispatchPolicy {
|
||||
|
||||
public static final String PTP_CLIENTID = "PTP_CLIENTID";
|
||||
public static final String PTP_SUFFIX = ".PTP";
|
||||
|
||||
private String ptpClientId = PTP_CLIENTID;
|
||||
private String ptpSuffix = PTP_SUFFIX;
|
||||
|
||||
public boolean dispatch(MessageReference node, MessageEvaluationContext msgContext, List<Subscription> consumers) throws Exception {
|
||||
|
||||
Object _clientId = node.getMessage().getProperty(ptpClientId);
|
||||
if (_clientId == null) return super.dispatch(node, msgContext, consumers);
|
||||
|
||||
ActiveMQDestination _destination = node.getMessage().getDestination();
|
||||
int count = 0;
|
||||
for (Subscription sub : consumers) {
|
||||
// Don't deliver to browsers
|
||||
if (sub.getConsumerInfo().isBrowser()) {
|
||||
continue;
|
||||
}
|
||||
// Only dispatch to interested subscriptions
|
||||
if (!sub.matches(node, msgContext)) {
|
||||
sub.unmatched(node);
|
||||
continue;
|
||||
}
|
||||
if (_clientId != null && _destination.isTopic() && _clientId.equals(sub.getContext().getClientId())
|
||||
&& _destination.getQualifiedName().endsWith(this.ptpSuffix)) {
|
||||
sub.add(node);
|
||||
count++;
|
||||
} else {
|
||||
sub.unmatched(node);
|
||||
}
|
||||
}
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
public String getPtpClientId() {
|
||||
return ptpClientId;
|
||||
}
|
||||
|
||||
public void setPtpClientId(String ptpClientId) {
|
||||
this.ptpClientId = ptpClientId;
|
||||
}
|
||||
|
||||
public String getPtpSuffix() {
|
||||
return ptpSuffix;
|
||||
}
|
||||
|
||||
public void setPtpSuffix(String ptpSuffix) {
|
||||
this.ptpSuffix = ptpSuffix;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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.policy;
|
||||
|
||||
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||
import org.apache.activemq.broker.BrokerFactory;
|
||||
import org.apache.activemq.broker.BrokerService;
|
||||
import org.apache.activemq.broker.region.policy.*;
|
||||
import org.apache.activemq.command.ActiveMQTopic;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.BlockJUnit4ClassRunner;
|
||||
|
||||
import javax.jms.*;
|
||||
import java.net.URI;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@RunWith(BlockJUnit4ClassRunner.class)
|
||||
public class ClientIdFilterDispatchPolicyTest {
|
||||
|
||||
@Test
|
||||
public void testClientIdFilter() throws Exception {
|
||||
BrokerService broker = BrokerFactory.createBroker(new URI("broker://()/localhost?persistent=false&useJmx=true"));;
|
||||
|
||||
PolicyEntry policy = new PolicyEntry();
|
||||
policy.setDispatchPolicy(new ClientIdFilterDispatchPolicy());
|
||||
//policy.setSubscriptionRecoveryPolicy(new FixedCountSubscriptionRecoveryPolicy());
|
||||
PolicyMap pMap = new PolicyMap();
|
||||
pMap.setDefaultEntry(policy);
|
||||
broker.setDestinationPolicy(pMap);
|
||||
broker.start();
|
||||
|
||||
// test dispacth
|
||||
String topic = "test"+ClientIdFilterDispatchPolicy.PTP_SUFFIX;
|
||||
long timeout = 5000L;
|
||||
final Result r = new Result();
|
||||
|
||||
ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory("vm://localhost");
|
||||
// 1.consumer1
|
||||
Connection connection1 = cf.createConnection();
|
||||
connection1.setClientID("test1");
|
||||
connection1.start();
|
||||
Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer consumer1 = session1.createConsumer(new ActiveMQTopic(topic));
|
||||
consumer1.setMessageListener(
|
||||
new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
System.out.println(message.getStringProperty(ClientIdFilterDispatchPolicy.PTP_CLIENTID));
|
||||
String clientId = message.getStringProperty(ClientIdFilterDispatchPolicy.PTP_CLIENTID);
|
||||
//assertEquals("test1", clientId);
|
||||
r.test1 = clientId;
|
||||
r.count++;
|
||||
} catch (JMSException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 2.consumer2
|
||||
Connection connection2 = cf.createConnection();
|
||||
connection2.setClientID("test2");
|
||||
connection2.start();
|
||||
Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||
MessageConsumer consumer2 = session2.createConsumer(new ActiveMQTopic(topic));
|
||||
consumer2.setMessageListener(
|
||||
new MessageListener() {
|
||||
@Override
|
||||
public void onMessage(Message message) {
|
||||
try {
|
||||
System.out.println(message.getStringProperty(ClientIdFilterDispatchPolicy.PTP_CLIENTID));
|
||||
String clientId = message.getStringProperty(ClientIdFilterDispatchPolicy.PTP_CLIENTID);
|
||||
//assertEquals("test2", clientId);
|
||||
r.test2 = clientId;
|
||||
r.count++;
|
||||
} catch (JMSException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 3.producer
|
||||
Message m1 = session1.createTextMessage("test1");
|
||||
m1.setStringProperty(ClientIdFilterDispatchPolicy.PTP_CLIENTID, "test1");
|
||||
Message m2 = session1.createTextMessage("test2");
|
||||
m2.setStringProperty(ClientIdFilterDispatchPolicy.PTP_CLIENTID, "test2");
|
||||
Message m3 = session1.createTextMessage("test3");
|
||||
m3.setStringProperty(ClientIdFilterDispatchPolicy.PTP_CLIENTID, "test3");
|
||||
|
||||
MessageProducer producer = session1.createProducer(new ActiveMQTopic(topic));
|
||||
producer.send(m1);
|
||||
producer.send(m2);
|
||||
producer.send(m3);
|
||||
|
||||
long time = 0L;
|
||||
|
||||
while( r.count < 2 && time < timeout) {
|
||||
time += 50L;
|
||||
Thread.sleep(50L);
|
||||
}
|
||||
System.out.println(time);
|
||||
assertEquals(2,r.count);
|
||||
assertEquals("test1",r.test1);
|
||||
assertEquals("test2",r.test2);
|
||||
|
||||
producer.close();
|
||||
session1.close();
|
||||
connection1.stop();
|
||||
session2.close();;
|
||||
connection2.close();
|
||||
broker.stop();
|
||||
}
|
||||
|
||||
public static class Result{
|
||||
int count;
|
||||
public String test1;
|
||||
public String test2;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue