diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java index 32b1600add3..4b0c1773d09 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/logs/AuditLogger.java @@ -2859,4 +2859,11 @@ static void getTotalSessionCount(Object source) { @LogMessage(id = 601797, value = "User {} is getting total session count on target resource: {}", level = LogMessage.Level.INFO) void getTotalSessionCount(String user, Object source); + + static void exportConfigAsProperties(Object source) { + BASE_LOGGER.exportConfigAsProperties(getCaller(), source); + } + + @LogMessage(id = 601798, value = "User {} is exporting configuration as properties on target resource: {}", level = LogMessage.Level.INFO) + void exportConfigAsProperties(String user, Object source); } diff --git a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/FluentPropertyBeanIntrospectorWithIgnores.java b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/FluentPropertyBeanIntrospectorWithIgnores.java index 4ab1c4bad58..31ff14d3789 100644 --- a/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/FluentPropertyBeanIntrospectorWithIgnores.java +++ b/artemis-commons/src/main/java/org/apache/activemq/artemis/utils/uri/FluentPropertyBeanIntrospectorWithIgnores.java @@ -36,13 +36,13 @@ public class FluentPropertyBeanIntrospectorWithIgnores extends FluentPropertyBea private static ConcurrentHashSet> ignores = new ConcurrentHashSet<>(); - public static void addIgnore(String className, String propertyName) { - logger.trace("Adding ignore on {}/{}", className, propertyName); - ignores.add(new Pair<>(className, propertyName)); + public static void addIgnore(String className, String methodName) { + logger.trace("Adding ignore on {}/{}", className, methodName); + ignores.add(new Pair<>(className, methodName)); } - public static boolean isIgnored(String className, String propertyName) { - return ignores.contains(new Pair<>(className, propertyName)); + public static boolean isIgnored(String className, String methodName) { + return ignores.contains(new Pair<>(className, methodName)); } @Override @@ -72,6 +72,15 @@ private void introspect(IntrospectionContext icontext, Method writeMethod, Strin if (pd != null) { readMethod = pd.getReadMethod(); } + if (readMethod == null) { + try { + if (writeMethod != null && writeMethod.getParameterTypes().length == 1 && writeMethod.getParameterTypes()[0].equals(Boolean.class)) { + // is methods with Boolean return are not valid bean accessors but our fluent classes use them + readMethod = icontext.getTargetClass().getMethod("is" + capitalise(propertyName), null); + } + } catch (NoSuchMethodException ignored) { + } + } try { PropertyDescriptor withFluentWrite = createFluentPropertyDescriptor(readMethod, writeMethod, propertyName); icontext.addPropertyDescriptor(withFluentWrite); @@ -80,6 +89,13 @@ private void introspect(IntrospectionContext icontext, Method writeMethod, Strin } } + private String capitalise(String name) { + if (name.length() > 1) { + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + return name; + } + private PropertyDescriptor createFluentPropertyDescriptor(Method readMethod, Method writeMethod, String propertyName) throws IntrospectionException { return new PropertyDescriptor(propertyName, readMethod, writeMethod); } diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java index 3b41e6b2ed6..307ec0af2d4 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/management/ActiveMQServerControl.java @@ -2090,5 +2090,8 @@ void replay(@Parameter(name = "startScanDate", desc = "Start date where we will @Attribute(desc = AUTHORIZATION_FAILURE_COUNT) long getAuthorizationFailureCount(); + + @Operation(desc = "Export the broker configuration as properties", impact = MBeanOperationInfo.ACTION) + void exportConfigAsProperties() throws Exception; } diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationAddressPolicyConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationAddressPolicyConfiguration.java index fd6aa3bb6d1..16f2c13e3f3 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationAddressPolicyConfiguration.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationAddressPolicyConfiguration.java @@ -177,6 +177,9 @@ public static class Matcher implements Serializable { private String name; public String getName() { + if (name == null) { + return addressMatch; + } return name; } diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationQueuePolicyConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationQueuePolicyConfiguration.java index 6b93de81f48..116d405a87a 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationQueuePolicyConfiguration.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/config/federation/FederationQueuePolicyConfiguration.java @@ -139,6 +139,9 @@ public static class Matcher implements Serializable { private String name; public String getName() { + if (name == null) { + return addressMatch + queueMatch; + } return name; } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java index 501ae3b53ea..9dde060a20f 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java @@ -1198,7 +1198,7 @@ Configuration addDiscoveryGroupConfiguration(String key, Configuration setMaskPassword(Boolean maskPassword); /** - * If passwords are masked. True means the passwords are masked.enableda + * If passwords are masked. True means the passwords are masked. */ Boolean isMaskPassword(); @@ -1504,4 +1504,6 @@ default String resolvePropertiesSources(String propertiesFileUrl) { Configuration setMirrorAckManagerWarnUnacked(boolean warnUnacked); boolean isMirrorAckManagerWarnUnacked(); + + void exportAsProperties(File to) throws Exception; } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectConfiguration.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectConfiguration.java index 009f9c198f3..527c0240251 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectConfiguration.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectConfiguration.java @@ -83,8 +83,7 @@ public List getMirrors() { return connectionElements; } - public AMQPBrokerConnectConfiguration addPeer(AMQPBrokerConnectionElement element) { - element.setType(AMQPBrokerConnectionAddressType.PEER); + public AMQPBrokerConnectConfiguration addPeer(AMQPPeerBrokerConnectionElement element) { return addElement(element); } @@ -92,8 +91,7 @@ public List getPeers() { return connectionElements; } - public AMQPBrokerConnectConfiguration addSender(AMQPBrokerConnectionElement element) { - element.setType(AMQPBrokerConnectionAddressType.SENDER); + public AMQPBrokerConnectConfiguration addSender(AMQPSenderBrokerConnectionElement element) { return addElement(element); } @@ -101,8 +99,7 @@ public List getSenders() { return connectionElements; } - public AMQPBrokerConnectConfiguration addReceiver(AMQPBrokerConnectionElement element) { - element.setType(AMQPBrokerConnectionAddressType.RECEIVER); + public AMQPBrokerConnectConfiguration addReceiver(AMQPReceiverBrokerConnectionElement element) { return addElement(element); } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectionElement.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectionElement.java index b237f074a42..ead5773933f 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectionElement.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPBrokerConnectionElement.java @@ -27,7 +27,7 @@ public class AMQPBrokerConnectionElement implements Serializable { private static final long serialVersionUID = 3653295602796835937L; - String name; + String name = "default"; SimpleString matchAddress; SimpleString queueName; AMQPBrokerConnectionAddressType type; diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationAddressPolicyElement.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationAddressPolicyElement.java index 71c30b21e50..139102c0bdd 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationAddressPolicyElement.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationAddressPolicyElement.java @@ -210,6 +210,9 @@ public static class AddressMatch implements Serializable { private String addressMatch; public String getName() { + if (name == null) { + return addressMatch; + } return name; } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationQueuePolicyElement.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationQueuePolicyElement.java index e790bd946ca..7b42dff02db 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationQueuePolicyElement.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPFederationQueuePolicyElement.java @@ -179,6 +179,9 @@ public static class QueueMatch implements Serializable { private String queueMatch; public String getName() { + if (name == null) { + return addressMatch + queueMatch; + } return name; } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPPeerBrokerConnectionElement.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPPeerBrokerConnectionElement.java new file mode 100644 index 00000000000..1929f72dc5a --- /dev/null +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPPeerBrokerConnectionElement.java @@ -0,0 +1,25 @@ +/* + * 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.artemis.core.config.amqpBrokerConnectivity; + +public class AMQPPeerBrokerConnectionElement extends AMQPBrokerConnectionElement { + private static final long serialVersionUID = -5021968319469459695L; + + public AMQPPeerBrokerConnectionElement() { + this.setType(AMQPBrokerConnectionAddressType.PEER); + } +} diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPReceiverBrokerConnectionElement.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPReceiverBrokerConnectionElement.java new file mode 100644 index 00000000000..466b66a4a08 --- /dev/null +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPReceiverBrokerConnectionElement.java @@ -0,0 +1,26 @@ +/* + * 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.artemis.core.config.amqpBrokerConnectivity; + +public class AMQPReceiverBrokerConnectionElement extends AMQPBrokerConnectionElement { + + private static final long serialVersionUID = 5257427388207911228L; + + public AMQPReceiverBrokerConnectionElement() { + this.setType(AMQPBrokerConnectionAddressType.RECEIVER); + } +} diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPSenderBrokerConnectionElement.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPSenderBrokerConnectionElement.java new file mode 100644 index 00000000000..82bf0d31e2e --- /dev/null +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/amqpBrokerConnectivity/AMQPSenderBrokerConnectionElement.java @@ -0,0 +1,25 @@ +/* + * 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.artemis.core.config.amqpBrokerConnectivity; + +public class AMQPSenderBrokerConnectionElement extends AMQPBrokerConnectionElement { + private static final long serialVersionUID = -7213161391886866563L; + + public AMQPSenderBrokerConnectionElement() { + this.setType(AMQPBrokerConnectionAddressType.SENDER); + } +} diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java index 9564365569f..1bc8e2b3cfa 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java @@ -19,10 +19,12 @@ import java.beans.IndexedPropertyDescriptor; import java.beans.PropertyDescriptor; import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; @@ -42,21 +44,27 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.Stack; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; import java.util.zip.Adler32; import java.util.zip.Checksum; import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration; +import org.apache.activemq.artemis.api.core.BroadcastEndpointFactory; import org.apache.activemq.artemis.api.core.BroadcastGroupConfiguration; import org.apache.activemq.artemis.api.core.DiscoveryGroupConfiguration; import org.apache.activemq.artemis.api.core.JsonUtil; @@ -78,7 +86,13 @@ import org.apache.activemq.artemis.core.config.StoreConfiguration; import org.apache.activemq.artemis.core.config.WildcardConfiguration; import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectConfiguration; +import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectionAddressType; +import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPBrokerConnectionElement; import org.apache.activemq.artemis.core.config.amqpBrokerConnectivity.AMQPFederationBrokerPlugin; +import org.apache.activemq.artemis.core.config.brokerConnectivity.BrokerConnectConfiguration; +import org.apache.activemq.artemis.core.config.federation.FederationAddressPolicyConfiguration; +import org.apache.activemq.artemis.core.config.federation.FederationPolicy; +import org.apache.activemq.artemis.core.config.federation.FederationQueuePolicyConfiguration; import org.apache.activemq.artemis.core.config.ha.ColocatedPolicyConfiguration; import org.apache.activemq.artemis.core.config.ha.LiveOnlyPolicyConfiguration; import org.apache.activemq.artemis.core.config.ha.ReplicaPolicyConfiguration; @@ -125,6 +139,7 @@ import org.apache.activemq.artemis.utils.XMLUtil; import org.apache.activemq.artemis.utils.critical.CriticalAnalyzerPolicy; import org.apache.activemq.artemis.utils.uri.BeanSupport; +import org.apache.activemq.artemis.utils.uri.FluentPropertyBeanIntrospectorWithIgnores; import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.beanutils.ConvertUtilsBean; import org.apache.commons.beanutils.Converter; @@ -137,6 +152,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.activemq.artemis.utils.PasswordMaskingUtil.isEncMasked; + public class ConfigurationImpl implements Configuration, Serializable { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); @@ -145,6 +162,8 @@ public class ConfigurationImpl implements Configuration, Serializable { public static final String PROPERTY_CLASS_SUFFIX = ".class"; + public static final String REDACTED = "**redacted**"; + private static final long serialVersionUID = 4077088945050267843L; private String name = "localhost"; @@ -451,6 +470,7 @@ public class ConfigurationImpl implements Configuration, Serializable { private File artemisInstance; private transient JsonObject jsonStatus = JsonLoader.createObjectBuilder().build(); private transient Checksum transientChecksum = null; + private final Set keysToRedact = new HashSet<>(); private JsonObject getJsonStatus() { if (jsonStatus == null) { @@ -548,10 +568,6 @@ public String getBrokerPropertiesRemoveValue() { return brokerPropertiesRemoveValue; } - public void setBrokerPropertiesRemoveValue(String brokerPropertiesRemoveValue) { - this.brokerPropertiesRemoveValue = brokerPropertiesRemoveValue; - } - @Override public Configuration parseProperties(String fileUrlToProperties) throws Exception { // system property overrides location of file(s) @@ -579,7 +595,7 @@ public Configuration parseProperties(String fileUrlToProperties) throws Exceptio return this; } - private void parseFileProperties(File file) throws Exception { + public void parseFileProperties(File file) throws Exception { InsertionOrderedProperties brokerProperties = new InsertionOrderedProperties(); try (FileReader fileReader = new FileReader(file); BufferedReader reader = new BufferedReader(fileReader)) { @@ -621,9 +637,13 @@ public void parsePrefixedProperties(Object target, String name, Properties prope checksum.update(value.getBytes(StandardCharsets.UTF_8)); value = XMLUtil.replaceSystemPropsInString(value); - value = PasswordMaskingUtil.resolveMask(isMaskPassword(), value, getPasswordCodec()); key = XMLUtil.replaceSystemPropsInString(key); - logger.debug("Property config, {}={}", key, value); + final boolean masked = isEncMasked(value); + if (masked) { + value = PasswordMaskingUtil.resolveMask(null, value, getPasswordCodec()); + keysToRedact.add(key); + } + logger.debug("Property config, {}={}", key, (masked || shouldRedact(key)) ? REDACTED : value); beanProperties.put(key, value); } alder32Hash = checksum.getValue(); @@ -919,7 +939,7 @@ public T convert(Class type, Object value) { logger.trace("populate: bean: {} with {}", this, beanProperties); - Map errors = new HashMap<>(); + Map errors = new LinkedHashMap<>(); // Loop through the property name/value pairs to be set for (final Map.Entry entry : beanProperties.entrySet()) { // Identify the property name and value(s) to be assigned @@ -945,6 +965,209 @@ public T convert(Class type, Object value) { updateApplyStatus(propsId, errors); } + @Override + public void exportAsProperties(File file) throws Exception { + try (FileWriter writer = new FileWriter(file, StandardCharsets.UTF_8)) { + writeProperties(writer); + } + } + + private void writeProperties(FileWriter writer) throws Exception { + final BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance(); + beanUtilsBean.getPropertyUtils().addBeanIntrospector(new FluentPropertyBeanIntrospectorWithIgnores()); + + try (BufferedWriter bufferedWriter = new BufferedWriter(writer)) { + export(beanUtilsBean, new Stack(), bufferedWriter, this); + } + } + + final Set ignored = Set.of( + // we report errors through the status, it should not typically be set + "status", + // we cannot import a map> property and this feature is only applied by the xml parser + "securityRoleNameMappings", + // another xml ism using a deprecated config object + "queueConfigs", + "encodeSize", + // duplicates + "federationPolicyMap", // core federation + "policySets", + "AMQPConnection", + "AMQPConnectionConfigurations", + "combinedParams", + "type", + // AMQPBrokerConnectConfiguration + // needs uri first + "uri", + // this relation breaks recursion + "parent", + // and connectionElements need to be split + "connectionElements" + ); + private void export(BeanUtilsBean beanUtils, Stack nested, BufferedWriter bufferedWriter, Object value) { + + if (value instanceof Collection collection) { + if (!collection.isEmpty()) { + // collection of strings, as a comma list + if (collection.stream().findFirst().orElseThrow() instanceof String) { + exportKeyValue(nested, bufferedWriter, (String) collection.stream().collect(Collectors.joining(","))); + } else if (collection instanceof EnumSet enumSet) { + exportKeyValue(nested, bufferedWriter, (String) enumSet.stream().map(Object::toString).collect(Collectors.joining(","))); + } else { + + Stream stream = collection.stream(); + if (collection.stream().findFirst().orElseThrow() instanceof AMQPBrokerConnectionElement amqpBrokerConnectionElement) { + // filter type from the shared underlying collection + String collectionName = nested.peek(); + AMQPBrokerConnectionAddressType subsetType = AMQPBrokerConnectionAddressType.valueOf(collectionName.substring(0, collectionName.length() - 1).toUpperCase(Locale.ENGLISH)); + stream = stream.filter((Object connectionElement)-> subsetType == ((AMQPBrokerConnectionElement)connectionElement).getType()); + } + // output nested by name + stream.forEach((Consumer) o -> { + nested.push(extractName(o)); + export(beanUtils, nested, bufferedWriter, o); + nested.pop(); + }); + } + } + } else if (value instanceof Map map) { + if (!map.isEmpty()) { + // possibly filter + Stream> stream = map.entrySet().stream(); + if (map.values().stream().findFirst().orElseThrow() instanceof FederationPolicy) { + // filter type from the shared underlying collection + final Class filterOn = "addressPolicies".equals(nested.peek()) ? FederationAddressPolicyConfiguration.class : FederationQueuePolicyConfiguration.class; + stream = stream.filter((Map.Entry entry)-> filterOn.isAssignableFrom(entry.getClass())); + } + stream.forEach(entry -> { + // nested by name + nested.push(entry.getKey().toString()); + export(beanUtils, nested, bufferedWriter, entry.getValue()); + nested.pop(); + }); + } + } else if (isComplexConfigObject(value)) { + + // these need constructor properties or .class values or particular attributes as first entry + if (value instanceof BrokerConnectConfiguration brokerConnectConfiguration) { + nested.push("uri"); // is in the ignored list so won't get duplicated + exportKeyValue(nested, bufferedWriter, brokerConnectConfiguration.getUri()); + nested.pop(); + } else if (value instanceof AMQPBrokerConnectionElement connectionElement) { + nested.push("type"); // is in the ignored list so won't get duplicated + exportKeyValue(nested, bufferedWriter, connectionElement.getType().toString()); + nested.pop(); + } else if (value instanceof HAPolicyConfiguration haPolicyConfiguration) { + exportKeyValue(nested, bufferedWriter, haPolicyConfiguration.getType().toString()); + } else if (value instanceof StoreConfiguration storeConfiguration) { + exportKeyValue(nested, bufferedWriter, storeConfiguration.getStoreType().toString()); + } else if (value instanceof NamedPropertyConfiguration namedPropertyConfiguration) { + exportKeyValue(nested, bufferedWriter, namedPropertyConfiguration.getName()); + } else if (value instanceof BroadcastEndpointFactory broadcastEndpointFactory) { + exportKeyValue(nested, bufferedWriter, broadcastEndpointFactory.getClass().getCanonicalName() + ".class"); + } else if (value instanceof ActiveMQMetricsPlugin plugin) { + exportKeyValue(nested, bufferedWriter, plugin.getClass().getCanonicalName() + ".class"); + nested.push("init"); + exportKeyValue(nested, bufferedWriter, ""); + nested.pop(); + } + // recursive export via accessors + Arrays.stream(beanUtils.getPropertyUtils().getPropertyDescriptors(value)).filter(propertyDescriptor -> { + + if (ignored.contains(propertyDescriptor.getName())) { + return false; + } + final Method descriptorReadMethod = propertyDescriptor.getReadMethod(); + if (descriptorReadMethod == null) { + return false; + } + Method descriptorWriteMethod = propertyDescriptor.getWriteMethod(); + if (descriptorWriteMethod == null) { + // we can write to a returned simple map or collection ok + final Class type = propertyDescriptor.getPropertyType(); + return Map.class.isAssignableFrom(type) || Collection.class.isAssignableFrom(type); + } + return true; + }).sorted((a, b) -> String.CASE_INSENSITIVE_ORDER.compare(a.getName(), b.getName())).forEach(propertyDescriptor -> { + Object attributeValue = null; + try { + attributeValue = propertyDescriptor.getReadMethod().invoke(value, null); + } catch (Exception e) { + throw new RuntimeException("accessing: " + propertyDescriptor.getName() + "@" + nested, e); + } + if (attributeValue != null) { + nested.push(propertyDescriptor.getName()); + export(beanUtils, nested, bufferedWriter, attributeValue); + nested.pop(); + } + }); + } else { + // string form works ok otherwise + exportKeyValue(nested, bufferedWriter, value.toString()); + } + } + + private void exportKeyValue(Stack nested, BufferedWriter bufferedWriter, String value) { + String key = writeKeyEquals(nested, bufferedWriter); + + try { + if (shouldRedact(key)) { + bufferedWriter.write(REDACTED); + } else { + bufferedWriter.write(value); + } + bufferedWriter.newLine(); + } catch (IOException e) { + throw new RuntimeException("error accessing: " + nested, e); + } + } + + private boolean isComplexConfigObject(Object value) { + return !(value instanceof SimpleString || value instanceof Enum) && value.getClass().getPackage().getName().contains("artemis"); + } + + private boolean shouldRedact(String name) { + return name.toUpperCase(Locale.ENGLISH).contains("PASSWORD") || keysToRedact.contains(name); + } + + private String writeKeyEquals(Stack nested, BufferedWriter bufferedWriter) { + + String key = nested.stream().sequential().map(ConfigurationImpl::quote).collect(Collectors.joining(".")); + try { + bufferedWriter.write(key); + bufferedWriter.write("="); + } catch (IOException e) { + throw new RuntimeException("error accessing: " + nested, e); + } + return key; + } + + public static String quote(String s) { + String escaped = s.replace("=", "\\\\=").replace(":", "\\\\:"); + if (s.contains(".")) { + escaped = "\"" + escaped + "\""; + } + return escaped; + } + + String extractName(Object o) { + if (o instanceof String s) { + return s; + } + try { + Method m = o.getClass().getMethod("getName", null); + if (m != null) { + Object nameVal = m.invoke(o, null); + if (nameVal == null) { + return "name-attribute-must-be-set-for-properties-key-export"; + } + return nameVal.toString(); + } + } catch (Exception expectedAndWillDefaultToStringForm) { + } + return String.valueOf(o); + } + protected static boolean isClassProperty(String property) { return property.endsWith(PROPERTY_CLASS_SUFFIX); } @@ -1460,6 +1683,7 @@ public ConfigurationImpl setQueueConfigs(final List configs) } @Override + @Deprecated public ConfigurationImpl addQueueConfiguration(final CoreQueueConfiguration config) { coreQueueConfigurations.add(config); return this; @@ -3566,6 +3790,8 @@ private Object newNamedInstanceForCollection(String collectionPropertyName, Obje // or strategies becomes strategy etc. addPropertyNameBuilder.append(collectionPropertyName, 1, collectionPropertyName.length() - 3); addPropertyNameBuilder.append('y'); + } else if (collectionPropertyName.endsWith("Map")) { + addPropertyNameBuilder.append(collectionPropertyName, 1, collectionPropertyName.length() - 3); } else { addPropertyNameBuilder.append(collectionPropertyName, 1, collectionPropertyName.length() - 1); } @@ -3580,7 +3806,18 @@ private Object newNamedInstanceForCollection(String collectionPropertyName, Obje // has a String key && String.class.equals(method.getParameterTypes()[0]) // but not initialised from a String form (eg: uri) - && !String.class.equals(method.getParameterTypes()[1])))).sorted((method1, method2) -> method2.getParameterCount() - method1.getParameterCount()).findFirst().orElse(null); + && !String.class.equals(method.getParameterTypes()[1])))).sorted((method1, method2) -> { + int result = method2.getParameterCount() - method1.getParameterCount(); + if (result == 0) { + // choose non deprecated + if (method1.getDeclaredAnnotation(Deprecated.class) == null) { + result = 1; + } else { + result = -1; + } + } + return result; + }).findFirst().orElse(null); if (candidate == null) { throw new IllegalArgumentException("failed to locate add method for collection property " + addPropertyName); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java index 50532aecde4..56a21d98256 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/management/impl/ActiveMQServerControlImpl.java @@ -157,7 +157,8 @@ public class ActiveMQServerControlImpl extends AbstractControl implements ActiveMQServerControl, NotificationEmitter, org.apache.activemq.artemis.core.server.management.NotificationListener { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - + public static final String CONFIG_AS_PROPERTIES_FILE = "broker_config_as_properties.txt"; + public static final String TMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; private final PostOffice postOffice; @@ -4746,6 +4747,22 @@ public long getAuthorizationFailureCount() { return server.getSecurityStore().getAuthorizationFailureCount(); } + @Override + public void exportConfigAsProperties() throws Exception { + if (AuditLogger.isBaseLoggingEnabled()) { + AuditLogger.exportConfigAsProperties(this.server); + } + + try (AutoCloseable lock = server.managementLock()) { + if (System.getProperty(TMP_DIR_SYSTEM_PROPERTY) == null) { + throw new IllegalStateException(TMP_DIR_SYSTEM_PROPERTY + " system property must be set"); + } else { + File exportFileInTmp = new File(System.getProperty(TMP_DIR_SYSTEM_PROPERTY), CONFIG_AS_PROPERTIES_FILE); + this.server.getConfiguration().exportAsProperties(exportFileInTmp); + } + } + } + public ActiveMQServer getServer() { return server; } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java index 948ebf522f4..1f8d0500322 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/settings/impl/AddressSettings.java @@ -1272,7 +1272,7 @@ public Integer getIDCacheSize() { return idCacheSize; } - public AddressSettings setIDCacheSize(int idCacheSize) { + public AddressSettings setIDCacheSize(Integer idCacheSize) { this.idCacheSize = idCacheSize; return this; } @@ -1281,7 +1281,7 @@ public Integer getInitialQueueBufferSize() { return initialQueueBufferSize; } - public AddressSettings setInitialQueueBufferSize(int initialQueueBufferSize) { + public AddressSettings setInitialQueueBufferSize(Integer initialQueueBufferSize) { this.initialQueueBufferSize = initialQueueBufferSize; return this; } diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java index 9e019323aef..32830ebe1ab 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImplTest.java @@ -16,15 +16,18 @@ */ package org.apache.activemq.artemis.core.config.impl; +import static org.apache.activemq.artemis.core.config.impl.ConfigurationImpl.REDACTED; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; +import java.beans.PropertyDescriptor; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; @@ -104,6 +107,8 @@ import org.apache.activemq.artemis.utils.RandomUtil; import org.apache.activemq.artemis.utils.actors.ArtemisExecutor; import org.apache.activemq.artemis.utils.critical.CriticalAnalyzerPolicy; +import org.apache.activemq.artemis.utils.uri.FluentPropertyBeanIntrospectorWithIgnores; +import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.commons.lang3.ClassUtils; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -362,7 +367,7 @@ private void testAMQPConnectionsConfiguration(boolean sync) throws Throwable { ConfigurationImpl configuration = new ConfigurationImpl(); Properties insertionOrderedProperties = new ConfigurationImpl.InsertionOrderedProperties(); - insertionOrderedProperties.put("AMQPConnections.target.uri", "localhost:61617"); + insertionOrderedProperties.put("AMQPConnections.target.uri", "tcp://localhost:61617"); insertionOrderedProperties.put("AMQPConnections.target.retryInterval", 55); insertionOrderedProperties.put("AMQPConnections.target.reconnectAttempts", -2); insertionOrderedProperties.put("AMQPConnections.target.user", "admin"); @@ -385,7 +390,7 @@ private void testAMQPConnectionsConfiguration(boolean sync) throws Throwable { assertEquals(1, configuration.getAMQPConnections().size()); AMQPBrokerConnectConfiguration connectConfiguration = configuration.getAMQPConnections().get(0); assertEquals("target", connectConfiguration.getName()); - assertEquals("localhost:61617", connectConfiguration.getUri()); + assertEquals("tcp://localhost:61617", connectConfiguration.getUri()); assertEquals(55, connectConfiguration.getRetryInterval()); assertEquals(-2, connectConfiguration.getReconnectAttempts()); assertEquals("admin", connectConfiguration.getUser()); @@ -403,6 +408,14 @@ private void testAMQPConnectionsConfiguration(boolean sync) throws Throwable { assertEquals("foo", amqpMirrorBrokerConnectionElement.getAddressFilter()); assertFalse(amqpMirrorBrokerConnectionElement.getProperties().isEmpty()); assertEquals("b", amqpMirrorBrokerConnectionElement.getProperties().get("a")); + + File exported = new File(getTestDirfile(), "broker_config_as_properties_export.txt"); + configuration.exportAsProperties(exported); + + ConfigurationImpl loadFromExport = new ConfigurationImpl(); + loadFromExport.parseFileProperties(exported); + + assertTrue(loadFromExport.getStatus().contains("\"errors\":[]")); } @Test @@ -421,7 +434,7 @@ private void doTestAMQPFederationAddressPolicyConfiguration(boolean local) throw final String policyType = local ? "localAddressPolicies" : "remoteAddressPolicies"; final Properties insertionOrderedProperties = new ConfigurationImpl.InsertionOrderedProperties(); - insertionOrderedProperties.put("AMQPConnections.target.uri", "localhost:61617"); + insertionOrderedProperties.put("AMQPConnections.target.uri", "tcp://localhost:61617"); insertionOrderedProperties.put("AMQPConnections.target.retryInterval", 55); insertionOrderedProperties.put("AMQPConnections.target.reconnectAttempts", -2); insertionOrderedProperties.put("AMQPConnections.target.user", "admin"); @@ -447,7 +460,7 @@ private void doTestAMQPFederationAddressPolicyConfiguration(boolean local) throw assertEquals(1, configuration.getAMQPConnections().size()); AMQPBrokerConnectConfiguration connectConfiguration = configuration.getAMQPConnections().get(0); assertEquals("target", connectConfiguration.getName()); - assertEquals("localhost:61617", connectConfiguration.getUri()); + assertEquals("tcp://localhost:61617", connectConfiguration.getUri()); assertEquals(55, connectConfiguration.getRetryInterval()); assertEquals(-2, connectConfiguration.getReconnectAttempts()); assertEquals("admin", connectConfiguration.getUser()); @@ -528,6 +541,14 @@ private void doTestAMQPFederationAddressPolicyConfiguration(boolean local) throw assertEquals(0, amqpFederationBrokerConnectionElement.getLocalQueuePolicies().size()); assertEquals(0, amqpFederationBrokerConnectionElement.getRemoteQueuePolicies().size()); + + File exported = new File(getTestDirfile(), "broker_config_as_properties_export.txt"); + configuration.exportAsProperties(exported); + + ConfigurationImpl loadFromExport = new ConfigurationImpl(); + loadFromExport.parseFileProperties(exported); + + assertTrue(loadFromExport.getStatus().contains("\"errors\":[]")); } @Test @@ -546,7 +567,7 @@ private void doTestAMQPFederationQueuePolicyConfiguration(boolean local) throws final String policyType = local ? "localQueuePolicies" : "remoteQueuePolicies"; final Properties insertionOrderedProperties = new ConfigurationImpl.InsertionOrderedProperties(); - insertionOrderedProperties.put("AMQPConnections.target.uri", "localhost:61617"); + insertionOrderedProperties.put("AMQPConnections.target.uri", "tcp://localhost:61617"); insertionOrderedProperties.put("AMQPConnections.target.retryInterval", 55); insertionOrderedProperties.put("AMQPConnections.target.reconnectAttempts", -2); insertionOrderedProperties.put("AMQPConnections.target.user", "admin"); @@ -572,7 +593,7 @@ private void doTestAMQPFederationQueuePolicyConfiguration(boolean local) throws assertEquals(1, configuration.getAMQPConnections().size()); AMQPBrokerConnectConfiguration connectConfiguration = configuration.getAMQPConnections().get(0); assertEquals("target", connectConfiguration.getName()); - assertEquals("localhost:61617", connectConfiguration.getUri()); + assertEquals("tcp://localhost:61617", connectConfiguration.getUri()); assertEquals(55, connectConfiguration.getRetryInterval()); assertEquals(-2, connectConfiguration.getReconnectAttempts()); assertEquals("admin", connectConfiguration.getUser()); @@ -656,6 +677,14 @@ private void doTestAMQPFederationQueuePolicyConfiguration(boolean local) throws assertEquals(0, amqpFederationBrokerConnectionElement.getLocalAddressPolicies().size()); assertEquals(0, amqpFederationBrokerConnectionElement.getRemoteAddressPolicies().size()); + + File exported = new File(getTestDirfile(), "broker_config_as_properties_export.txt"); + configuration.exportAsProperties(exported); + + ConfigurationImpl loadFromExport = new ConfigurationImpl(); + loadFromExport.parseFileProperties(exported); + + assertTrue(loadFromExport.getStatus().contains("\"errors\":[]")); } @Test @@ -1016,6 +1045,45 @@ public void testFederationUpstreamConfiguration() throws Throwable { assertEquals("secureexample", configuration.getFederationConfigurations().get(0).getCredentials().getPassword()); } + @Test + public void testExportWithNonPasswordEnc() throws Exception { + ConfigurationImpl configuration = new ConfigurationImpl(); + + Properties properties = new ConfigurationImpl.InsertionOrderedProperties(); + properties.put("name", "ENC(2a7c211d21c295cdbcde3589c205decb)"); + + properties.put("AMQPConnections.target.uri", "tcp://amq-dc1-tls-amqp-svc.dc1.svc.cluster.local:5673?clientFailureCheckPeriod=30000&connectionTTL=60000&sslEnabled=true&verifyHost=false&trustStorePath=/remote-cluster-truststore/client.ts"); + properties.put("AMQPConnections.target.transportConfigurations.target.params.enc", "ENC(2a7c211d21c295cdbcde3589c205decb)"); + + configuration.parsePrefixedProperties(properties, null); + + assertTrue(configuration.getStatus().contains("\"errors\":[]"), configuration.getStatus()); + + assertEquals("secureexample", configuration.getName()); + assertEquals("secureexample", configuration.getAMQPConnections().get(0).getTransportConfigurations().get(0).getParams().get("enc")); + + File exported = new File(getTestDirfile(), "broker_config_as_properties_export.txt"); + configuration.exportAsProperties(exported); + + ConfigurationImpl loadFromExport = new ConfigurationImpl(); + loadFromExport.parseFileProperties(exported); + + assertTrue(loadFromExport.getStatus().contains("\"errors\":[]")); + + assertEquals(REDACTED, loadFromExport.getName()); + assertEquals(REDACTED, loadFromExport.getAMQPConnections().get(0).getTransportConfigurations().get(0).getParams().get("enc")); + + ConfigurationImpl configurationCopy = (ConfigurationImpl) loadFromExport.copy(); + configurationCopy.exportAsProperties(exported); + + ConfigurationImpl loadFromExportCopy = new ConfigurationImpl(); + loadFromExportCopy.parseFileProperties(exported); + + assertTrue(loadFromExportCopy.getStatus().contains("\"errors\":[]")); + + assertEquals(REDACTED, loadFromExportCopy.getName()); + assertEquals(REDACTED, loadFromExportCopy.getAMQPConnections().get(0).getTransportConfigurations().get(0).getParams().get("enc")); + } @Test public void testAMQPBrokerConnectionMix() throws Throwable { @@ -1043,6 +1111,12 @@ public void testAMQPBrokerConnectionMix() throws Throwable { fail("unexpected amqp broker connection configuration: " + amqpBrokerConnectConfiguration.getName()); } } + + File exported = new File(getTestDirfile(), "broker_config_as_properties_export.txt"); + configuration.exportAsProperties(exported); + ConfigurationImpl loadFromExport = new ConfigurationImpl(); + loadFromExport.parseFileProperties(exported); + assertTrue(loadFromExport.getStatus().contains("\"errors\":[]")); } @Test @@ -1177,12 +1251,13 @@ public void testSetNestedPropertyOnExistingCollectionEntryViaMappedNotation() th public void testAddressViaProperties() throws Throwable { ConfigurationImpl configuration = new ConfigurationImpl(); - Properties properties = new Properties(); - + Properties properties = new ConfigurationImpl.InsertionOrderedProperties(); + properties.put("addressConfigurations.\"LB.TEST\".name", "LB.TEST"); properties.put("addressConfigurations.\"LB.TEST\".queueConfigs.\"LB.TEST\".routingType", "ANYCAST"); properties.put("addressConfigurations.\"LB.TEST\".queueConfigs.\"LB.TEST\".durable", "false"); configuration.parsePrefixedProperties(properties, null); + assertTrue(configuration.getStatus().contains("\"errors\":[]")); assertEquals(1, configuration.getAddressConfigurations().size()); assertEquals(1, configuration.getAddressConfigurations().get(0).getQueueConfigs().size()); @@ -1355,9 +1430,12 @@ public void testAddressSettingsViaProperties() throws Throwable { properties.put("addressSettings.NeedToSet.defaultExclusiveQueue", "true"); properties.put("addressSettings.NeedToSet.defaultMaxConsumers", 10); properties.put("addressSettings.NeedToSet.iDCacheSize", 10); + properties.put("addressSettings.NeedToSet.noExpiry", true); configuration.parsePrefixedProperties(properties, null); + assertTrue(configuration.getStatus().contains("\"errors\":[]"), configuration.getStatus()); + assertEquals(4, configuration.getAddressSettings().size()); assertEquals(SimpleString.of("sharedExpiry"), configuration.getAddressSettings().get("#").getExpiryAddress()); assertEquals(SimpleString.of("important"), configuration.getAddressSettings().get("NeedToTrackExpired").getExpiryAddress()); @@ -1421,6 +1499,7 @@ public void testAddressSettingsViaProperties() throws Throwable { assertTrue(configuration.getAddressSettings().get("NeedToSet").isDefaultExclusiveQueue()); assertEquals(Integer.valueOf(10), configuration.getAddressSettings().get("NeedToSet").getDefaultMaxConsumers()); assertEquals(Integer.valueOf(10), configuration.getAddressSettings().get("NeedToSet").getIDCacheSize()); + assertTrue(configuration.getAddressSettings().get("NeedToSet").isNoExpiry()); } @Test @@ -1715,6 +1794,23 @@ public void testRoleSettingsViaProperties() throws Exception { assertFalse(role.isCreateAddress()); } + @Test + public void testSecurityRoleMappingsViaPropertiesNotSupported() throws Exception { + ConfigurationImpl configuration = new ConfigurationImpl(); + Properties properties = new Properties(); + + properties.put("securityRoleNameMappings.amq", "myrole4"); + + configuration.parsePrefixedProperties(properties, null); + + assertTrue(configuration.getStatus().contains("\"errors\":[]"), configuration.getStatus()); + + Exception expected = assertThrows(ClassCastException.class, ()-> { + configuration.getSecurityRoleNameMappings().get("amq").contains("myrole4"); + }); + assertTrue(expected.toString().contains("Set")); + } + @Test public void testRoleAugmentViaProperties() throws Exception { @@ -2481,6 +2577,27 @@ public void testSetSystemPropertyCME() throws Throwable { assertEquals(4321, configuration.getGlobalMaxSize()); } + @Test + public void testTypeMatchFluentDescriptor() throws Exception { + BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance(); + beanUtilsBean.getPropertyUtils().addBeanIntrospector(new FluentPropertyBeanIntrospectorWithIgnores()); + PropertyDescriptor propertyDescriptor = beanUtilsBean.getPropertyUtils().getPropertyDescriptor(new DummyConfig(), "aBooleanProperty"); + + assertNotNull(propertyDescriptor); + assertNotNull(propertyDescriptor.getReadMethod()); + + propertyDescriptor = beanUtilsBean.getPropertyUtils().getPropertyDescriptor(new DummyConfig(), "IDCacheSize"); + + assertNotNull(propertyDescriptor); + assertNotNull(propertyDescriptor.getReadMethod()); + assertNotNull(propertyDescriptor.getWriteMethod()); + + // legacy access to a setter for this + propertyDescriptor = beanUtilsBean.getPropertyUtils().getPropertyDescriptor(new DummyConfig(), "iDCacheSize"); + assertNotNull(propertyDescriptor); + assertNotNull(propertyDescriptor.getWriteMethod()); + } + @Test public void testConfigWithMultipleNullDescendantChildren() throws Throwable { String dummyPropertyPrefix = "dummy."; @@ -2515,6 +2632,8 @@ public void testExtractPropertyClassName() throws Exception { public static class DummyConfig { private int intProperty; + private int idCacheSize; + private Boolean aBooleanProperty; private DummyConfig childConfig; @@ -2527,6 +2646,24 @@ public DummyConfig setIntProperty(int intProperty) { return this; } + public Boolean isABooleanProperty() { + return aBooleanProperty; + } + + public DummyConfig setABooleanProperty(Boolean booleanProperty) { + this.aBooleanProperty = booleanProperty; + return this; + } + + public Integer getIDCacheSize() { + return idCacheSize; + } + + public DummyConfig setIDCacheSize(Integer idCacheSize) { + this.idCacheSize = idCacheSize; + return this; + } + public DummyConfig getChildConfig() { return childConfig; } diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java index c8ff8202154..be2c322ae4e 100644 --- a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java +++ b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java @@ -16,6 +16,7 @@ */ package org.apache.activemq.artemis.core.config.impl; +import static org.apache.activemq.artemis.core.config.impl.ConfigurationImpl.REDACTED; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; @@ -179,89 +180,93 @@ protected Configuration createConfiguration() throws Exception { @TestTemplate public void testFileConfiguration() { + validateFullConfig(conf); + } + + private void validateFullConfig(Configuration configInstance) { // Check they match the values from the test file - assertEquals("SomeNameForUseOnTheApplicationServer", conf.getName()); - assertFalse(conf.isPersistenceEnabled()); - assertTrue(conf.isClustered()); - assertEquals(12345, conf.getScheduledThreadPoolMaxSize()); - assertEquals(54321, conf.getThreadPoolMaxSize()); - assertFalse(conf.isSecurityEnabled()); - assertEquals(5423, conf.getSecurityInvalidationInterval()); - assertEquals(333, conf.getAuthenticationCacheSize()); - assertEquals(444, conf.getAuthorizationCacheSize()); - assertTrue(conf.isWildcardRoutingEnabled()); - assertEquals(SimpleString.of("Giraffe"), conf.getManagementAddress()); - assertEquals(SimpleString.of("Whatever"), conf.getManagementNotificationAddress()); - assertEquals("Frog", conf.getClusterUser()); - assertEquals("Wombat", conf.getClusterPassword()); - assertFalse(conf.isJMXManagementEnabled()); - assertEquals("gro.qtenroh", conf.getJMXDomain()); - assertTrue(conf.isMessageCounterEnabled()); - assertEquals(5, conf.getMessageCounterMaxDayHistory()); - assertEquals(123456, conf.getMessageCounterSamplePeriod()); - assertEquals(12345, conf.getConnectionTTLOverride()); - assertEquals(98765, conf.getTransactionTimeout()); - assertEquals(56789, conf.getTransactionTimeoutScanPeriod()); - assertEquals(10111213, conf.getMessageExpiryScanPeriod()); - assertEquals(25000, conf.getAddressQueueScanPeriod()); - assertEquals(127, conf.getIDCacheSize()); - assertTrue(conf.isPersistIDCache()); - assertEquals(Integer.valueOf(777), conf.getJournalDeviceBlockSize()); - assertTrue(conf.isPersistDeliveryCountBeforeDelivery()); - assertEquals("pagingdir", conf.getPagingDirectory()); - assertEquals("somedir", conf.getBindingsDirectory()); - assertFalse(conf.isCreateBindingsDir()); - assertTrue(conf.isAmqpUseCoreSubscriptionNaming()); - assertFalse(conf.isSuppressSessionNotifications()); - assertEquals("()", conf.getLiteralMatchMarkers()); - - assertEquals(17, conf.getPageMaxConcurrentIO(), "max concurrent io"); - assertTrue(conf.isReadWholePage()); - assertEquals("somedir2", conf.getJournalDirectory()); - assertEquals("history", conf.getJournalRetentionDirectory()); - assertEquals(10L * 1024L * 1024L * 1024L, conf.getJournalRetentionMaxBytes()); - assertEquals(TimeUnit.DAYS.toMillis(365), conf.getJournalRetentionPeriod()); - assertFalse(conf.isCreateJournalDir()); - assertEquals(JournalType.NIO, conf.getJournalType()); - assertEquals(10000, conf.getJournalBufferSize_NIO()); - assertEquals(1000, conf.getJournalBufferTimeout_NIO()); - assertEquals(56546, conf.getJournalMaxIO_NIO()); - assertEquals(9876, conf.getJournalFileOpenTimeout()); - - assertFalse(conf.isJournalSyncTransactional()); - assertTrue(conf.isJournalSyncNonTransactional()); - assertEquals(12345678, conf.getJournalFileSize()); - assertEquals(100, conf.getJournalMinFiles()); - assertEquals(123, conf.getJournalCompactMinFiles()); - assertEquals(33, conf.getJournalCompactPercentage()); - assertEquals(7654, conf.getJournalLockAcquisitionTimeout()); - assertTrue(conf.isGracefulShutdownEnabled()); - assertEquals(12345, conf.getGracefulShutdownTimeout()); - assertTrue(conf.isPopulateValidatedUser()); - assertFalse(conf.isRejectEmptyValidatedUser()); - assertEquals(123456, conf.getMqttSessionScanInterval()); - assertEquals(567890, conf.getMqttSessionStatePersistenceTimeout()); - assertEquals(98765, conf.getConnectionTtlCheckInterval()); - assertEquals(1234567, conf.getConfigurationFileRefreshPeriod()); - assertEquals("TEMP", conf.getTemporaryQueueNamespace()); - - assertEquals("127.0.0.1", conf.getNetworkCheckList()); - assertEquals("some-nick", conf.getNetworkCheckNIC()); - assertEquals(123, conf.getNetworkCheckPeriod()); - assertEquals(321, conf.getNetworkCheckTimeout()); - assertEquals("ping-four", conf.getNetworkCheckPingCommand()); - assertEquals("ping-six", conf.getNetworkCheckPing6Command()); - - assertEquals("largemessagesdir", conf.getLargeMessagesDirectory()); - assertEquals(95, conf.getMemoryWarningThreshold()); - - assertEquals(2, conf.getIncomingInterceptorClassNames().size()); - assertTrue(conf.getIncomingInterceptorClassNames().contains("org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor1")); - assertTrue(conf.getIncomingInterceptorClassNames().contains("org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor2")); - - assertEquals(2, conf.getConnectorConfigurations().size()); - - TransportConfiguration tc = conf.getConnectorConfigurations().get("connector1"); + assertEquals("SomeNameForUseOnTheApplicationServer", configInstance.getName()); + assertFalse(configInstance.isPersistenceEnabled()); + assertTrue(configInstance.isClustered()); + assertEquals(12345, configInstance.getScheduledThreadPoolMaxSize()); + assertEquals(54321, configInstance.getThreadPoolMaxSize()); + assertFalse(configInstance.isSecurityEnabled()); + assertEquals(5423, configInstance.getSecurityInvalidationInterval()); + assertEquals(333, configInstance.getAuthenticationCacheSize()); + assertEquals(444, configInstance.getAuthorizationCacheSize()); + assertTrue(configInstance.isWildcardRoutingEnabled()); + assertEquals(SimpleString.of("Giraffe"), configInstance.getManagementAddress()); + assertEquals(SimpleString.of("Whatever"), configInstance.getManagementNotificationAddress()); + assertEquals("Frog", configInstance.getClusterUser()); + assertEquals("Wombat", configInstance.getClusterPassword()); + assertFalse(configInstance.isJMXManagementEnabled()); + assertEquals("gro.qtenroh", configInstance.getJMXDomain()); + assertTrue(configInstance.isMessageCounterEnabled()); + assertEquals(5, configInstance.getMessageCounterMaxDayHistory()); + assertEquals(123456, configInstance.getMessageCounterSamplePeriod()); + assertEquals(12345, configInstance.getConnectionTTLOverride()); + assertEquals(98765, configInstance.getTransactionTimeout()); + assertEquals(56789, configInstance.getTransactionTimeoutScanPeriod()); + assertEquals(10111213, configInstance.getMessageExpiryScanPeriod()); + assertEquals(25000, configInstance.getAddressQueueScanPeriod()); + assertEquals(127, configInstance.getIDCacheSize()); + assertTrue(configInstance.isPersistIDCache()); + assertEquals(Integer.valueOf(777), configInstance.getJournalDeviceBlockSize()); + assertTrue(configInstance.isPersistDeliveryCountBeforeDelivery()); + assertEquals("pagingdir", configInstance.getPagingDirectory()); + assertEquals("somedir", configInstance.getBindingsDirectory()); + assertFalse(configInstance.isCreateBindingsDir()); + assertTrue(configInstance.isAmqpUseCoreSubscriptionNaming()); + assertFalse(configInstance.isSuppressSessionNotifications()); + assertEquals("()", configInstance.getLiteralMatchMarkers()); + + assertEquals(17, configInstance.getPageMaxConcurrentIO(), "max concurrent io"); + assertTrue(configInstance.isReadWholePage()); + assertEquals("somedir2", configInstance.getJournalDirectory()); + assertEquals("history", configInstance.getJournalRetentionDirectory()); + assertEquals(10L * 1024L * 1024L * 1024L, configInstance.getJournalRetentionMaxBytes()); + assertEquals(TimeUnit.DAYS.toMillis(365), configInstance.getJournalRetentionPeriod()); + assertFalse(configInstance.isCreateJournalDir()); + assertEquals(JournalType.NIO, configInstance.getJournalType()); + assertEquals(10000, configInstance.getJournalBufferSize_NIO()); + assertEquals(1000, configInstance.getJournalBufferTimeout_NIO()); + assertEquals(56546, configInstance.getJournalMaxIO_NIO()); + assertEquals(9876, configInstance.getJournalFileOpenTimeout()); + + assertFalse(configInstance.isJournalSyncTransactional()); + assertTrue(configInstance.isJournalSyncNonTransactional()); + assertEquals(12345678, configInstance.getJournalFileSize()); + assertEquals(100, configInstance.getJournalMinFiles()); + assertEquals(123, configInstance.getJournalCompactMinFiles()); + assertEquals(33, configInstance.getJournalCompactPercentage()); + assertEquals(7654, configInstance.getJournalLockAcquisitionTimeout()); + assertTrue(configInstance.isGracefulShutdownEnabled()); + assertEquals(12345, configInstance.getGracefulShutdownTimeout()); + assertTrue(configInstance.isPopulateValidatedUser()); + assertFalse(configInstance.isRejectEmptyValidatedUser()); + assertEquals(123456, configInstance.getMqttSessionScanInterval()); + assertEquals(567890, configInstance.getMqttSessionStatePersistenceTimeout()); + assertEquals(98765, configInstance.getConnectionTtlCheckInterval()); + assertEquals(1234567, configInstance.getConfigurationFileRefreshPeriod()); + assertEquals("TEMP", configInstance.getTemporaryQueueNamespace()); + + assertEquals("127.0.0.1", configInstance.getNetworkCheckList()); + assertEquals("some-nick", configInstance.getNetworkCheckNIC()); + assertEquals(123, configInstance.getNetworkCheckPeriod()); + assertEquals(321, configInstance.getNetworkCheckTimeout()); + assertEquals("ping-four", configInstance.getNetworkCheckPingCommand()); + assertEquals("ping-six", configInstance.getNetworkCheckPing6Command()); + + assertEquals("largemessagesdir", configInstance.getLargeMessagesDirectory()); + assertEquals(95, configInstance.getMemoryWarningThreshold()); + + assertEquals(2, configInstance.getIncomingInterceptorClassNames().size()); + assertTrue(configInstance.getIncomingInterceptorClassNames().contains("org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor1")); + assertTrue(configInstance.getIncomingInterceptorClassNames().contains("org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor2")); + + assertEquals(2, configInstance.getConnectorConfigurations().size()); + + TransportConfiguration tc = configInstance.getConnectorConfigurations().get("connector1"); assertNotNull(tc); assertEquals("org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory", tc.getFactoryClassName()); assertEquals("mylocal", tc.getParams().get("localAddress")); @@ -269,13 +274,13 @@ public void testFileConfiguration() { assertEquals("localhost1", tc.getParams().get("host")); assertEquals("5678", tc.getParams().get("port")); - tc = conf.getConnectorConfigurations().get("connector2"); + tc = configInstance.getConnectorConfigurations().get("connector2"); assertNotNull(tc); assertEquals("org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory", tc.getFactoryClassName()); assertEquals("5", tc.getParams().get("serverId")); - assertEquals(2, conf.getAcceptorConfigurations().size()); - for (TransportConfiguration ac : conf.getAcceptorConfigurations()) { + assertEquals(2, configInstance.getAcceptorConfigurations().size()); + for (TransportConfiguration ac : configInstance.getAcceptorConfigurations()) { if (ac.getFactoryClassName().equals("org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory")) { assertEquals("456", ac.getParams().get("tcpNoDelay")); assertEquals("44", ac.getParams().get("connectionTtl")); @@ -287,8 +292,8 @@ public void testFileConfiguration() { } } - assertEquals(2, conf.getBroadcastGroupConfigurations().size()); - for (BroadcastGroupConfiguration bc : conf.getBroadcastGroupConfigurations()) { + assertEquals(2, configInstance.getBroadcastGroupConfigurations().size()); + for (BroadcastGroupConfiguration bc : configInstance.getBroadcastGroupConfigurations()) { UDPBroadcastEndpointFactory udpBc = (UDPBroadcastEndpointFactory) bc.getEndpointFactory(); if (bc.getName().equals("bg1")) { assertEquals("bg1", bc.getName()); @@ -307,23 +312,23 @@ public void testFileConfiguration() { } } - assertEquals(2, conf.getDiscoveryGroupConfigurations().size()); - DiscoveryGroupConfiguration dc = conf.getDiscoveryGroupConfigurations().get("dg1"); + assertEquals(2, configInstance.getDiscoveryGroupConfigurations().size()); + DiscoveryGroupConfiguration dc = configInstance.getDiscoveryGroupConfigurations().get("dg1"); assertEquals("dg1", dc.getName()); assertEquals("192.168.0.120", ((UDPBroadcastEndpointFactory) dc.getBroadcastEndpointFactory()).getGroupAddress()); assertEquals("172.16.8.10", ((UDPBroadcastEndpointFactory) dc.getBroadcastEndpointFactory()).getLocalBindAddress()); assertEquals(11999, ((UDPBroadcastEndpointFactory) dc.getBroadcastEndpointFactory()).getGroupPort()); assertEquals(12345, dc.getRefreshTimeout()); - dc = conf.getDiscoveryGroupConfigurations().get("dg2"); + dc = configInstance.getDiscoveryGroupConfigurations().get("dg2"); assertEquals("dg2", dc.getName()); assertEquals("192.168.0.121", ((UDPBroadcastEndpointFactory) dc.getBroadcastEndpointFactory()).getGroupAddress()); assertEquals("172.16.8.11", ((UDPBroadcastEndpointFactory) dc.getBroadcastEndpointFactory()).getLocalBindAddress()); assertEquals(12999, ((UDPBroadcastEndpointFactory) dc.getBroadcastEndpointFactory()).getGroupPort()); assertEquals(23456, dc.getRefreshTimeout()); - assertEquals(3, conf.getDivertConfigurations().size()); - for (DivertConfiguration dic : conf.getDivertConfigurations()) { + assertEquals(3, configInstance.getDivertConfigurations().size()); + for (DivertConfiguration dic : configInstance.getDivertConfigurations()) { if (dic.getName().equals("divert1")) { assertEquals("divert1", dic.getName()); assertEquals("routing-name1", dic.getRoutingName()); @@ -348,8 +353,8 @@ public void testFileConfiguration() { } } - assertEquals(6, conf.getConnectionRouters().size()); - for (ConnectionRouterConfiguration bc : conf.getConnectionRouters()) { + assertEquals(6, configInstance.getConnectionRouters().size()); + for (ConnectionRouterConfiguration bc : configInstance.getConnectionRouters()) { if (bc.getName().equals("simple-local")) { assertEquals(KeyType.CLIENT_ID, bc.getKeyType()); assertNotNull(bc.getLocalTargetFilter()); @@ -400,8 +405,8 @@ public void testFileConfiguration() { } } - assertEquals(4, conf.getBridgeConfigurations().size()); - for (BridgeConfiguration bc : conf.getBridgeConfigurations()) { + assertEquals(4, configInstance.getBridgeConfigurations().size()); + for (BridgeConfiguration bc : configInstance.getBridgeConfigurations()) { if (bc.getName().equals("bridge1")) { assertEquals("bridge1", bc.getName()); assertEquals("queue1", bc.getQueueName()); @@ -442,9 +447,9 @@ public void testFileConfiguration() { } } - assertEquals(3, conf.getClusterConfigurations().size()); + assertEquals(3, configInstance.getClusterConfigurations().size()); - HAPolicyConfiguration pc = conf.getHAPolicyConfiguration(); + HAPolicyConfiguration pc = configInstance.getHAPolicyConfiguration(); assertNotNull(pc); assertInstanceOf(PrimaryOnlyPolicyConfiguration.class, pc); PrimaryOnlyPolicyConfiguration lopc = (PrimaryOnlyPolicyConfiguration) pc; @@ -453,7 +458,7 @@ public void testFileConfiguration() { assertEquals("dg1", lopc.getScaleDownConfiguration().getDiscoveryGroup()); assertEquals(33, lopc.getScaleDownConfiguration().getCommitInterval()); - for (ClusterConnectionConfiguration ccc : conf.getClusterConfigurations()) { + for (ClusterConnectionConfiguration ccc : configInstance.getClusterConfigurations()) { if (ccc.getName().equals("cluster-connection3")) { assertEquals(MessageLoadBalancingType.OFF_WITH_REDISTRIBUTION, ccc.getMessageLoadBalancingType()); assertEquals(ActiveMQDefaultConfiguration.getDefaultClusterCallTimeout(), ccc.getCallTimeout()); @@ -495,125 +500,125 @@ public void testFileConfiguration() { } } - assertEquals(2, conf.getAddressSettings().size()); - - assertNotNull(conf.getAddressSettings().get("a1")); - assertNotNull(conf.getAddressSettings().get("a2")); - - assertEquals("a1.1", conf.getAddressSettings().get("a1").getDeadLetterAddress().toString()); - assertEquals(AddressSettings.DEFAULT_AUTO_CREATE_DEAD_LETTER_RESOURCES, conf.getAddressSettings().get("a1").isAutoCreateDeadLetterResources()); - assertEquals(AddressSettings.DEFAULT_DEAD_LETTER_QUEUE_PREFIX, conf.getAddressSettings().get("a1").getDeadLetterQueuePrefix()); - assertEquals(AddressSettings.DEFAULT_DEAD_LETTER_QUEUE_SUFFIX, conf.getAddressSettings().get("a1").getDeadLetterQueueSuffix()); - assertEquals("a1.2", conf.getAddressSettings().get("a1").getExpiryAddress().toString()); - assertEquals(1L, (long) conf.getAddressSettings().get("a1").getExpiryDelay()); - assertEquals(2L, (long) conf.getAddressSettings().get("a1").getMinExpiryDelay()); - assertEquals(3L, (long) conf.getAddressSettings().get("a1").getMaxExpiryDelay()); - assertTrue(conf.getAddressSettings().get("a1").isNoExpiry()); - assertEquals(AddressSettings.DEFAULT_AUTO_CREATE_EXPIRY_RESOURCES, conf.getAddressSettings().get("a1").isAutoCreateExpiryResources()); - assertEquals(AddressSettings.DEFAULT_EXPIRY_QUEUE_PREFIX, conf.getAddressSettings().get("a1").getExpiryQueuePrefix()); - assertEquals(AddressSettings.DEFAULT_EXPIRY_QUEUE_SUFFIX, conf.getAddressSettings().get("a1").getExpiryQueueSuffix()); - assertEquals(1, conf.getAddressSettings().get("a1").getRedeliveryDelay()); - assertEquals(0.5, conf.getAddressSettings().get("a1").getRedeliveryCollisionAvoidanceFactor(), 0); - assertEquals(856686592L, conf.getAddressSettings().get("a1").getMaxSizeBytes()); - assertEquals(817381738L, conf.getAddressSettings().get("a1").getPageSizeBytes()); - assertEquals(10, conf.getAddressSettings().get("a1").getPageCacheMaxSize()); - assertEquals(4, conf.getAddressSettings().get("a1").getMessageCounterHistoryDayLimit()); - assertEquals(10, conf.getAddressSettings().get("a1").getSlowConsumerThreshold()); - assertEquals(SlowConsumerThresholdMeasurementUnit.MESSAGES_PER_HOUR, conf.getAddressSettings().get("a1").getSlowConsumerThresholdMeasurementUnit()); - assertEquals(5, conf.getAddressSettings().get("a1").getSlowConsumerCheckPeriod()); - assertEquals(SlowConsumerPolicy.NOTIFY, conf.getAddressSettings().get("a1").getSlowConsumerPolicy()); - assertTrue(conf.getAddressSettings().get("a1").isAutoCreateJmsQueues()); - assertTrue(conf.getAddressSettings().get("a1").isAutoDeleteJmsQueues()); - assertTrue(conf.getAddressSettings().get("a1").isAutoCreateJmsTopics()); - assertTrue(conf.getAddressSettings().get("a1").isAutoDeleteJmsTopics()); - assertEquals(0, conf.getAddressSettings().get("a1").getAutoDeleteQueuesDelay()); - assertFalse(conf.getAddressSettings().get("a1").getAutoDeleteQueuesSkipUsageCheck()); - assertEquals(0, conf.getAddressSettings().get("a1").getAutoDeleteAddressesDelay()); - assertFalse(conf.getAddressSettings().get("a1").isAutoDeleteAddressesSkipUsageCheck()); - assertNotNull(conf.getAddressSettings().get("a1").isDefaultPurgeOnNoConsumers()); - assertFalse(conf.getAddressSettings().get("a1").isDefaultPurgeOnNoConsumers()); - assertEquals(Integer.valueOf(5), conf.getAddressSettings().get("a1").getDefaultMaxConsumers()); - assertEquals(RoutingType.ANYCAST, conf.getAddressSettings().get("a1").getDefaultQueueRoutingType()); - assertEquals(RoutingType.MULTICAST, conf.getAddressSettings().get("a1").getDefaultAddressRoutingType()); - assertEquals(3, conf.getAddressSettings().get("a1").getDefaultRingSize()); - assertEquals(0, conf.getAddressSettings().get("a1").getRetroactiveMessageCount()); - assertTrue(conf.getAddressSettings().get("a1").isEnableMetrics()); - assertTrue(conf.getAddressSettings().get("a1").isEnableIngressTimestamp()); - assertNull(conf.getAddressSettings().get("a1").getIDCacheSize()); - assertNull(conf.getAddressSettings().get("a1").getInitialQueueBufferSize()); - - assertEquals("a2.1", conf.getAddressSettings().get("a2").getDeadLetterAddress().toString()); - assertTrue(conf.getAddressSettings().get("a2").isAutoCreateDeadLetterResources()); - assertEquals("", conf.getAddressSettings().get("a2").getDeadLetterQueuePrefix().toString()); - assertEquals(".DLQ", conf.getAddressSettings().get("a2").getDeadLetterQueueSuffix().toString()); - assertEquals("a2.2", conf.getAddressSettings().get("a2").getExpiryAddress().toString()); - assertEquals(-1L, (long) conf.getAddressSettings().get("a2").getExpiryDelay()); - assertEquals(-1L, (long) conf.getAddressSettings().get("a2").getMinExpiryDelay()); - assertEquals(-1L, (long) conf.getAddressSettings().get("a2").getMaxExpiryDelay()); - assertFalse(conf.getAddressSettings().get("a2").isNoExpiry()); - assertTrue(conf.getAddressSettings().get("a2").isAutoCreateDeadLetterResources()); - assertEquals("", conf.getAddressSettings().get("a2").getExpiryQueuePrefix().toString()); - assertEquals(".EXP", conf.getAddressSettings().get("a2").getExpiryQueueSuffix().toString()); - assertEquals(5, conf.getAddressSettings().get("a2").getRedeliveryDelay()); - assertEquals(0.0, conf.getAddressSettings().get("a2").getRedeliveryCollisionAvoidanceFactor(), 0); - assertEquals(932489234928324L, conf.getAddressSettings().get("a2").getMaxSizeBytes()); - assertEquals(712671626L, conf.getAddressSettings().get("a2").getPageSizeBytes()); - assertEquals(20, conf.getAddressSettings().get("a2").getPageCacheMaxSize()); - assertEquals(8, conf.getAddressSettings().get("a2").getMessageCounterHistoryDayLimit()); - assertEquals(20, conf.getAddressSettings().get("a2").getSlowConsumerThreshold()); - assertEquals(SlowConsumerThresholdMeasurementUnit.MESSAGES_PER_DAY, conf.getAddressSettings().get("a2").getSlowConsumerThresholdMeasurementUnit()); - assertEquals(15, conf.getAddressSettings().get("a2").getSlowConsumerCheckPeriod()); - assertEquals(SlowConsumerPolicy.KILL, conf.getAddressSettings().get("a2").getSlowConsumerPolicy()); - assertFalse(conf.getAddressSettings().get("a2").isAutoCreateJmsQueues()); - assertFalse(conf.getAddressSettings().get("a2").isAutoDeleteJmsQueues()); - assertFalse(conf.getAddressSettings().get("a2").isAutoCreateJmsTopics()); - assertFalse(conf.getAddressSettings().get("a2").isAutoDeleteJmsTopics()); - assertEquals(500, conf.getAddressSettings().get("a2").getAutoDeleteQueuesDelay()); - assertTrue(conf.getAddressSettings().get("a2").getAutoDeleteQueuesSkipUsageCheck()); - assertEquals(1000, conf.getAddressSettings().get("a2").getAutoDeleteAddressesDelay()); - assertTrue(conf.getAddressSettings().get("a2").isAutoDeleteAddressesSkipUsageCheck()); - assertNotNull(conf.getAddressSettings().get("a2").isDefaultPurgeOnNoConsumers()); - assertTrue(conf.getAddressSettings().get("a2").isDefaultPurgeOnNoConsumers()); - assertEquals(Integer.valueOf(15), conf.getAddressSettings().get("a2").getDefaultMaxConsumers()); - assertEquals(RoutingType.MULTICAST, conf.getAddressSettings().get("a2").getDefaultQueueRoutingType()); - assertEquals(RoutingType.ANYCAST, conf.getAddressSettings().get("a2").getDefaultAddressRoutingType()); - assertEquals(10000, conf.getAddressSettings().get("a2").getDefaultConsumerWindowSize()); - assertEquals(-1, conf.getAddressSettings().get("a2").getDefaultRingSize()); - assertEquals(10, conf.getAddressSettings().get("a2").getRetroactiveMessageCount()); - assertFalse(conf.getAddressSettings().get("a2").isEnableMetrics()); - assertFalse(conf.getAddressSettings().get("a2").isEnableIngressTimestamp()); - assertEquals(Integer.valueOf(500), conf.getAddressSettings().get("a2").getIDCacheSize()); - assertEquals(Integer.valueOf(128), conf.getAddressSettings().get("a2").getInitialQueueBufferSize()); - - assertEquals(111, conf.getMirrorAckManagerQueueAttempts()); - assertTrue(conf.isMirrorAckManagerWarnUnacked()); - assertEquals(222, conf.getMirrorAckManagerPageAttempts()); - assertEquals(333, conf.getMirrorAckManagerRetryDelay()); - assertTrue(conf.isMirrorPageTransaction()); - - assertTrue(conf.getResourceLimitSettings().containsKey("myUser")); + assertEquals(2, configInstance.getAddressSettings().size()); + + assertNotNull(configInstance.getAddressSettings().get("a1")); + assertNotNull(configInstance.getAddressSettings().get("a2")); + + assertEquals("a1.1", configInstance.getAddressSettings().get("a1").getDeadLetterAddress().toString()); + assertEquals(AddressSettings.DEFAULT_AUTO_CREATE_DEAD_LETTER_RESOURCES, configInstance.getAddressSettings().get("a1").isAutoCreateDeadLetterResources()); + assertEquals(AddressSettings.DEFAULT_DEAD_LETTER_QUEUE_PREFIX, configInstance.getAddressSettings().get("a1").getDeadLetterQueuePrefix()); + assertEquals(AddressSettings.DEFAULT_DEAD_LETTER_QUEUE_SUFFIX, configInstance.getAddressSettings().get("a1").getDeadLetterQueueSuffix()); + assertEquals("a1.2", configInstance.getAddressSettings().get("a1").getExpiryAddress().toString()); + assertEquals(1L, (long) configInstance.getAddressSettings().get("a1").getExpiryDelay()); + assertEquals(2L, (long) configInstance.getAddressSettings().get("a1").getMinExpiryDelay()); + assertEquals(3L, (long) configInstance.getAddressSettings().get("a1").getMaxExpiryDelay()); + assertTrue(configInstance.getAddressSettings().get("a1").isNoExpiry()); + assertEquals(AddressSettings.DEFAULT_AUTO_CREATE_EXPIRY_RESOURCES, configInstance.getAddressSettings().get("a1").isAutoCreateExpiryResources()); + assertEquals(AddressSettings.DEFAULT_EXPIRY_QUEUE_PREFIX, configInstance.getAddressSettings().get("a1").getExpiryQueuePrefix()); + assertEquals(AddressSettings.DEFAULT_EXPIRY_QUEUE_SUFFIX, configInstance.getAddressSettings().get("a1").getExpiryQueueSuffix()); + assertEquals(1, configInstance.getAddressSettings().get("a1").getRedeliveryDelay()); + assertEquals(0.5, configInstance.getAddressSettings().get("a1").getRedeliveryCollisionAvoidanceFactor(), 0); + assertEquals(856686592L, configInstance.getAddressSettings().get("a1").getMaxSizeBytes()); + assertEquals(817381738L, configInstance.getAddressSettings().get("a1").getPageSizeBytes()); + assertEquals(10, configInstance.getAddressSettings().get("a1").getPageCacheMaxSize()); + assertEquals(4, configInstance.getAddressSettings().get("a1").getMessageCounterHistoryDayLimit()); + assertEquals(10, configInstance.getAddressSettings().get("a1").getSlowConsumerThreshold()); + assertEquals(SlowConsumerThresholdMeasurementUnit.MESSAGES_PER_HOUR, configInstance.getAddressSettings().get("a1").getSlowConsumerThresholdMeasurementUnit()); + assertEquals(5, configInstance.getAddressSettings().get("a1").getSlowConsumerCheckPeriod()); + assertEquals(SlowConsumerPolicy.NOTIFY, configInstance.getAddressSettings().get("a1").getSlowConsumerPolicy()); + assertTrue(configInstance.getAddressSettings().get("a1").isAutoCreateJmsQueues()); + assertTrue(configInstance.getAddressSettings().get("a1").isAutoDeleteJmsQueues()); + assertTrue(configInstance.getAddressSettings().get("a1").isAutoCreateJmsTopics()); + assertTrue(configInstance.getAddressSettings().get("a1").isAutoDeleteJmsTopics()); + assertEquals(0, configInstance.getAddressSettings().get("a1").getAutoDeleteQueuesDelay()); + assertFalse(configInstance.getAddressSettings().get("a1").getAutoDeleteQueuesSkipUsageCheck()); + assertEquals(0, configInstance.getAddressSettings().get("a1").getAutoDeleteAddressesDelay()); + assertFalse(configInstance.getAddressSettings().get("a1").isAutoDeleteAddressesSkipUsageCheck()); + assertNotNull(configInstance.getAddressSettings().get("a1").isDefaultPurgeOnNoConsumers()); + assertFalse(configInstance.getAddressSettings().get("a1").isDefaultPurgeOnNoConsumers()); + assertEquals(Integer.valueOf(5), configInstance.getAddressSettings().get("a1").getDefaultMaxConsumers()); + assertEquals(RoutingType.ANYCAST, configInstance.getAddressSettings().get("a1").getDefaultQueueRoutingType()); + assertEquals(RoutingType.MULTICAST, configInstance.getAddressSettings().get("a1").getDefaultAddressRoutingType()); + assertEquals(3, configInstance.getAddressSettings().get("a1").getDefaultRingSize()); + assertEquals(0, configInstance.getAddressSettings().get("a1").getRetroactiveMessageCount()); + assertTrue(configInstance.getAddressSettings().get("a1").isEnableMetrics()); + assertTrue(configInstance.getAddressSettings().get("a1").isEnableIngressTimestamp()); + assertNull(configInstance.getAddressSettings().get("a1").getIDCacheSize()); + assertNull(configInstance.getAddressSettings().get("a1").getInitialQueueBufferSize()); + + assertEquals("a2.1", configInstance.getAddressSettings().get("a2").getDeadLetterAddress().toString()); + assertTrue(configInstance.getAddressSettings().get("a2").isAutoCreateDeadLetterResources()); + assertEquals("", configInstance.getAddressSettings().get("a2").getDeadLetterQueuePrefix().toString()); + assertEquals(".DLQ", configInstance.getAddressSettings().get("a2").getDeadLetterQueueSuffix().toString()); + assertEquals("a2.2", configInstance.getAddressSettings().get("a2").getExpiryAddress().toString()); + assertEquals(-1L, (long) configInstance.getAddressSettings().get("a2").getExpiryDelay()); + assertEquals(-1L, (long) configInstance.getAddressSettings().get("a2").getMinExpiryDelay()); + assertEquals(-1L, (long) configInstance.getAddressSettings().get("a2").getMaxExpiryDelay()); + assertFalse(configInstance.getAddressSettings().get("a2").isNoExpiry()); + assertTrue(configInstance.getAddressSettings().get("a2").isAutoCreateDeadLetterResources()); + assertEquals("", configInstance.getAddressSettings().get("a2").getExpiryQueuePrefix().toString()); + assertEquals(".EXP", configInstance.getAddressSettings().get("a2").getExpiryQueueSuffix().toString()); + assertEquals(5, configInstance.getAddressSettings().get("a2").getRedeliveryDelay()); + assertEquals(0.0, configInstance.getAddressSettings().get("a2").getRedeliveryCollisionAvoidanceFactor(), 0); + assertEquals(932489234928324L, configInstance.getAddressSettings().get("a2").getMaxSizeBytes()); + assertEquals(712671626L, configInstance.getAddressSettings().get("a2").getPageSizeBytes()); + assertEquals(20, configInstance.getAddressSettings().get("a2").getPageCacheMaxSize()); + assertEquals(8, configInstance.getAddressSettings().get("a2").getMessageCounterHistoryDayLimit()); + assertEquals(20, configInstance.getAddressSettings().get("a2").getSlowConsumerThreshold()); + assertEquals(SlowConsumerThresholdMeasurementUnit.MESSAGES_PER_DAY, configInstance.getAddressSettings().get("a2").getSlowConsumerThresholdMeasurementUnit()); + assertEquals(15, configInstance.getAddressSettings().get("a2").getSlowConsumerCheckPeriod()); + assertEquals(SlowConsumerPolicy.KILL, configInstance.getAddressSettings().get("a2").getSlowConsumerPolicy()); + assertFalse(configInstance.getAddressSettings().get("a2").isAutoCreateJmsQueues()); + assertFalse(configInstance.getAddressSettings().get("a2").isAutoDeleteJmsQueues()); + assertFalse(configInstance.getAddressSettings().get("a2").isAutoCreateJmsTopics()); + assertFalse(configInstance.getAddressSettings().get("a2").isAutoDeleteJmsTopics()); + assertEquals(500, configInstance.getAddressSettings().get("a2").getAutoDeleteQueuesDelay()); + assertTrue(configInstance.getAddressSettings().get("a2").getAutoDeleteQueuesSkipUsageCheck()); + assertEquals(1000, configInstance.getAddressSettings().get("a2").getAutoDeleteAddressesDelay()); + assertTrue(configInstance.getAddressSettings().get("a2").isAutoDeleteAddressesSkipUsageCheck()); + assertNotNull(configInstance.getAddressSettings().get("a2").isDefaultPurgeOnNoConsumers()); + assertTrue(configInstance.getAddressSettings().get("a2").isDefaultPurgeOnNoConsumers()); + assertEquals(Integer.valueOf(15), configInstance.getAddressSettings().get("a2").getDefaultMaxConsumers()); + assertEquals(RoutingType.MULTICAST, configInstance.getAddressSettings().get("a2").getDefaultQueueRoutingType()); + assertEquals(RoutingType.ANYCAST, configInstance.getAddressSettings().get("a2").getDefaultAddressRoutingType()); + assertEquals(10000, configInstance.getAddressSettings().get("a2").getDefaultConsumerWindowSize()); + assertEquals(-1, configInstance.getAddressSettings().get("a2").getDefaultRingSize()); + assertEquals(10, configInstance.getAddressSettings().get("a2").getRetroactiveMessageCount()); + assertFalse(configInstance.getAddressSettings().get("a2").isEnableMetrics()); + assertFalse(configInstance.getAddressSettings().get("a2").isEnableIngressTimestamp()); + assertEquals(Integer.valueOf(500), configInstance.getAddressSettings().get("a2").getIDCacheSize()); + assertEquals(Integer.valueOf(128), configInstance.getAddressSettings().get("a2").getInitialQueueBufferSize()); + + assertEquals(111, configInstance.getMirrorAckManagerQueueAttempts()); + assertTrue(configInstance.isMirrorAckManagerWarnUnacked()); + assertEquals(222, configInstance.getMirrorAckManagerPageAttempts()); + assertEquals(333, configInstance.getMirrorAckManagerRetryDelay()); + assertTrue(configInstance.isMirrorPageTransaction()); + + assertTrue(configInstance.getResourceLimitSettings().containsKey("myUser")); // continue testing deprecated method - assertEquals(104, conf.getResourceLimitSettings().get("myUser").getMaxConnections()); - assertEquals(104, conf.getResourceLimitSettings().get("myUser").getMaxSessions()); - assertEquals(13, conf.getResourceLimitSettings().get("myUser").getMaxQueues()); + assertEquals(104, configInstance.getResourceLimitSettings().get("myUser").getMaxConnections()); + assertEquals(104, configInstance.getResourceLimitSettings().get("myUser").getMaxSessions()); + assertEquals(13, configInstance.getResourceLimitSettings().get("myUser").getMaxQueues()); - assertEquals(2, conf.getQueueConfigs().size()); + assertEquals(2, configInstance.getQueueConfigs().size()); - assertEquals("queue1", conf.getQueueConfigs().get(0).getName().toString()); - assertEquals("address1", conf.getQueueConfigs().get(0).getAddress().toString()); - assertEquals("color='red'", conf.getQueueConfigs().get(0).getFilterString().toString()); - assertNotNull(conf.getQueueConfigs().get(0).isDurable()); - assertFalse(conf.getQueueConfigs().get(0).isDurable()); + assertEquals("queue1", configInstance.getQueueConfigs().get(0).getName().toString()); + assertEquals("address1", configInstance.getQueueConfigs().get(0).getAddress().toString()); + assertEquals("color='red'", configInstance.getQueueConfigs().get(0).getFilterString().toString()); + assertNotNull(configInstance.getQueueConfigs().get(0).isDurable()); + assertFalse(configInstance.getQueueConfigs().get(0).isDurable()); - assertEquals("queue2", conf.getQueueConfigs().get(1).getName().toString()); - assertEquals("address2", conf.getQueueConfigs().get(1).getAddress().toString()); - assertEquals("color='blue'", conf.getQueueConfigs().get(1).getFilterString().toString()); - assertNotNull(conf.getQueueConfigs().get(1).isDurable()); - assertFalse(conf.getQueueConfigs().get(1).isDurable()); + assertEquals("queue2", configInstance.getQueueConfigs().get(1).getName().toString()); + assertEquals("address2", configInstance.getQueueConfigs().get(1).getAddress().toString()); + assertEquals("color='blue'", configInstance.getQueueConfigs().get(1).getFilterString().toString()); + assertNotNull(configInstance.getQueueConfigs().get(1).isDurable()); + assertFalse(configInstance.getQueueConfigs().get(1).isDurable()); verifyAddresses(); - Map> roles = conf.getSecurityRoles(); + Map> roles = configInstance.getSecurityRoles(); assertEquals(2, roles.size()); @@ -640,26 +645,26 @@ public void testFileConfiguration() { assertFalse(a2Role.isCreateNonDurableQueue()); assertTrue(a2Role.isDeleteNonDurableQueue()); assertFalse(a2Role.isManage()); - assertEquals(1234567, conf.getGlobalMaxSize()); - assertEquals(37, conf.getMaxDiskUsage()); - assertEquals(123, conf.getDiskScanPeriod()); + assertEquals(1234567, configInstance.getGlobalMaxSize()); + assertEquals(37, configInstance.getMaxDiskUsage()); + assertEquals(123, configInstance.getDiskScanPeriod()); - assertEquals(333, conf.getCriticalAnalyzerCheckPeriod()); - assertEquals(777, conf.getCriticalAnalyzerTimeout()); - assertFalse(conf.isCriticalAnalyzer()); - assertEquals(CriticalAnalyzerPolicy.HALT, conf.getCriticalAnalyzerPolicy()); + assertEquals(333, configInstance.getCriticalAnalyzerCheckPeriod()); + assertEquals(777, configInstance.getCriticalAnalyzerTimeout()); + assertFalse(configInstance.isCriticalAnalyzer()); + assertEquals(CriticalAnalyzerPolicy.HALT, configInstance.getCriticalAnalyzerPolicy()); - assertFalse(conf.isJournalDatasync()); + assertFalse(configInstance.isJournalDatasync()); // keep test for backwards compatibility - ActiveMQMetricsPlugin metricsPlugin = conf.getMetricsPlugin(); + ActiveMQMetricsPlugin metricsPlugin = configInstance.getMetricsPlugin(); assertInstanceOf(SimpleMetricsPlugin.class, metricsPlugin); Map options = ((SimpleMetricsPlugin) metricsPlugin).getOptions(); assertEquals("x", options.get("foo")); assertEquals("y", options.get("bar")); assertEquals("z", options.get("baz")); - MetricsConfiguration metricsConfiguration = conf.getMetricsConfiguration(); + MetricsConfiguration metricsConfiguration = configInstance.getMetricsConfiguration(); assertInstanceOf(SimpleMetricsPlugin.class, metricsConfiguration.getPlugin()); options = ((SimpleMetricsPlugin) metricsPlugin).getOptions(); assertEquals("x", options.get("foo")); @@ -1020,6 +1025,22 @@ public void testSetConnectionRoutersPolicyConfiguration() throws Throwable { doSetConnectionRoutersPolicyConfigurationTestImpl(new FileConfiguration()); } + @TestTemplate() + public void testExportImportFromProperties() throws Exception { + File exported = new File(getTestDirfile(), "broker_config_as_properties_export.txt"); + + conf.exportAsProperties(exported); + + ConfigurationImpl configuration = new FileConfiguration(); + configuration.parseFileProperties(exported); + + assertTrue(configuration.getStatus().contains("\"errors\":[]")); + + assertTrue(REDACTED.equals(configuration.getClusterPassword())); + configuration.setClusterPassword("Wombat"); + validateFullConfig(configuration); + } + private Configuration createConfiguration(String filename) throws Exception { FileConfiguration fc = new FileConfiguration(); FileDeploymentManager deploymentManager = new FileDeploymentManager(filename); diff --git a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml index 543b2e96efc..db79760739b 100644 --- a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml +++ b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml @@ -90,13 +90,13 @@ vm://5 - + tcp://0.0.0.0:61616? tcpNoDelay=456; connectionTtl=44; connectionsAllowed=${ninetyTwoProp} - vm://0?e1=z1;e2=567;connectionsAllowed=87 + vm://0?e1=z1;e2=567;connectionsAllowed=87 @@ -654,7 +654,7 @@ - + org.foo diff --git a/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-acceptors.xml b/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-acceptors.xml index 9ebad5712ff..26e16361428 100644 --- a/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-acceptors.xml +++ b/artemis-server/src/test/resources/ConfigurationTest-xinclude-config-acceptors.xml @@ -15,6 +15,6 @@ limitations under the License. --> - tcp://0.0.0.0:61616?tcpNoDelay=456;connectionTtl=44;connectionsAllowed=${ninetyTwoProp} - vm://0?e1=z1;e2=567;connectionsAllowed=87 + tcp://0.0.0.0:61616?tcpNoDelay=456;connectionTtl=44;connectionsAllowed=${ninetyTwoProp} + vm://0?e1=z1;e2=567;connectionsAllowed=87 \ No newline at end of file diff --git a/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-acceptors.xml b/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-acceptors.xml index 9ebad5712ff..26e16361428 100644 --- a/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-acceptors.xml +++ b/artemis-server/src/test/resources/ConfigurationTest-xinclude-schema-config-acceptors.xml @@ -15,6 +15,6 @@ limitations under the License. --> - tcp://0.0.0.0:61616?tcpNoDelay=456;connectionTtl=44;connectionsAllowed=${ninetyTwoProp} - vm://0?e1=z1;e2=567;connectionsAllowed=87 + tcp://0.0.0.0:61616?tcpNoDelay=456;connectionTtl=44;connectionsAllowed=${ninetyTwoProp} + vm://0?e1=z1;e2=567;connectionsAllowed=87 \ No newline at end of file diff --git a/docs/user-manual/management.adoc b/docs/user-manual/management.adoc index c08e51d44f1..b5244b53841 100644 --- a/docs/user-manual/management.adoc +++ b/docs/user-manual/management.adoc @@ -86,6 +86,12 @@ To do this use the `forceFailover()` operation. Since this method actually stops the server you will probably receive some sort of error depending on which management service you use to call it. ==== +* The effective configuration of the broker core can be exported as properties using `exportConfigAsProperties()`. This operation will write a file to the broker's tmp dir called `broker_config_as_properties.txt`. The content can provide an entry point for using xref:configuration-index.adoc#broker-properties[brokerProperties]. + +[NOTE] +==== +The broker's tmp dir is configured via the system property `java.io.tmpdir`. The default value, set via the launch scripts, is `$ARTEMIS_INSTANCE/tmp`. +==== === Address Management diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java index cbca87d0be4..1581f300083 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlTest.java @@ -26,6 +26,8 @@ import javax.jms.TopicSubscriber; import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; +import java.io.File; +import java.io.FileReader; import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.nio.ByteBuffer; @@ -39,6 +41,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.UUID; import java.util.concurrent.CountDownLatch; @@ -83,6 +86,7 @@ import org.apache.activemq.artemis.core.config.DivertConfiguration; import org.apache.activemq.artemis.core.config.brokerConnectivity.BrokerConnectConfiguration; import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration; +import org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl; import org.apache.activemq.artemis.core.management.impl.view.ConnectionField; import org.apache.activemq.artemis.core.management.impl.view.ConsumerField; import org.apache.activemq.artemis.core.management.impl.view.ProducerField; @@ -138,6 +142,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl.TMP_DIR_SYSTEM_PROPERTY; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -380,6 +385,22 @@ public void testAuthCounts() throws Exception { assertEquals(1, serverControl.getAuthorizationFailureCount()); } + @TestTemplate + public void testExportAsProperties() throws Exception { + + ActiveMQServerControl serverControl = createManagementControl(); + + serverControl.exportConfigAsProperties(); + + File out = new File(System.getProperty(TMP_DIR_SYSTEM_PROPERTY), ActiveMQServerControlImpl.CONFIG_AS_PROPERTIES_FILE); + assertTrue(out.exists()); + try (FileReader reader = new FileReader(out)) { + Properties properties = new Properties(); + properties.load(reader); + assertEquals(properties.getProperty("name"), serverControl.getName()); + } + } + @TestTemplate public void testGetConnectors() throws Exception { ActiveMQServerControl serverControl = createManagementControl(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java index 1260cd7bb05..4464cac8f9d 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java @@ -1856,6 +1856,11 @@ public long getAuthorizationSuccessCount() { public long getAuthorizationFailureCount() { return (long) proxy.retrieveAttributeValue("authorizationFailureCount"); } + + @Override + public void exportConfigAsProperties() throws Exception { + proxy.invokeOperation("exportConfigAsProperties"); + } }; }