Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3387,7 +3387,7 @@
}

@Override
public ConfigurationImpl setTemporaryQueueNamespace(final String temporaryQueueNamespace) {

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (21)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (25)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (17)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (17)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (17)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (25)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (21)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3390 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (21)

setTemporaryQueueNamespace(java.lang.String) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal
return setUuidNamespace(temporaryQueueNamespace);
}

Expand Down Expand Up @@ -3425,12 +3425,12 @@
}

@Override
public long getMqttSessionStatePersistenceTimeout() {

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (21)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (25)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (17)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (17)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (17)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (25)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (21)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3428 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (21)

getMqttSessionStatePersistenceTimeout() in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal
return mqttSessionStatePersistenceTimeout;
}

@Override
public Configuration setMqttSessionStatePersistenceTimeout(long mqttSessionStatePersistenceTimeout) {

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (21)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (25)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (17)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (17)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (17)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Test (25)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (21)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal

Check warning on line 3433 in artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

View workflow job for this annotation

GitHub Actions / Checks (21)

setMqttSessionStatePersistenceTimeout(long) in org.apache.activemq.artemis.core.config.Configuration has been deprecated and marked for removal
this.mqttSessionStatePersistenceTimeout = mqttSessionStatePersistenceTimeout;
return this;
}
Expand Down Expand Up @@ -3950,15 +3950,29 @@
put(discriminatorKey, String.valueOf(classDiscriminator));
}

// process scalar entries before nested maps — scalar setters must complete
// before nested property resolution triggers getters that may lazily depend on
// sibling scalar values (e.g., uri must be set before transportConfigurations
// is accessed, because getTransportConfigurations() lazily calls parseURI())
loadYamlEntries(keySurroundString, parentKey, map, false);
loadYamlEntries(keySurroundString, parentKey, map, true);
}

@SuppressWarnings("unchecked")
private void loadYamlEntries(String keySurroundString, String parentKey, Map<String, Object> map, boolean parseMaps) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
Object value = entry.getValue();
boolean isMap = value instanceof Map;
if (isMap != parseMaps) {
continue;
}
String key = entry.getKey();
if (JSON_CLASS_DISCRIMINATOR_KEY.equals(key)) {
continue;
}
key = autoSurroundIfNecessary(key, keySurroundString);
String propertyKey = parentKey + key;
Object value = entry.getValue();
if (value instanceof Map) {
if (isMap) {
loadYamlMap(keySurroundString, propertyKey + ".", (Map<String, Object>) value);
} else if (value instanceof List<?> list) {
put(propertyKey, list.stream()
Expand Down Expand Up @@ -3990,13 +4004,26 @@
put(discriminatorKey, jsonObject.getString(JSON_CLASS_DISCRIMINATOR_KEY));
}

// process scalar entries before nested objects — scalar setters must complete
// before nested property resolution triggers getters that may lazily depend on
// sibling scalar values (e.g., uri must be set before transportConfigurations
// is accessed, because getTransportConfigurations() lazily calls parseURI())
loadJsonEntries(keySurroundString, parentKey, jsonObject, false);
loadJsonEntries(keySurroundString, parentKey, jsonObject, true);
}

private void loadJsonEntries(String keySurroundString, String parentKey, JsonObject jsonObject, boolean parseObjects) {
jsonObject.entrySet().stream().forEach(jsonEntry -> {
String jsonKey = jsonEntry.getKey();
if (JSON_CLASS_DISCRIMINATOR_KEY.equals(jsonKey)) {
return;
}
JsonValue jsonValue = jsonEntry.getValue();
JsonValue.ValueType jsonValueType = jsonValue.getValueType();
boolean isObject = jsonValueType == JsonValue.ValueType.OBJECT;
if (isObject != parseObjects) {
return;
}
jsonKey = autoSurroundIfNecessary(jsonKey, keySurroundString);
String propertyKey = parentKey + jsonKey;
switch (jsonValueType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,9 +455,10 @@ public void testAddressSettings() {

@Test
public void testAMQPConnections() {
assertEquals(1, configuration.getAMQPConnections().size());
AMQPBrokerConnectConfiguration amqp = configuration.getAMQPConnections().get(0);
assertEquals("mirror-target", amqp.getName());
assertEquals(2, configuration.getAMQPConnections().size());
AMQPBrokerConnectConfiguration amqp = configuration.getAMQPConnections().stream()
.filter(c -> "mirror-target".equals(c.getName())).findFirst().orElse(null);
assertNotNull(amqp);
assertEquals("tcp://mirror-host:5672", amqp.getUri());
assertEquals(5000, amqp.getRetryInterval());
assertEquals(-1, amqp.getReconnectAttempts());
Expand All @@ -475,6 +476,27 @@ public void testAMQPConnections() {
assertEquals("orders", mirror.getAddressFilter());
assertTrue(mirror.isSync());
assertEquals("mirrorVal1", mirror.getProperties().get("mirrorProp1"));

AMQPBrokerConnectConfiguration reversed = configuration.getAMQPConnections().stream()
.filter(c -> "reversed-order-target".equals(c.getName())).findFirst().orElse(null);
assertNotNull(reversed, "reversed-order-target AMQP connection must load even with objects before scalars in JSON/YAML");
assertEquals("tcp://reversed-host:5672", reversed.getUri());
assertEquals(10000, reversed.getRetryInterval());
assertEquals(5, reversed.getReconnectAttempts());
assertEquals("reversed-user", reversed.getUser());
assertEquals("reversed-password", reversed.getPassword());
assertTrue(reversed.isAutostart());

assertEquals(1, reversed.getConnectionElements().size());
assertTrue(reversed.getConnectionElements().get(0) instanceof AMQPMirrorBrokerConnectionElement);
AMQPMirrorBrokerConnectionElement mirrorReversed = (AMQPMirrorBrokerConnectionElement) reversed.getConnectionElements().get(0);
assertEquals("mirror-reversed", mirrorReversed.getName());
assertFalse(mirrorReversed.isMessageAcknowledgements());
assertTrue(mirrorReversed.isQueueCreation());
assertTrue(mirrorReversed.isQueueRemoval());
assertEquals("events", mirrorReversed.getAddressFilter());
assertFalse(mirrorReversed.isSync());
assertEquals("reversedVal1", mirrorReversed.getProperties().get("reversedProp1"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2625,6 +2625,43 @@ public void testJsonNeedsInsertionOrder() throws Exception {
assertEquals(4, configuration.getAMQPConnections().get(0).getTransportConfigurations().get(0).getParams().size());
}

@Test
public void testJsonAMQPConnectionUriOrderIndependent() throws Exception {
// transportConfigurations appears BEFORE uri in JSON — this simulates what happens
// when a JSON serializer sorts keys alphabetically (e.g., Go's json.Marshal),
// since "transportConfigurations" < "uri" lexically.
// Without the scalars-before-objects fix, getTransportConfigurations() lazily calls
// parseURI() before uri is set, causing trustStorePassword to be silently lost.
File tmpFile = File.createTempFile("amqp-uri-order-test", ".json", temporaryFolder);
try (FileOutputStream fileOutputStream = new FileOutputStream(tmpFile);
PrintWriter printWriter = new PrintWriter(fileOutputStream)) {

printWriter.write("{\n");
printWriter.write(" \"AMQPConnections\" : {\n");
printWriter.write(" \"target\" : {\n");
printWriter.write(" \"transportConfigurations\" : {\n");
printWriter.write(" \"target\" : {\n");
printWriter.write(" \"params\" : { \"trustStorePassword\" : \"pass\"\n }\n");
printWriter.write(" }\n");
printWriter.write(" },\n");
printWriter.write(" \"uri\" : \"tcp://host:6449?trustStorePath=/client.ts\"\n");
printWriter.write(" }\n");
printWriter.write(" }\n");
printWriter.write("}\n");
}

ConfigurationImpl configuration = new ConfigurationImpl();
configuration.parseProperties(tmpFile.getAbsolutePath());

String matchNoErrors = "\"errors\":\\[]";
assertEquals(3, configuration.getStatus().split(matchNoErrors, 10).length, configuration.getStatus());

Map<String, Object> params = configuration.getAMQPConnections().get(0).getTransportConfigurations().get(0).getParams();
assertEquals(4, params.size(), "Expected 4 params: host, port, trustStorePath (from URI), trustStorePassword (explicit)");
assertEquals("/client.ts", params.get("trustStorePath"));
assertEquals("pass", params.get("trustStorePassword"));
}

@Test
public void testTextPropertiesReaderFromFile() throws Exception {
List<String> textProperties = buildSimpleConfigTextList();
Expand Down
21 changes: 21 additions & 0 deletions artemis-server/src/test/resources/broker-full-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,27 @@
}
}
}
},
"reversed-order-target": {
"mirrors": {
"mirror-reversed": {
"properties": {
"reversedProp1": "reversedVal1"
},
"type": "MIRROR",
"messageAcknowledgements": false,
"queueCreation": true,
"queueRemoval": true,
"addressFilter": "events",
"sync": false
}
},
"uri": "tcp://reversed-host:5672",
"retryInterval": 10000,
"reconnectAttempts": 5,
"user": "reversed-user",
"password": "reversed-password",
"autostart": true
}
},

Expand Down
17 changes: 17 additions & 0 deletions artemis-server/src/test/resources/broker-full-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,23 @@ AMQPConnections:
sync: true
properties:
mirrorProp1: "mirrorVal1"
reversed-order-target:
mirrors:
mirror-reversed:
properties:
reversedProp1: "reversedVal1"
type: "MIRROR"
messageAcknowledgements: false
queueCreation: true
queueRemoval: true
addressFilter: "events"
sync: false
uri: "tcp://reversed-host:5672"
retryInterval: 10000
reconnectAttempts: 5
user: "reversed-user"
password: "reversed-password"
autostart: true

HAPolicyConfiguration: "PRIMARY_ONLY"

Expand Down
Loading