Skip to content

Commit ee98a00

Browse files
committed
ARTEMIS-5911 Ensure core federation ignores AMQP federation configuration
When parsing the Core federation XML elements we need to ensure that AMQP broker connections with federation configuration does not get picked up as that creates empty configuration entries in the broker configuration.
1 parent 3856ce5 commit ee98a00

File tree

2 files changed

+205
-4
lines changed

2 files changed

+205
-4
lines changed

artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -670,12 +670,21 @@ public void parseMainConfig(final Element e, final Configuration config) throws
670670
}
671671
}
672672

673-
NodeList fedNodes = e.getElementsByTagName("federation");
673+
// Ensure AMQP federation configuration isn't picked up here by core federation
674+
// configuration parsing, any AMQP federation configuration would generate empty
675+
// Core federation configurations that would not create active federations.
676+
NodeList federations = e.getElementsByTagName("federations");
674677

675-
for (int i = 0; i < fedNodes.getLength(); i++) {
676-
Element fedNode = (Element) fedNodes.item(i);
678+
for (int i = 0; i < federations.getLength(); i++) {
679+
Element federationElement = (Element) federations.item(i);
677680

678-
parseFederationConfiguration(fedNode, config);
681+
for (int j = 0; j < federationElement.getChildNodes().getLength(); ++j) {
682+
Node node = federationElement.getChildNodes().item(j);
683+
684+
if (node.getNodeName().equalsIgnoreCase("federation")) {
685+
parseFederationConfiguration((Element) node, config);
686+
}
687+
}
679688
}
680689

681690
NodeList gaNodes = e.getElementsByTagName("grouping-handler");

artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationParserTest.java

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import java.util.Map;
3535
import java.util.Set;
3636
import java.util.concurrent.TimeUnit;
37+
import java.util.function.Function;
38+
import java.util.stream.Collectors;
3739

3840
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
3941
import org.apache.activemq.artemis.api.core.SimpleString;
@@ -501,6 +503,196 @@ public void testDefaultBridgeProducerWindowSize() throws Exception {
501503
assertEquals(ActiveMQDefaultConfiguration.getDefaultBridgeProducerWindowSize(), bconfig.getProducerWindowSize());
502504
}
503505

506+
@Test
507+
public void testCoreFederationIgnoresAMQPFederationConfigurations() throws Exception {
508+
FileConfigurationParser parser = new FileConfigurationParser();
509+
String middlePart = """
510+
<broker-connections>
511+
<amqp-connection uri="tcp://test1:111" name="test1" retry-interval="333" reconnect-attempts="33" user="testuser" password="testpassword">
512+
<federation>
513+
<local-queue-policy name="federation5" priority-adjustment="1" include-federated="false">
514+
<include address-match="test" queue-match="tracking" />
515+
</local-queue-policy>
516+
</federation>
517+
</amqp-connection>
518+
<amqp-connection uri="tcp://federation" name="federation6" auto-start="false">
519+
<federation>
520+
<local-queue-policy name="lqp1" priority-adjustment="1" include-federated="false">
521+
<include address-match="test" queue-match="tracking" />
522+
<property key="amqpCredits" value="1"/>
523+
<transformer-class-name>class-another</transformer-class-name>
524+
</local-queue-policy>
525+
<remote-queue-policy name="rqp1" priority-adjustment="-1" include-federated="true">
526+
<include address-match="#" queue-match="tracking" />
527+
<property key="amqpCredits" value="2"/>
528+
<property key="amqpLowCredits" value="1"/>
529+
</remote-queue-policy>
530+
<local-address-policy name="lap1" auto-delete="false" auto-delete-delay="1" auto-delete-message-count="12" max-hops="2" enable-divert-bindings="true">
531+
<include address-match="orders" />
532+
<exclude address-match="all.#" />
533+
<transformer-class-name>class-name</transformer-class-name>
534+
</local-address-policy>
535+
<local-queue-policy name="lqp2">
536+
<include address-match="address" queue-match="theQueue" />
537+
<transformer-class-name>class-another</transformer-class-name>
538+
</local-queue-policy>
539+
<remote-address-policy name="rap1" auto-delete="true" auto-delete-delay="2" auto-delete-message-count="42" max-hops="1" enable-divert-bindings="false">
540+
<include address-match="support" />
541+
<property key="amqpCredits" value="2"/>
542+
<property key="amqpLowCredits" value="1"/>
543+
<transformer>
544+
<class-name>something</class-name>
545+
<property key="key1" value="value1"/>
546+
<property key="key2" value="value2"/>
547+
</transformer>
548+
</remote-address-policy>
549+
<property key="amqpCredits" value="7"/>
550+
<property key="amqpLowCredits" value="1"/>
551+
</federation>
552+
</amqp-connection>
553+
</broker-connections>
554+
<federations>
555+
<federation name="federation1">
556+
<upstream name="eu-west-1" user="westuser" password="32a10275cf4ab4e9">
557+
<static-connectors>
558+
<connector-ref>connector1</connector-ref>
559+
</static-connectors>
560+
<policy ref="policySetA"/>
561+
</upstream>
562+
<upstream name="eu-east-1" user="eastuser" password="32a10275cf4ab4e9">
563+
<ha>true</ha>
564+
<discovery-group-ref discovery-group-name="dg1"/>
565+
<policy ref="policySetA"/>
566+
</upstream>
567+
<policy-set name="policySetA">
568+
<policy ref="address-federation" />
569+
<policy ref="queue-federation" />
570+
</policy-set>
571+
<queue-policy name="queue-federation" >
572+
<exclude queue-match="the_queue" address-match="#" />
573+
</queue-policy>
574+
<address-policy name="address-federation" >
575+
<include address-match="the_address" />
576+
</address-policy>
577+
</federation>
578+
<federation name="federation2" user="globaluser" password="32a10275cf4ab4e9">
579+
<upstream name="usa-west-1">
580+
<static-connectors>
581+
<connector-ref>connector1</connector-ref>
582+
</static-connectors>
583+
<policy ref="address-federation-usa"/>
584+
</upstream>
585+
<upstream name="usa-east-1" >
586+
<ha>true</ha>
587+
<discovery-group-ref discovery-group-name="dg1"/>
588+
<policy ref="queue-federation-usa"/>
589+
</upstream>
590+
<queue-policy name="queue-federation-usa" >
591+
<exclude queue-match="the_queue" address-match="#" />
592+
</queue-policy>
593+
<address-policy name="address-federation-usa" >
594+
<include address-match="the_address" />
595+
</address-policy>
596+
</federation>
597+
<federation name="federation3" user="globaluser" password="32a10275cf4ab4e9">
598+
<upstream name="asia-1">
599+
<static-connectors>
600+
<connector-ref>connector1</connector-ref>
601+
</static-connectors>
602+
<policy ref="queue-federation-asia"/>
603+
<policy ref="address-federation-asia"/>
604+
</upstream>
605+
<upstream name="asia-2" >
606+
<ha>true</ha>
607+
<discovery-group-ref discovery-group-name="dg1"/>
608+
<policy ref="queue-federation-asia"/>
609+
<policy ref="address-federation-asia"/>
610+
</upstream>
611+
<queue-policy name="queue-federation-asia" transformer-ref="federation-transformer-3" >
612+
<exclude queue-match="the_queue" address-match="#" />
613+
</queue-policy>
614+
<address-policy name="address-federation-asia" transformer-ref="federation-transformer-3" >
615+
<include address-match="the_address" />
616+
</address-policy>
617+
<transformer name="federation-transformer-3">
618+
<class-name>org.foo.FederationTransformer3</class-name>
619+
<property key="federationTransformerKey1" value="federationTransformerValue1"/>
620+
<property key="federationTransformerKey2" value="federationTransformerValue2"/>
621+
</transformer>
622+
</federation>
623+
<federation name="federation4" user="globaluser" password="32a10275cf4ab4e9">
624+
<upstream name="asia-3">
625+
<static-connectors>
626+
<connector-ref>connector1</connector-ref>
627+
</static-connectors>
628+
<policy ref="queue-federation-asia"/>
629+
<policy ref="address-federation-asia"/>
630+
</upstream>
631+
<downstream name="asia-4" >
632+
<ha>true</ha>
633+
<discovery-group-ref discovery-group-name="dg1"/>
634+
<policy ref="queue-federation-asia"/>
635+
<policy ref="address-federation-asia"/>
636+
<upstream-connector-ref>connector1</upstream-connector-ref>
637+
</downstream>
638+
<queue-policy name="queue-federation-asia2" transformer-ref="federation-transformer-4" >
639+
<exclude queue-match="the_queue" address-match="#" />
640+
</queue-policy>
641+
<address-policy name="address-federation-asia2" transformer-ref="federation-transformer-4" >
642+
<include address-match="the_address" />
643+
</address-policy>
644+
<transformer name="federation-transformer-4">
645+
<class-name>org.foo.FederationTransformer4</class-name>
646+
<property key="federationTransformerKey1" value="federationTransformerValue1"/>
647+
<property key="federationTransformerKey2" value="federationTransformerValue2"/>
648+
</transformer>
649+
</federation>
650+
</federations>""";
651+
652+
String configStr = FIRST_PART + middlePart + LAST_PART;
653+
ByteArrayInputStream input = new ByteArrayInputStream(configStr.getBytes(StandardCharsets.UTF_8));
654+
655+
Configuration config = parser.parseMainConfig(input);
656+
657+
assertEquals(4, config.getFederationConfigurations().size());
658+
659+
final Map<String, FederationConfiguration> federations =
660+
config.getFederationConfigurations().stream()
661+
.collect(Collectors.toMap(c -> c.getName(), Function.identity()));
662+
663+
assertTrue(federations.containsKey("federation1"));
664+
665+
final FederationConfiguration configuration1 = federations.get("federation1");
666+
667+
assertEquals(2, configuration1.getUpstreamConfigurations().size());
668+
assertEquals(0, configuration1.getDownstreamConfigurations().size());
669+
assertEquals(0, configuration1.getTransformerConfigurations().size());
670+
671+
assertTrue(federations.containsKey("federation2"));
672+
673+
final FederationConfiguration configuration2 = federations.get("federation3");
674+
675+
assertEquals(2, configuration2.getUpstreamConfigurations().size());
676+
assertEquals(0, configuration2.getDownstreamConfigurations().size());
677+
assertEquals(1, configuration2.getTransformerConfigurations().size());
678+
679+
assertTrue(federations.containsKey("federation3"));
680+
681+
final FederationConfiguration configuration3 = federations.get("federation3");
682+
683+
assertEquals(2, configuration3.getUpstreamConfigurations().size());
684+
assertEquals(0, configuration3.getDownstreamConfigurations().size());
685+
assertEquals(1, configuration3.getTransformerConfigurations().size());
686+
687+
assertTrue(federations.containsKey("federation4"));
688+
689+
final FederationConfiguration configuration4 = federations.get("federation4");
690+
691+
assertEquals(1, configuration4.getUpstreamConfigurations().size());
692+
assertEquals(1, configuration4.getDownstreamConfigurations().size());
693+
assertEquals(1, configuration4.getTransformerConfigurations().size());
694+
}
695+
504696
@Test
505697
public void testParsingOverflowPageSize() throws Exception {
506698
testParsingOverFlow("""

0 commit comments

Comments
 (0)