|
30 | 30 | import java.util.concurrent.atomic.AtomicInteger;
|
31 | 31 |
|
32 | 32 | import org.apache.activemq.artemis.api.core.ActiveMQException;
|
| 33 | +import org.apache.activemq.artemis.api.core.ActiveMQExceptionType; |
33 | 34 | import org.apache.activemq.artemis.api.core.Message;
|
34 | 35 | import org.apache.activemq.artemis.api.core.SimpleString;
|
35 | 36 | import org.apache.activemq.artemis.api.core.client.ClientConsumer;
|
|
43 | 44 | import org.apache.activemq.artemis.core.postoffice.Binding;
|
44 | 45 | import org.apache.activemq.artemis.core.postoffice.Bindings;
|
45 | 46 | import org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding;
|
| 47 | +import org.apache.activemq.artemis.core.server.ActiveMQMessageBundle; |
46 | 48 | import org.apache.activemq.artemis.core.server.cluster.MessageFlowRecord;
|
47 | 49 | import org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding;
|
48 | 50 | import org.apache.activemq.artemis.core.server.cluster.impl.BridgeTestAccessor;
|
@@ -413,6 +415,107 @@ public void testPauseAddressBlockingSnFQueue() throws Exception {
|
413 | 415 | stopServers(0, 1);
|
414 | 416 | }
|
415 | 417 |
|
| 418 | + @Test |
| 419 | + public void testBadClientSendMessagesToSnFQueue() throws Exception { |
| 420 | + setupServer(0, isFileStorage(), isNetty()); |
| 421 | + setupServer(1, isFileStorage(), isNetty()); |
| 422 | + |
| 423 | + setupClusterConnection("cluster0", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 0, 1); |
| 424 | + |
| 425 | + setupClusterConnection("cluster1", "queues", MessageLoadBalancingType.ON_DEMAND, 1, isNetty(), 1, 0); |
| 426 | + |
| 427 | + String dla = "DLA"; |
| 428 | + AddressSettings addressSettings = new AddressSettings(); |
| 429 | + addressSettings.setDeadLetterAddress(SimpleString.of(dla)); |
| 430 | + |
| 431 | + servers[0].getAddressSettingsRepository().addMatch("#", addressSettings); |
| 432 | + servers[1].getAddressSettingsRepository().addMatch("#", addressSettings); |
| 433 | + |
| 434 | + startServers(0, 1); |
| 435 | + |
| 436 | + setupSessionFactory(0, isNetty()); |
| 437 | + setupSessionFactory(1, isNetty()); |
| 438 | + |
| 439 | + createQueue(0, dla, dla, null, true); |
| 440 | + createQueue(1, dla, dla, null, true); |
| 441 | + |
| 442 | + waitForBindings(0, dla, 1, 0, true); |
| 443 | + waitForBindings(1, dla, 1, 0, true); |
| 444 | + |
| 445 | + ClientSession session0 = sfs[0].createSession(); |
| 446 | + ClientSession session1 = sfs[1].createSession(); |
| 447 | + |
| 448 | + session0.start(); |
| 449 | + session1.start(); |
| 450 | + |
| 451 | + final int num = 10; |
| 452 | + |
| 453 | + SimpleString nodeId1 = servers[1].getNodeID(); |
| 454 | + ClusterConnectionImpl cc0 = (ClusterConnectionImpl) servers[0].getClusterManager().getClusterConnection("cluster0"); |
| 455 | + SimpleString snfQueue0 = cc0.getSfQueueName(nodeId1.toString()); |
| 456 | + |
| 457 | + ClientProducer badProducer0 = session0.createProducer(snfQueue0); |
| 458 | + for (int i = 0; i < num; i++) { |
| 459 | + Message msg = session0.createMessage(true); |
| 460 | + msg.putStringProperty("origin", "from producer 0"); |
| 461 | + badProducer0.send(msg); |
| 462 | + } |
| 463 | + |
| 464 | + //add a remote queue and consumer to enable message to flow from node 0 to node 1 |
| 465 | + createQueue(1, "queues.testaddress", "queue0", null, true); |
| 466 | + ClientConsumer consumer1 = session1.createConsumer("queue0"); |
| 467 | + |
| 468 | + waitForBindings(0, "queues.testaddress", 0, 0, true); |
| 469 | + waitForBindings(1, "queues.testaddress", 1, 1, true); |
| 470 | + |
| 471 | + waitForBindings(0, "queues.testaddress", 1, 1, false); |
| 472 | + waitForBindings(1, "queues.testaddress", 0, 0, false); |
| 473 | + |
| 474 | + ClientConsumer dlqConsumer = session0.createConsumer(dla); |
| 475 | + |
| 476 | + for (int i = 0; i < num; i++) { |
| 477 | + Message msg = session0.createMessage(true); |
| 478 | + msg.putStringProperty("origin", "from producer 0"); |
| 479 | + badProducer0.send(msg); |
| 480 | + } |
| 481 | + |
| 482 | + //messages will never reache the consumer |
| 483 | + assertNull(consumer1.receiveImmediate()); |
| 484 | + |
| 485 | + SimpleString idsHeaderName = Message.HDR_ROUTE_TO_IDS.concat(snfQueue0); |
| 486 | + for (int i = 0; i < num * 2; i++) { |
| 487 | + ClientMessage m = dlqConsumer.receive(5000); |
| 488 | + assertNotNull(m); |
| 489 | + String propValue = m.getStringProperty("origin"); |
| 490 | + assertEquals("from producer 0", propValue); |
| 491 | + propValue = m.getStringProperty(Message.HDR_ROUTE_DLQ_DETAIL); |
| 492 | + ActiveMQException expected = ActiveMQExceptionType.INVALID_MESSAGE_EXCEPTION.createException(ActiveMQMessageBundle.BUNDLE.messageMissingHeader(idsHeaderName)); |
| 493 | + assertEquals(expected.toString(), propValue); |
| 494 | + m.acknowledge(); |
| 495 | + } |
| 496 | + assertNull(dlqConsumer.receiveImmediate()); |
| 497 | + |
| 498 | + //normal message flow should work |
| 499 | + ClientProducer goodProducer0 = session0.createProducer("queues.testaddress"); |
| 500 | + for (int i = 0; i < num; i++) { |
| 501 | + Message msg = session0.createMessage(true); |
| 502 | + msg.putStringProperty("origin", "from producer 0"); |
| 503 | + goodProducer0.send(msg); |
| 504 | + } |
| 505 | + |
| 506 | + //consumer1 can receive from node0 |
| 507 | + for (int i = 0; i < num; i++) { |
| 508 | + ClientMessage m = consumer1.receive(5000); |
| 509 | + assertNotNull(m); |
| 510 | + String propValue = m.getStringProperty("origin"); |
| 511 | + assertEquals("from producer 0", propValue); |
| 512 | + m.acknowledge(); |
| 513 | + } |
| 514 | + assertNull(consumer1.receiveImmediate()); |
| 515 | + |
| 516 | + stopServers(0, 1); |
| 517 | + } |
| 518 | + |
416 | 519 | @Override
|
417 | 520 | @AfterEach
|
418 | 521 | public void tearDown() throws Exception {
|
|
0 commit comments