changeset 2031:5a183ba7be84

Add support for IPv6 in agent bind addresses. Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-November/021611.html PR3229
author Severin Gehwolf <sgehwolf@redhat.com>
date Tue, 15 Nov 2016 15:36:09 +0100
parents a26429779377
children 5f1cb273e609
files agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/AgentApplication.java agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/AgentApplicationTest.java agent/core/src/main/java/com/redhat/thermostat/agent/Agent.java agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentStartupConfiguration.java agent/core/src/test/java/com/redhat/thermostat/agent/AgentTest.java agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentStartupConfigurationTest.java
diffstat 7 files changed, 135 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/AgentApplication.java	Wed Oct 26 09:11:46 2016 -0400
+++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/AgentApplication.java	Tue Nov 15 15:36:09 2016 +0100
@@ -65,6 +65,7 @@
 import com.redhat.thermostat.common.cli.CommandContext;
 import com.redhat.thermostat.common.cli.CommandException;
 import com.redhat.thermostat.common.tools.ApplicationState;
+import com.redhat.thermostat.common.utils.HostPortPair;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.shared.config.InvalidConfigurationException;
 import com.redhat.thermostat.storage.core.Connection.ConnectionListener;
@@ -142,10 +143,10 @@
             @Override
             public Object addingService(ServiceReference reference) {
                 final ConfigurationServer configServer = (ConfigurationServer) super.addingService(reference);
-                String [] host = configuration.getConfigListenAddress().split(":");
+                final HostPortPair hostPort = configuration.getConfigListenAddress();
 
                 try {
-                    configServer.startListening(host[0], Integer.valueOf(host[1]));
+                    configServer.startListening(hostPort.getHost(), hostPort.getPort());
 
                     ConnectionListener connectionListener = new ConnectionListener() {
                         @Override
--- a/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/AgentApplicationTest.java	Wed Oct 26 09:11:46 2016 -0400
+++ b/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/AgentApplicationTest.java	Tue Nov 15 15:36:09 2016 +0100
@@ -74,6 +74,7 @@
 import com.redhat.thermostat.common.cli.Arguments;
 import com.redhat.thermostat.common.cli.CommandContext;
 import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.utils.HostPortPair;
 import com.redhat.thermostat.shared.config.InvalidConfigurationException;
 import com.redhat.thermostat.storage.core.Connection.ConnectionListener;
 import com.redhat.thermostat.storage.core.Connection.ConnectionStatus;
@@ -109,7 +110,8 @@
         
         AgentStartupConfiguration config = mock(AgentStartupConfiguration.class);
         when(config.getDBConnectionString()).thenReturn("test string; please ignore");
-        when(config.getConfigListenAddress()).thenReturn(COMMAND_CHANNLE_BIND_HOST + ":" + COMMAND_CHANNEL_BIND_PORT);
+        HostPortPair hostPort = new HostPortPair(COMMAND_CHANNLE_BIND_HOST, COMMAND_CHANNEL_BIND_PORT);
+        when(config.getConfigListenAddress()).thenReturn(hostPort);
 
         configCreator = mock(ConfigurationCreator.class);
         when(configCreator.create()).thenReturn(config);
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/Agent.java	Wed Oct 26 09:11:46 2016 -0400
+++ b/agent/core/src/main/java/com/redhat/thermostat/agent/Agent.java	Tue Nov 15 15:36:09 2016 +0100
@@ -48,6 +48,7 @@
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.LaunchException;
 import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+import com.redhat.thermostat.common.utils.HostPortPair;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.storage.core.Storage;
 import com.redhat.thermostat.storage.core.WriterID;
@@ -157,7 +158,12 @@
         AgentInformation agentInfo = new AgentInformation(writerId);
         agentInfo.setStartTime(config.getStartTime());
         agentInfo.setAlive(true);
-        agentInfo.setConfigListenAddress(config.getConfigListenAddress());
+        HostPortPair hostPort = config.getConfigListenAddress();
+        String host = hostPort.getHost();
+        if (host.indexOf(":") != -1) {
+            host = "[" + host + "]";
+        }
+        agentInfo.setConfigListenAddress(String.format("%s:%d", host, hostPort.getPort()));
         return agentInfo;
     }
 
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentStartupConfiguration.java	Wed Oct 26 09:11:46 2016 -0400
+++ b/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentStartupConfiguration.java	Tue Nov 15 15:36:09 2016 +0100
@@ -36,16 +36,18 @@
 
 package com.redhat.thermostat.agent.config;
 
+import java.util.List;
+
+import com.redhat.thermostat.common.utils.HostPortPair;
+import com.redhat.thermostat.common.utils.HostPortsParser;
 import com.redhat.thermostat.storage.config.StartupConfiguration;
 
 public class AgentStartupConfiguration implements StartupConfiguration {
 
     private boolean purge;
-    
     private String url;
-
     private long startTime;
-    private String address;
+    private HostPortPair hostPort;
     
     AgentStartupConfiguration() {
     }
@@ -77,11 +79,17 @@
     }
 
     public void setConfigListenAddress(String address) {
-        this.address = address;
+        HostPortsParser parser = new HostPortsParser(address);
+        parser.parse();
+        List<HostPortPair> list = parser.getHostsPorts();
+        if (list.size() != 1) {
+            throw new AssertionError("Multiple listen addresses not supported! Got: " + address);
+        }
+        this.hostPort = parser.getHostsPorts().get(0);
     }
 
-    public String getConfigListenAddress() {
-        return address;
+    public HostPortPair getConfigListenAddress() {
+        return hostPort;
     }
 }
 
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/AgentTest.java	Wed Oct 26 09:11:46 2016 -0400
+++ b/agent/core/src/test/java/com/redhat/thermostat/agent/AgentTest.java	Tue Nov 15 15:36:09 2016 +0100
@@ -42,6 +42,7 @@
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+import com.redhat.thermostat.common.utils.HostPortPair;
 import com.redhat.thermostat.storage.core.Storage;
 import com.redhat.thermostat.storage.core.WriterID;
 import com.redhat.thermostat.storage.dao.AgentInfoDAO;
@@ -81,6 +82,7 @@
         config = mock(AgentStartupConfiguration.class);
         when(config.getStartTime()).thenReturn(123L);
         when(config.purge()).thenReturn(true);
+        when(config.getConfigListenAddress()).thenReturn(new HostPortPair("foo", 23));
         
         storage = mock(Storage.class);
         agentInfoDao = mock(AgentInfoDAO.class);
@@ -197,6 +199,7 @@
         AgentStartupConfiguration config = mock(AgentStartupConfiguration.class);
         when(config.getStartTime()).thenReturn(123L);
         when(config.purge()).thenReturn(false);
+        when(config.getConfigListenAddress()).thenReturn(new HostPortPair("foo", 23));
         
         WriterID id = mock(WriterID.class);
         Agent agent = new Agent(backendRegistry, config, storage, agentInfoDao, backendInfoDao, id);
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java	Wed Oct 26 09:11:46 2016 -0400
+++ b/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java	Tue Nov 15 15:36:09 2016 +0100
@@ -44,6 +44,7 @@
 import org.junit.Assert;
 import org.junit.Test;
 
+import com.redhat.thermostat.common.utils.HostPortPair;
 import com.redhat.thermostat.shared.config.InvalidConfigurationException;
 import com.redhat.thermostat.testutils.TestUtils;
 
@@ -84,7 +85,9 @@
         setConfigs(sysProps, new Properties());
         AgentStartupConfiguration config = AgentConfigsUtils.createAgentConfigs();
 
-        Assert.assertEquals("42.42.42.42:42", config.getConfigListenAddress());
+        HostPortPair hostPorts = config.getConfigListenAddress();
+        Assert.assertEquals("42.42.42.42", hostPorts.getHost());
+        Assert.assertEquals(42, hostPorts.getPort());
     }
     
     @Test
@@ -114,15 +117,29 @@
         setConfigs(sysProps, userProps);
         AgentStartupConfiguration config = AgentConfigsUtils.createAgentConfigs();        
 
-        Assert.assertEquals("24.24.24.24:24", config.getConfigListenAddress());
+        HostPortPair hostPorts = config.getConfigListenAddress();
+        Assert.assertEquals("24.24.24.24", hostPorts.getHost());
+        Assert.assertEquals(24, hostPorts.getPort());
+    }
+    
+    @Test
+    public void canParseIpv6ConfigAddress() {
+        String ipV6AddressPair = "[::1]:12000";
+        Properties sysProps = createSystemProperties(ipV6AddressPair);
+        setConfigs(sysProps, new Properties());
+        AgentStartupConfiguration config = AgentConfigsUtils.createAgentConfigs();        
+
+        HostPortPair hostPorts = config.getConfigListenAddress();
+        Assert.assertEquals("::1", hostPorts.getHost());
+        Assert.assertEquals(12000, hostPorts.getPort());
+    }
+    
+    private Properties createSystemProperties(String configListenAddress) {
+        return doCreateSystemProperties(configListenAddress);
     }
     
     private Properties createSystemProperties() {
-        Properties agentProperties = new Properties();
-        agentProperties.setProperty("DB_URL", "http://1.2.3.4:9001/hello");
-        agentProperties.setProperty("SAVE_ON_EXIT", "true");
-        agentProperties.setProperty("CONFIG_LISTEN_ADDRESS", "42.42.42.42:42");
-        return agentProperties;
+        return createSystemProperties("42.42.42.42:42");
     }
     
     private Properties createUserProperties() {
@@ -133,6 +150,14 @@
         return agentProperties;
     }
     
+    private Properties doCreateSystemProperties(String configListenAddress) {
+        Properties agentProperties = new Properties();
+        agentProperties.setProperty("DB_URL", "http://1.2.3.4:9001/hello");
+        agentProperties.setProperty("SAVE_ON_EXIT", "true");
+        agentProperties.setProperty("CONFIG_LISTEN_ADDRESS", configListenAddress);
+        return agentProperties;
+    }
+    
     private void setConfigs(Properties sysProps, Properties userProps) {
         try {
             String tmpDirPath = TestUtils.setupAgentConfigs(sysProps, userProps);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentStartupConfigurationTest.java	Tue Nov 15 15:36:09 2016 +0100
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.agent.config;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.common.utils.HostPortPair;
+
+public class AgentStartupConfigurationTest {
+
+    private static final String IP_V4_LISTEN_ADDRESS = "127.0.0.1:12000";
+    private static final String IP_V6_LISTEN_ADDRESS = "[::1]:12000";
+    
+    private AgentStartupConfiguration config;
+    
+    @Before
+    public void setup() {
+        config = new AgentStartupConfiguration();
+    }
+    
+    @Test
+    public void testIPv4ConfigListenAddress() {
+        config.setConfigListenAddress(IP_V4_LISTEN_ADDRESS);
+        HostPortPair hostPort = config.getConfigListenAddress();
+        assertEquals("127.0.0.1", hostPort.getHost());
+        assertEquals(12000, hostPort.getPort());
+    }
+    
+    @Test
+    public void testIPv6ConfigListenAddress() {
+        config.setConfigListenAddress(IP_V6_LISTEN_ADDRESS);
+        HostPortPair hostPort = config.getConfigListenAddress();
+        assertEquals("::1", hostPort.getHost());
+        assertEquals(12000, hostPort.getPort());
+    }
+}