From cc9db6b2f79b6cf0d82167fa3ba5c087abc69982 Mon Sep 17 00:00:00 2001 From: Domenico Francesco Bruscino Date: Wed, 19 Apr 2023 17:01:28 +0200 Subject: [PATCH] ARTEMIS-4244 Set web config using system properties --- .../activemq/artemis/cli/commands/Run.java | 4 + .../artemis/cli/commands/Upgrade.java | 11 +- .../commands/etc/bootstrap-web-settings.txt | 8 +- .../config/ActiveMQDefaultConfiguration.java | 6 + .../apache/activemq/artemis/dto/AppDTO.java | 31 +++ .../activemq/artemis/dto/BindingDTO.java | 68 +++++++ .../activemq/artemis/dto/WebServerDTO.java | 57 +++++- .../artemis/dto/test/WebServerDTOTest.java | 24 +-- .../artemis/core/config/Configuration.java | 3 + .../core/config/impl/ConfigurationImpl.java | 15 +- .../artemis/component/WebServerComponent.java | 2 +- docs/user-manual/en/web-server.md | 38 ++++ .../web/WebServerDTOConfigTest.java | 183 ++++++++++++++++++ 13 files changed, 420 insertions(+), 30 deletions(-) create mode 100644 tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/web/WebServerDTOConfigTest.java diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java index 1604d3854b..281852d68b 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java @@ -133,6 +133,10 @@ public class Run extends LockAbstract { broker.components.add(broker.web); } + String systemWebPropertyPrefix = ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix(); + server.getServer().getConfiguration().parsePrefixedProperties(broker.web, + "system-" + systemWebPropertyPrefix, System.getProperties(), systemWebPropertyPrefix); + for (ComponentDTO componentDTO : broker.components) { Class clazz = this.getClass().getClassLoader().loadClass(componentDTO.componentClassName); ExternalComponent component = (ExternalComponent) clazz.getDeclaredConstructor(null).newInstance(); diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Upgrade.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Upgrade.java index 9e43ee9669..953b782a3a 100644 --- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Upgrade.java +++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Upgrade.java @@ -182,7 +182,12 @@ public class Upgrade extends InstallAbstract { final File bootstrapXmlBkp = new File(etcBkp, Create.ETC_BOOTSTRAP_XML); Files.copy(bootstrapXml.toPath(), bootstrapXmlTmp.toPath()); - replaceLines(context, bootstrapXmlTmp, bootstrapXml, bootstrapXmlBkp, ""); + replaceLines(context, bootstrapXmlTmp, bootstrapXml, bootstrapXmlBkp, + "^(.*)", + "^(.*) { for (int i = 0; i < replacePairs.length; i += 2) { - if (newLine.trim().startsWith(replacePairs[i])) { - return replacePairs[i + 1]; + if (newLine.matches(replacePairs[i])) { + return newLine.replaceAll(replacePairs[i], replacePairs[i + 1]); } } return newLine; diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt index 0e79e4e6bc..a564e3431d 100644 --- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt +++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/bootstrap-web-settings.txt @@ -1,8 +1,8 @@ - - - - + + + + diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java index 41eedc73a2..05e8e7494d 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java @@ -563,6 +563,8 @@ public final class ActiveMQDefaultConfiguration { public static final String DEFAULT_SYSTEM_PROPERTY_PREFIX = "brokerconfig."; + public static final String DEFAULT_SYSTEM_WEB_PROPERTY_PREFIX = "webconfig."; + public static final String BROKER_PROPERTIES_SYSTEM_PROPERTY_NAME = "broker.properties"; public static final String BROKER_PROPERTIES_KEY_SURROUND = "\""; @@ -1615,6 +1617,10 @@ public final class ActiveMQDefaultConfiguration { return DEFAULT_SYSTEM_PROPERTY_PREFIX; } + public static String getDefaultSystemWebPropertyPrefix() { + return DEFAULT_SYSTEM_WEB_PROPERTY_PREFIX; + } + public static String getDefaultBrokerPropertiesKeySurround() { return BROKER_PROPERTIES_KEY_SURROUND; } diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AppDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AppDTO.java index 5609509b00..c4af7ecb9d 100644 --- a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AppDTO.java +++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/AppDTO.java @@ -25,9 +25,40 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlAccessorType(XmlAccessType.FIELD) public class AppDTO { + @XmlAttribute + public String name; + @XmlAttribute public String url; @XmlAttribute public String war; + + public String getName() { + if (name == null) { + return url; + } + + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getWar() { + return war; + } + + public void setWar(String war) { + this.war = war; + } } diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/BindingDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/BindingDTO.java index 32cfcb91ce..f436a5c4b7 100644 --- a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/BindingDTO.java +++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/BindingDTO.java @@ -23,12 +23,16 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; import java.util.List; @XmlRootElement(name = "binding") @XmlAccessorType(XmlAccessType.FIELD) public class BindingDTO { + @XmlAttribute + public String name; + @XmlAttribute public String uri; @@ -117,6 +121,70 @@ public class BindingDTO { excludedCipherSuites = marshalArray(cipherSuites); } + public String getName() { + if (name == null) { + return uri; + } + + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public Boolean getClientAuth() { + return clientAuth; + } + + public void setClientAuth(Boolean clientAuth) { + this.clientAuth = clientAuth; + } + + public String getPasswordCodec() { + return passwordCodec; + } + + public void setPasswordCodec(String passwordCodec) { + this.passwordCodec = passwordCodec; + } + + public String getKeyStorePath() { + return keyStorePath; + } + + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } + + public String getTrustStorePath() { + return trustStorePath; + } + + public void setTrustStorePath(String trustStorePath) { + this.trustStorePath = trustStorePath; + } + + public List getApps() { + return apps; + } + + public void addApp(AppDTO app) { + apps.add(app); + } + + public BindingDTO() { + apps = new ArrayList<>(); + } + private String[] unmarshalArray(String text) { if (text == null) { return null; diff --git a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java index 9910c6a456..b6360113dd 100644 --- a/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java +++ b/artemis-dto/src/main/java/org/apache/activemq/artemis/dto/WebServerDTO.java @@ -21,6 +21,7 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElementRef; import javax.xml.bind.annotation.XmlRootElement; +import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -94,11 +95,61 @@ public class WebServerDTO extends ComponentDTO { @XmlAttribute public Boolean webContentEnabled; - public WebServerDTO() { - componentClassName = "org.apache.activemq.artemis.component.WebServerComponent"; + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getCustomizer() { + return customizer; + } + + public void setCustomizer(String customizer) { + this.customizer = customizer; + } + + public RequestLogDTO getRequestLog() { + return requestLog; + } + + public void setRequestLog(RequestLogDTO requestLog) { + this.requestLog = requestLog; + } + + public String getRootRedirectLocation() { + return rootRedirectLocation; + } + + public void setRootRedirectLocation(String rootRedirectLocation) { + this.rootRedirectLocation = rootRedirectLocation; + } + + public Boolean getWebContentEnabled() { + return webContentEnabled; + } + + public void setWebContentEnabled(Boolean webContentEnabled) { + this.webContentEnabled = webContentEnabled; } public List getBindings() { + return bindings; + } + + public void addBinding(BindingDTO binding) { + bindings.add(binding); + } + + + public WebServerDTO() { + componentClassName = "org.apache.activemq.artemis.component.WebServerComponent"; + bindings = new ArrayList<>(); + } + + public List getAllBindings() { if (bindings == null || bindings.isEmpty()) { return Collections.singletonList(convertToBindingDTO()); } @@ -127,6 +178,6 @@ public class WebServerDTO extends ComponentDTO { } public BindingDTO getDefaultBinding() { - return getBindings().get(0); + return getAllBindings().get(0); } } diff --git a/artemis-dto/src/test/java/org/apache/activemq/artemis/dto/test/WebServerDTOTest.java b/artemis-dto/src/test/java/org/apache/activemq/artemis/dto/test/WebServerDTOTest.java index b3d3e2a3d8..9756315af5 100644 --- a/artemis-dto/src/test/java/org/apache/activemq/artemis/dto/test/WebServerDTOTest.java +++ b/artemis-dto/src/test/java/org/apache/activemq/artemis/dto/test/WebServerDTOTest.java @@ -30,8 +30,8 @@ public class WebServerDTOTest { public void testDefault() throws Exception { WebServerDTO webServer = new WebServerDTO(); - Assert.assertNotNull(webServer.getBindings()); - Assert.assertEquals(1, webServer.getBindings().size()); + Assert.assertNotNull(webServer.getAllBindings()); + Assert.assertEquals(1, webServer.getAllBindings().size()); Assert.assertNotNull(webServer.getDefaultBinding()); BindingDTO defaultBinding = webServer.getDefaultBinding(); @@ -54,8 +54,8 @@ public class WebServerDTOTest { WebServerDTO webServer = new WebServerDTO(); webServer.bind = "http://localhost:0"; - Assert.assertNotNull(webServer.getBindings()); - Assert.assertEquals(1, webServer.getBindings().size()); + Assert.assertNotNull(webServer.getAllBindings()); + Assert.assertEquals(1, webServer.getAllBindings().size()); Assert.assertNotNull(webServer.getDefaultBinding()); Assert.assertEquals("http://localhost:0", webServer.getDefaultBinding().uri); } @@ -68,8 +68,8 @@ public class WebServerDTOTest { WebServerDTO webServer = new WebServerDTO(); webServer.setBindings(Collections.singletonList(binding)); - Assert.assertNotNull(webServer.getBindings()); - Assert.assertEquals(1, webServer.getBindings().size()); + Assert.assertNotNull(webServer.getAllBindings()); + Assert.assertEquals(1, webServer.getAllBindings().size()); Assert.assertNotNull(webServer.getDefaultBinding()); Assert.assertEquals("http://localhost:0", webServer.getDefaultBinding().uri); } @@ -84,12 +84,12 @@ public class WebServerDTOTest { WebServerDTO webServer = new WebServerDTO(); webServer.setBindings(List.of(binding1, binding2)); - Assert.assertNotNull(webServer.getBindings()); - Assert.assertEquals(2, webServer.getBindings().size()); + Assert.assertNotNull(webServer.getAllBindings()); + Assert.assertEquals(2, webServer.getAllBindings().size()); Assert.assertNotNull(webServer.getDefaultBinding()); Assert.assertEquals("http://localhost:0", webServer.getDefaultBinding().uri); - Assert.assertEquals("http://localhost:0", webServer.getBindings().get(0).uri); - Assert.assertEquals("http://localhost:1", webServer.getBindings().get(1).uri); + Assert.assertEquals("http://localhost:0", webServer.getAllBindings().get(0).uri); + Assert.assertEquals("http://localhost:1", webServer.getAllBindings().get(1).uri); } @Test @@ -101,8 +101,8 @@ public class WebServerDTOTest { webServer.bind = "http://localhost:1"; webServer.setBindings(Collections.singletonList(binding)); - Assert.assertNotNull(webServer.getBindings()); - Assert.assertEquals(1, webServer.getBindings().size()); + Assert.assertNotNull(webServer.getAllBindings()); + Assert.assertEquals(1, webServer.getAllBindings().size()); Assert.assertNotNull(webServer.getDefaultBinding()); Assert.assertEquals("http://localhost:0", webServer.getDefaultBinding().uri); } 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 42ca44adf4..29dd21b2c5 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 @@ -20,6 +20,7 @@ import java.io.File; import java.net.URL; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -89,6 +90,8 @@ public interface Configuration { Configuration parseProperties(String optionalUrlToPropertiesFile) throws Exception; + void parsePrefixedProperties(Object target, String name, Properties properties, String prefix) throws Exception; + boolean isCriticalAnalyzer(); Configuration setCriticalAnalyzer(boolean CriticalAnalyzer); 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 167c28543d..37db97b804 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 @@ -526,7 +526,7 @@ public class ConfigurationImpl implements Configuration, Serializable { BufferedInputStream reader = new BufferedInputStream(fileInputStream)) { brokerProperties.clear(); brokerProperties.load(reader); - parsePrefixedProperties(fileName, brokerProperties, null); + parsePrefixedProperties(this, fileName, brokerProperties, null); } } } @@ -536,7 +536,7 @@ public class ConfigurationImpl implements Configuration, Serializable { try (FileInputStream fileInputStream = new FileInputStream(file); BufferedInputStream reader = new BufferedInputStream(fileInputStream)) { brokerProperties.load(reader); - parsePrefixedProperties(file.getName(), brokerProperties, null); + parsePrefixedProperties(this, file.getName(), brokerProperties, null); } } } @@ -546,10 +546,11 @@ public class ConfigurationImpl implements Configuration, Serializable { } public void parsePrefixedProperties(Properties properties, String prefix) throws Exception { - parsePrefixedProperties("system", properties, prefix); + parsePrefixedProperties(this, "system-" + prefix, properties, prefix); } - public void parsePrefixedProperties(String name, Properties properties, String prefix) throws Exception { + @Override + public void parsePrefixedProperties(Object target, String name, Properties properties, String prefix) throws Exception { Map beanProperties = new LinkedHashMap<>(); long alder32Hash = 0; synchronized (properties) { @@ -582,11 +583,11 @@ public class ConfigurationImpl implements Configuration, Serializable { updateReadPropertiesStatus(name, alder32Hash); if (!beanProperties.isEmpty()) { - populateWithProperties(name, beanProperties); + populateWithProperties(target, name, beanProperties); } } - public void populateWithProperties(final String propsId, Map beanProperties) throws InvocationTargetException, IllegalAccessException { + public void populateWithProperties(final Object target, final String propsId, Map beanProperties) throws InvocationTargetException, IllegalAccessException { CollectionAutoFillPropertiesUtil autoFillCollections = new CollectionAutoFillPropertiesUtil(); BeanUtilsBean beanUtils = new BeanUtilsBean(new ConvertUtilsBean(), autoFillCollections) { // override to treat missing properties as errors, not skip as the default impl does @@ -770,7 +771,7 @@ public class ConfigurationImpl implements Configuration, Serializable { final String name = entry.getKey(); try { // Perform the assignment for this property - beanUtils.setProperty(this, name, entry.getValue()); + beanUtils.setProperty(target, name, entry.getValue()); } catch (InvocationTargetException invocationTargetException) { logger.trace("failed to populate property with key: {}", name, invocationTargetException); Throwable toLog = invocationTargetException; diff --git a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java index 56842d3b49..6271abb0d4 100644 --- a/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java +++ b/artemis-web/src/main/java/org/apache/activemq/artemis/component/WebServerComponent.java @@ -108,7 +108,7 @@ public class WebServerComponent implements ExternalComponent, WebServerComponent } } - List bindings = this.webServerConfig.getBindings(); + List bindings = this.webServerConfig.getAllBindings(); connectors = new ServerConnector[bindings.size()]; String[] virtualHosts = new String[bindings.size()]; diff --git a/docs/user-manual/en/web-server.md b/docs/user-manual/en/web-server.md index d6ff76389e..a5a3b68981 100644 --- a/docs/user-manual/en/web-server.md +++ b/docs/user-manual/en/web-server.md @@ -109,6 +109,44 @@ Here is an example configuration: ``` +### System properties + +It is possible to use system properties to add or update web configuration items. +If you define a system property starting with "webconfig." it will be parsed at the startup +to update the web configuration. + +To enable the client authentication for an existing binding with the name `artemis`, +set the system property `webconfig.bindings.artemis.clientAuth` to `true`, i.e. + +``` +java -Dwebconfig.bindings.artemis.clientAuth=true +``` + +To add a new binding or app set the new binding or app attributes using their new names, i.e. + +``` +java -Dwebconfig.bindings.my-binding.uri=http://localhost:8162 +java -Dwebconfig.bindings.my-binding.apps.my-app.uri=my-app +java -Dwebconfig.bindings.my-binding.apps.my-app.war=my-app.war +``` + +To update a binding without a name use its uri and to update an app without a name use its url , i.e. + +```xml + + + +... +``` + +``` +java -Dwebconfig.bindings."http://localhost:8161".clientAuth=true +``` + +``` +java -Dwebconfig.bindings."http://localhost:8161".apps."activemq-branding".war=my-branding.war +``` + ## Proxy Forwarding The proxies and load balancers usually support `X-Forwarded` headers diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/web/WebServerDTOConfigTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/web/WebServerDTOConfigTest.java new file mode 100644 index 0000000000..d876a8bdc0 --- /dev/null +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/web/WebServerDTOConfigTest.java @@ -0,0 +1,183 @@ +/* + * 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.tests.integration.web; + +import java.util.Properties; + +import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration; +import org.apache.activemq.artemis.api.core.JsonUtil; +import org.apache.activemq.artemis.core.config.Configuration; +import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl; +import org.apache.activemq.artemis.dto.AppDTO; +import org.apache.activemq.artemis.dto.BindingDTO; +import org.apache.activemq.artemis.dto.WebServerDTO; +import org.apache.activemq.artemis.json.JsonArray; +import org.apache.activemq.artemis.json.JsonObject; +import org.junit.Assert; +import org.junit.Test; + +public class WebServerDTOConfigTest { + + private static final String INVALID_ATTRIBUTE_NAME = "invalidAttribute"; + private static final String BINDING_TEST_NAME = "test-binding"; + private static final String BINDING_TEST_URL = "http://localhost:61616"; + private static final String APP_TEST_NAME = "test-app"; + private static final String APP_TEST_URL = "test-url"; + + @Test + public void testSetWebProperties() throws Throwable { + WebServerDTO webServer = new WebServerDTO(); + Properties properties = new Properties(); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "customizer", "customizerTest"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "rootRedirectLocation", "locationTest"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "webContentEnabled", "true"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + INVALID_ATTRIBUTE_NAME, "true"); + Configuration configuration = new ConfigurationImpl(); + String systemWebPropertyPrefix = ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix(); + configuration.parsePrefixedProperties(webServer, "system-" + systemWebPropertyPrefix, properties, systemWebPropertyPrefix); + + Assert.assertEquals("customizerTest", webServer.getCustomizer()); + Assert.assertEquals("locationTest", webServer.getRootRedirectLocation()); + Assert.assertEquals(true, webServer.getWebContentEnabled()); + + testStatus(configuration.getStatus(), "system-" + systemWebPropertyPrefix, ""); + } + + @Test + public void testSetNewWebBindingProperties() throws Throwable { + WebServerDTO webServer = new WebServerDTO(); + + testSetWebBindingProperties(webServer, BINDING_TEST_NAME); + } + + @Test + public void testSetExistingWebBindingProperties() throws Throwable { + WebServerDTO webServer = new WebServerDTO(); + BindingDTO exitingBinding = new BindingDTO(); + exitingBinding.setName(BINDING_TEST_NAME); + webServer.addBinding(exitingBinding); + + testSetWebBindingProperties(webServer, BINDING_TEST_NAME); + } + + @Test + public void testSetExistingWebBindingWithoutNameProperties() throws Throwable { + WebServerDTO webServer = new WebServerDTO(); + BindingDTO exitingBinding = new BindingDTO(); + exitingBinding.setUri(BINDING_TEST_URL); + webServer.addBinding(exitingBinding); + + testSetWebBindingProperties(webServer, BINDING_TEST_URL); + } + + private void testSetWebBindingProperties(WebServerDTO webServer, String bindingName) throws Throwable { + Properties properties = new Properties(); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".uri", BINDING_TEST_URL); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".clientAuth", "true"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".passwordCodec", "test-passwordCodec"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".keyStorePath", "test-keyStorePath"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".trustStorePath", "test-trustStorePath"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".includedTLSProtocols", "test-includedTLSProtocols,0"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".excludedTLSProtocols", "test-excludedTLSProtocols,1"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".includedCipherSuites", "test-includedCipherSuites,2"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".excludedCipherSuites", "test-excludedCipherSuites,3"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".keyStorePassword", "test-keyStorePassword"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".trustStorePassword", "test-trustStorePassword"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + "." + INVALID_ATTRIBUTE_NAME, "true"); + Configuration configuration = new ConfigurationImpl(); + String systemWebPropertyPrefix = ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix(); + configuration.parsePrefixedProperties(webServer, "system-" + systemWebPropertyPrefix, properties, systemWebPropertyPrefix); + + BindingDTO testBinding = webServer.getAllBindings().stream().filter(binding -> bindingName.equals(binding.getName())).findFirst().get(); + Assert.assertEquals(BINDING_TEST_URL, testBinding.getUri()); + Assert.assertEquals(true, testBinding.getClientAuth()); + Assert.assertEquals("test-passwordCodec", testBinding.getPasswordCodec()); + Assert.assertEquals("test-keyStorePath", testBinding.getKeyStorePath()); + Assert.assertEquals("test-trustStorePath", testBinding.getTrustStorePath()); + Assert.assertEquals("test-includedTLSProtocols,0", String.join(",", testBinding.getIncludedTLSProtocols())); + Assert.assertEquals("test-excludedTLSProtocols,1", String.join(",", testBinding.getExcludedTLSProtocols())); + Assert.assertEquals("test-includedCipherSuites,2", String.join(",", testBinding.getIncludedCipherSuites())); + Assert.assertEquals("test-excludedCipherSuites,3", String.join(",", testBinding.getExcludedCipherSuites())); + Assert.assertEquals("test-keyStorePassword", testBinding.getKeyStorePassword()); + Assert.assertEquals("test-trustStorePassword", testBinding.getTrustStorePassword()); + + testStatus(configuration.getStatus(), "system-" + systemWebPropertyPrefix, "bindings." + bindingName + "."); + } + + @Test + public void testSetNewWebBindingAppProperties() throws Throwable { + WebServerDTO webServer = new WebServerDTO(); + + testSetWebBindingAppProperties(webServer, BINDING_TEST_NAME, APP_TEST_NAME); + } + + @Test + public void testSetExistingWebBindingAppProperties() throws Throwable { + WebServerDTO webServer = new WebServerDTO(); + BindingDTO exitingBinding = new BindingDTO(); + exitingBinding.setName(BINDING_TEST_NAME); + AppDTO existingApp = new AppDTO(); + existingApp.setName(APP_TEST_NAME); + exitingBinding.addApp(existingApp); + webServer.addBinding(exitingBinding); + + testSetWebBindingAppProperties(webServer, BINDING_TEST_NAME, APP_TEST_NAME); + } + + @Test + public void testSetExistingWebBindingAppWithoutNameProperties() throws Throwable { + WebServerDTO webServer = new WebServerDTO(); + BindingDTO exitingBinding = new BindingDTO(); + exitingBinding.setName(BINDING_TEST_NAME); + AppDTO existingApp = new AppDTO(); + existingApp.setUrl(APP_TEST_URL); + exitingBinding.addApp(existingApp); + webServer.addBinding(exitingBinding); + + testSetWebBindingAppProperties(webServer, BINDING_TEST_NAME, APP_TEST_URL); + } + + private void testSetWebBindingAppProperties(WebServerDTO webServer, String bindingName, String appName) throws Throwable { + Properties properties = new Properties(); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".apps." + appName + ".url", APP_TEST_URL); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".apps." + appName + ".war", "test-war"); + properties.put(ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix() + "bindings." + bindingName + ".apps." + appName + "." + INVALID_ATTRIBUTE_NAME, "true"); + Configuration configuration = new ConfigurationImpl(); + String systemWebPropertyPrefix = ActiveMQDefaultConfiguration.getDefaultSystemWebPropertyPrefix(); + configuration.parsePrefixedProperties(webServer, "system-" + systemWebPropertyPrefix, properties, systemWebPropertyPrefix); + + BindingDTO testBinding = webServer.getAllBindings().stream().filter(binding -> bindingName.equals(binding.getName())).findFirst().get(); + AppDTO testApp = testBinding.getApps().stream().filter(app -> appName.equals(app.getName())).findFirst().get(); + Assert.assertEquals("test-url", testApp.getUrl()); + Assert.assertEquals("test-war", testApp.getWar()); + + testStatus(configuration.getStatus(), "system-" + systemWebPropertyPrefix, "bindings." + bindingName + ".apps." + appName + "."); + } + + private void testStatus(String status, String name, String prefix) { + Assert.assertNotNull(status); + JsonObject statusJsonObject = JsonUtil.readJsonObject(status); + Assert.assertNotNull(statusJsonObject); + JsonObject propertiesJsonObject = statusJsonObject.getJsonObject("properties"); + Assert.assertNotNull(propertiesJsonObject); + JsonObject systemWebPropertiesJsonObject = propertiesJsonObject.getJsonObject(name); + Assert.assertNotNull(systemWebPropertiesJsonObject); + JsonArray errorsJsonObject = systemWebPropertiesJsonObject.getJsonArray("errors"); + Assert.assertNotNull(errorsJsonObject); + Assert.assertEquals(prefix + INVALID_ATTRIBUTE_NAME + "=true", errorsJsonObject.getJsonObject(0).getString("value")); + } +}