| /* |
| * 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.geode.distributed.internal; |
| |
| import static org.apache.geode.distributed.ConfigurationProperties.ARCHIVE_DISK_SPACE_LIMIT; |
| import static org.apache.geode.distributed.ConfigurationProperties.ARCHIVE_FILE_SIZE_LIMIT; |
| import static org.apache.geode.distributed.ConfigurationProperties.CACHE_XML_FILE; |
| import static org.apache.geode.distributed.ConfigurationProperties.CLUSTER_SSL_ENABLED; |
| import static org.apache.geode.distributed.ConfigurationProperties.GATEWAY_SSL_ENABLED; |
| import static org.apache.geode.distributed.ConfigurationProperties.GROUPS; |
| import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_SSL_ENABLED; |
| import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_SSL_ENABLED; |
| import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS; |
| import static org.apache.geode.distributed.ConfigurationProperties.LOG_DISK_SPACE_LIMIT; |
| import static org.apache.geode.distributed.ConfigurationProperties.LOG_FILE_SIZE_LIMIT; |
| import static org.apache.geode.distributed.ConfigurationProperties.LOG_LEVEL; |
| import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; |
| import static org.apache.geode.distributed.ConfigurationProperties.MEMBERSHIP_PORT_RANGE; |
| import static org.apache.geode.distributed.ConfigurationProperties.MEMBER_TIMEOUT; |
| import static org.apache.geode.distributed.ConfigurationProperties.NAME; |
| import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_AUTH_TOKEN_ENABLED_COMPONENTS; |
| import static org.apache.geode.distributed.ConfigurationProperties.SERVER_SSL_ENABLED; |
| import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS; |
| import static org.apache.geode.distributed.ConfigurationProperties.START_LOCATOR; |
| import static org.apache.geode.distributed.ConfigurationProperties.STATISTIC_ARCHIVE_FILE; |
| import static org.apache.geode.distributed.ConfigurationProperties.STATISTIC_SAMPLE_RATE; |
| import static org.apache.geode.distributed.ConfigurationProperties.STATISTIC_SAMPLING_ENABLED; |
| import static org.apache.geode.internal.AvailablePortHelper.getRandomAvailableTCPPort; |
| import static org.assertj.core.api.Assertions.assertThat; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.fail; |
| import static org.mockito.ArgumentMatchers.any; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.when; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.net.Inet4Address; |
| import java.net.Inet6Address; |
| import java.net.InetAddress; |
| import java.net.NetworkInterface; |
| import java.net.SocketException; |
| import java.net.UnknownHostException; |
| import java.util.Collection; |
| import java.util.Enumeration; |
| import java.util.Properties; |
| import java.util.logging.Level; |
| |
| import io.micrometer.core.instrument.MeterRegistry; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.experimental.categories.Category; |
| import org.junit.rules.ExpectedException; |
| |
| import org.apache.geode.distributed.DistributedSystem; |
| import org.apache.geode.distributed.DistributedSystemDisconnectedException; |
| import org.apache.geode.distributed.Locator; |
| import org.apache.geode.internal.Config; |
| import org.apache.geode.internal.ConfigSource; |
| import org.apache.geode.internal.logging.InternalLogWriter; |
| import org.apache.geode.metrics.internal.MetricsService; |
| import org.apache.geode.test.junit.categories.MembershipTest; |
| import org.apache.geode.util.internal.GeodeGlossary; |
| |
| /** |
| * Tests the functionality of the {@link InternalDistributedSystem} class. Mostly checks |
| * configuration error checking. |
| * |
| * @since GemFire 2.1 |
| */ |
| @Category({MembershipTest.class}) |
| public class InternalDistributedSystemJUnitTest { |
| /** |
| * A connection to a distributed system created by this test |
| */ |
| private InternalDistributedSystem system; |
| |
| private InternalDistributedSystem createSystem(Properties props, |
| MetricsService.Builder metricsSessionBuilder) { |
| this.system = new InternalDistributedSystem.Builder(props, metricsSessionBuilder) |
| .build(); |
| return this.system; |
| } |
| |
| /** |
| * Creates a <code>DistributedSystem</code> with the given configuration properties. |
| */ |
| private InternalDistributedSystem createSystem(Properties props) { |
| MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class); |
| when(metricsSessionBuilder.build(any())).thenReturn(mock(MetricsService.class)); |
| return createSystem(props, metricsSessionBuilder); |
| } |
| |
| /** |
| * Disconnects any distributed system that was created by this test |
| * |
| * @see DistributedSystem#disconnect |
| */ |
| @After |
| public void tearDown() throws Exception { |
| if (this.system != null) { |
| this.system.disconnect(); |
| } |
| } |
| |
| //////// Test methods |
| |
| @Test |
| public void testUnknownArgument() { |
| Properties props = new Properties(); |
| props.put("UNKNOWN", "UNKNOWN"); |
| |
| try { |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| } |
| |
| /** |
| * Tests that the default values of properties are what we expect |
| */ |
| @Test |
| public void testDefaultProperties() { |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| DistributionConfig config = createSystem(props).getConfig(); |
| |
| assertEquals(DistributionConfig.DEFAULT_NAME, config.getName()); |
| |
| assertEquals(0, config.getMcastPort()); |
| |
| assertEquals(DistributionConfig.DEFAULT_MEMBERSHIP_PORT_RANGE[0], |
| config.getMembershipPortRange()[0]); |
| assertEquals(DistributionConfig.DEFAULT_MEMBERSHIP_PORT_RANGE[1], |
| config.getMembershipPortRange()[1]); |
| |
| if (System.getProperty(GeodeGlossary.GEMFIRE_PREFIX + "mcast-address") == null) { |
| assertEquals(DistributionConfig.DEFAULT_MCAST_ADDRESS, config.getMcastAddress()); |
| } |
| if (System.getProperty(GeodeGlossary.GEMFIRE_PREFIX + "bind-address") == null) { |
| assertEquals(DistributionConfig.DEFAULT_BIND_ADDRESS, config.getBindAddress()); |
| } |
| |
| assertEquals(DistributionConfig.DEFAULT_LOG_FILE, config.getLogFile()); |
| |
| // default log level gets overrided by the gemfire.properties created for unit tests. |
| // assertIndexDetailsEquals(DistributionConfig.DEFAULT_LOG_LEVEL, config.getLogLevel()); |
| |
| assertEquals(DistributionConfig.DEFAULT_STATISTIC_SAMPLING_ENABLED, |
| config.getStatisticSamplingEnabled()); |
| |
| assertEquals(DistributionConfig.DEFAULT_STATISTIC_SAMPLE_RATE, config.getStatisticSampleRate()); |
| |
| assertEquals(DistributionConfig.DEFAULT_STATISTIC_ARCHIVE_FILE, |
| config.getStatisticArchiveFile()); |
| |
| // ack-wait-threadshold is overridden on VM's command line using a |
| // system property. This is not a valid test. Hrm. |
| // assertIndexDetailsEquals(DistributionConfig.DEFAULT_ACK_WAIT_THRESHOLD, |
| // config.getAckWaitThreshold()); |
| |
| assertEquals(DistributionConfig.DEFAULT_ACK_SEVERE_ALERT_THRESHOLD, |
| config.getAckSevereAlertThreshold()); |
| |
| assertEquals(DistributionConfig.DEFAULT_CACHE_XML_FILE, config.getCacheXmlFile()); |
| |
| assertEquals(DistributionConfig.DEFAULT_ARCHIVE_DISK_SPACE_LIMIT, |
| config.getArchiveDiskSpaceLimit()); |
| assertEquals(DistributionConfig.DEFAULT_ARCHIVE_FILE_SIZE_LIMIT, |
| config.getArchiveFileSizeLimit()); |
| assertEquals(DistributionConfig.DEFAULT_LOG_DISK_SPACE_LIMIT, config.getLogDiskSpaceLimit()); |
| assertEquals(DistributionConfig.DEFAULT_LOG_FILE_SIZE_LIMIT, config.getLogFileSizeLimit()); |
| |
| assertEquals(DistributionConfig.DEFAULT_ENABLE_NETWORK_PARTITION_DETECTION, |
| config.getEnableNetworkPartitionDetection()); |
| } |
| |
| @Test |
| public void testGetName() { |
| String name = "testGetName"; |
| |
| Properties props = new Properties(); |
| props.put(NAME, name); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| |
| DistributionConfig config = createSystem(props).getOriginalConfig(); |
| assertEquals(name, config.getName()); |
| } |
| |
| @Test |
| public void testMemberTimeout() { |
| Properties props = new Properties(); |
| int memberTimeout = 100; |
| props.put(MEMBER_TIMEOUT, String.valueOf(memberTimeout)); |
| props.put(MCAST_PORT, "0"); |
| |
| DistributionConfig config = createSystem(props).getOriginalConfig(); |
| assertEquals(memberTimeout, config.getMemberTimeout()); |
| } |
| |
| @Test |
| public void testMalformedLocators() { |
| Properties props = new Properties(); |
| |
| try { |
| // Totally bogus locator |
| props.put(LOCATORS, "14lasfk^5234"); |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| |
| try { |
| // missing port |
| props.put(LOCATORS, "localhost["); |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| |
| try { |
| // Missing ] |
| props.put(LOCATORS, "localhost[234ty"); |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| |
| try { |
| // Malformed port |
| props.put(LOCATORS, "localhost[234ty]"); |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| |
| try { |
| // Malformed port in second locator |
| props.put(LOCATORS, "localhost[12345],localhost[sdf3"); |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| } |
| |
| /** |
| * Creates a new <code>DistributionConfigImpl</code> with the given locators string. |
| * |
| * @throws IllegalArgumentException If <code>locators</code> is malformed |
| * @since GemFire 4.0 |
| */ |
| private void checkLocator(String locator) { |
| Properties props = new Properties(); |
| props.put(LOCATORS, locator); |
| new DistributionConfigImpl(props); |
| } |
| |
| /** |
| * Tests that both the traditional syntax ("host[port]") and post bug-32306 syntax ("host:port") |
| * can be used with locators. |
| * |
| * @since GemFire 4.0 |
| */ |
| @Test |
| public void testLocatorSyntax() throws Exception { |
| String localhost = java.net.InetAddress.getLocalHost().getCanonicalHostName(); |
| checkLocator(localhost + "[12345]"); |
| checkLocator(localhost + ":12345"); |
| |
| String bindAddress = getHostAddress(java.net.InetAddress.getLocalHost()); |
| if (bindAddress.indexOf(':') < 0) { |
| checkLocator(localhost + ":" + bindAddress + "[12345]"); |
| } |
| checkLocator(localhost + "@" + bindAddress + "[12345]"); |
| if (bindAddress.indexOf(':') < 0) { |
| checkLocator(localhost + ":" + bindAddress + ":12345"); |
| } |
| if (localhost.indexOf(':') < 0) { |
| checkLocator(localhost + ":" + "12345"); |
| } |
| } |
| |
| /** |
| * Tests that getting the log level is what we expect. |
| */ |
| @Test |
| public void testGetLogLevel() { |
| Level logLevel = Level.FINER; |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(LOG_LEVEL, logLevel.toString()); |
| |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(logLevel.intValue(), config.getLogLevel()); |
| } |
| |
| @Test |
| public void testInvalidLogLevel() { |
| try { |
| Properties props = new Properties(); |
| props.put(LOG_LEVEL, "blah blah blah"); |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| } |
| |
| @Test |
| public void testGetStatisticSamplingEnabled() { |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(STATISTIC_SAMPLING_ENABLED, "true"); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(true, config.getStatisticSamplingEnabled()); |
| } |
| |
| @Test |
| public void testGetStatisticSampleRate() { |
| String rate = String.valueOf(DistributionConfig.MIN_STATISTIC_SAMPLE_RATE); |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(STATISTIC_SAMPLE_RATE, rate); |
| DistributionConfig config = createSystem(props).getConfig(); |
| // The fix for 48228 causes the rate to be 1000 even if we try to set it less |
| assertEquals(1000, config.getStatisticSampleRate()); |
| } |
| |
| @Test |
| public void testMembershipPortRange() { |
| Properties props = new Properties(); |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.setProperty(MEMBERSHIP_PORT_RANGE, "45100-45200"); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(45100, config.getMembershipPortRange()[0]); |
| assertEquals(45200, config.getMembershipPortRange()[1]); |
| } |
| |
| @Test |
| public void testBadMembershipPortRange() { |
| Properties props = new Properties(); |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.setProperty(MEMBERSHIP_PORT_RANGE, "5200-5100"); |
| Object exception = null; |
| try { |
| createSystem(props).getConfig(); |
| } catch (IllegalArgumentException expected) { |
| exception = expected; |
| } |
| assertNotNull("Expected an IllegalArgumentException", exception); |
| } |
| |
| @Test |
| public void testGetStatisticArchiveFile() { |
| String fileName = "testGetStatisticArchiveFile"; |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(STATISTIC_ARCHIVE_FILE, fileName); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(fileName, config.getStatisticArchiveFile().getName()); |
| } |
| |
| @Test |
| public void testGetCacheXmlFile() { |
| String fileName = "blah"; |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(CACHE_XML_FILE, fileName); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(fileName, config.getCacheXmlFile().getPath()); |
| } |
| |
| @Test |
| public void testGetArchiveDiskSpaceLimit() { |
| String value = String.valueOf(DistributionConfig.MIN_ARCHIVE_DISK_SPACE_LIMIT); |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(ARCHIVE_DISK_SPACE_LIMIT, value); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(Integer.parseInt(value), config.getArchiveDiskSpaceLimit()); |
| } |
| |
| @Test |
| public void testInvalidArchiveDiskSpaceLimit() { |
| Properties props = new Properties(); |
| props.put(ARCHIVE_DISK_SPACE_LIMIT, "blah"); |
| try { |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| } |
| |
| @Test |
| public void testGetArchiveFileSizeLimit() { |
| String value = String.valueOf(DistributionConfig.MIN_ARCHIVE_FILE_SIZE_LIMIT); |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(ARCHIVE_FILE_SIZE_LIMIT, value); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(Integer.parseInt(value), config.getArchiveFileSizeLimit()); |
| } |
| |
| @Test |
| public void testInvalidArchiveFileSizeLimit() { |
| Properties props = new Properties(); |
| props.put(ARCHIVE_FILE_SIZE_LIMIT, "blah"); |
| try { |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| } |
| |
| @Test |
| public void testGetLogDiskSpaceLimit() { |
| String value = String.valueOf(DistributionConfig.MIN_LOG_DISK_SPACE_LIMIT); |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(LOG_DISK_SPACE_LIMIT, value); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(Integer.parseInt(value), config.getLogDiskSpaceLimit()); |
| } |
| |
| @Test |
| public void testInvalidLogDiskSpaceLimit() { |
| Properties props = new Properties(); |
| props.put(LOG_DISK_SPACE_LIMIT, "blah"); |
| try { |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| } |
| |
| @Test |
| public void testGetLogFileSizeLimit() { |
| String value = String.valueOf(DistributionConfig.MIN_LOG_FILE_SIZE_LIMIT); |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(LOG_FILE_SIZE_LIMIT, value); |
| DistributionConfig config = createSystem(props).getConfig(); |
| assertEquals(Integer.parseInt(value), config.getLogFileSizeLimit()); |
| } |
| |
| @Test |
| public void testInvalidLogFileSizeLimit() { |
| Properties props = new Properties(); |
| props.put(LOG_FILE_SIZE_LIMIT, "blah"); |
| try { |
| createSystem(props); |
| fail("Should have thrown an IllegalArgumentException"); |
| |
| } catch (IllegalArgumentException ex) { |
| // pass... |
| } |
| } |
| |
| @Test |
| public void testAccessingClosedDistributedSystem() { |
| Properties props = new Properties(); |
| |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| InternalDistributedSystem system = createSystem(props); |
| system.disconnect(); |
| |
| try { |
| system.getDistributionManager(); |
| fail("Should have thrown an IllegalStateException"); |
| |
| } catch (DistributedSystemDisconnectedException ex) { |
| // pass... |
| } |
| try { |
| system.getLogWriter(); |
| |
| } catch (IllegalStateException ex) { |
| fail("Shouldn't have thrown an IllegalStateException"); |
| } |
| } |
| |
| @Test |
| public void testPropertySources() throws Exception { |
| // TODO: fix this test on Windows: the File renameTo and delete in finally fails on Windows |
| String os = System.getProperty("os.name"); |
| if (os != null) { |
| if (os.indexOf("Windows") != -1) { |
| return; |
| } |
| } |
| File propFile = new File(GeodeGlossary.GEMFIRE_PREFIX + "properties"); |
| boolean propFileExisted = propFile.exists(); |
| File spropFile = new File("gfsecurity.properties"); |
| boolean spropFileExisted = spropFile.exists(); |
| try { |
| System.setProperty(GeodeGlossary.GEMFIRE_PREFIX + LOG_LEVEL, "finest"); |
| Properties apiProps = new Properties(); |
| apiProps.setProperty(GROUPS, "foo, bar"); |
| { |
| if (propFileExisted) { |
| propFile.renameTo(new File(GeodeGlossary.GEMFIRE_PREFIX + "properties.sav")); |
| } |
| Properties fileProps = new Properties(); |
| fileProps.setProperty("name", "myName"); |
| FileWriter fw = new FileWriter(GeodeGlossary.GEMFIRE_PREFIX + "properties"); |
| fileProps.store(fw, null); |
| fw.close(); |
| } |
| { |
| if (spropFileExisted) { |
| spropFile.renameTo(new File("gfsecurity.properties.sav")); |
| } |
| Properties fileProps = new Properties(); |
| fileProps.setProperty(STATISTIC_SAMPLE_RATE, "999"); |
| FileWriter fw = new FileWriter("gfsecurity.properties"); |
| fileProps.store(fw, null); |
| fw.close(); |
| } |
| DistributionConfigImpl dci = new DistributionConfigImpl(apiProps); |
| assertEquals(null, dci.getAttributeSource(MCAST_PORT)); |
| assertEquals(ConfigSource.api(), dci.getAttributeSource(GROUPS)); |
| assertEquals(ConfigSource.sysprop(), dci.getAttributeSource(LOG_LEVEL)); |
| assertEquals(ConfigSource.Type.FILE, dci.getAttributeSource("name").getType()); |
| assertEquals(ConfigSource.Type.SECURE_FILE, |
| dci.getAttributeSource(STATISTIC_SAMPLE_RATE).getType()); |
| } finally { |
| System.clearProperty(GeodeGlossary.GEMFIRE_PREFIX + "log-level"); |
| propFile.delete(); |
| if (propFileExisted) { |
| new File(GeodeGlossary.GEMFIRE_PREFIX + "properties.sav").renameTo(propFile); |
| } |
| spropFile.delete(); |
| if (spropFileExisted) { |
| new File("gfsecurity.properties.sav").renameTo(spropFile); |
| } |
| } |
| } |
| |
| /** |
| * Create a <Code>DistributedSystem</code> with a non-default name. |
| */ |
| @Test |
| public void testNonDefaultConnectionName() { |
| String name = "BLAH"; |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.setProperty(NAME, name); |
| createSystem(props); |
| } |
| |
| @Test |
| public void testNonDefaultLogLevel() { |
| Level level = Level.FINE; |
| |
| Properties props = new Properties(); |
| // a loner is all this test needs |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| props.put(LOG_LEVEL, level.toString()); |
| InternalDistributedSystem system = createSystem(props); |
| assertEquals(level.intValue(), system.getConfig().getLogLevel()); |
| assertEquals(level.intValue(), ((InternalLogWriter) system.getLogWriter()).getLogWriterLevel()); |
| } |
| |
| @Test |
| public void testStartLocator() { |
| Properties props = new Properties(); |
| int unusedPort = getRandomAvailableTCPPort(); |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(START_LOCATOR, "localhost[" + unusedPort + "],server=false,peer=true"); |
| deleteStateFile(unusedPort); |
| createSystem(props); |
| Collection locators = Locator.getLocators(); |
| Assert.assertEquals(1, locators.size()); |
| Locator locator = (Locator) locators.iterator().next(); |
| // Assert.assertIndexDetailsEquals("127.0.0.1", locator.getBindAddress().getHostAddress()); |
| // removed this check for ipv6 testing |
| Assert.assertEquals(unusedPort, locator.getPort().intValue()); |
| deleteStateFile(unusedPort); |
| } |
| |
| private void deleteStateFile(int port) { |
| File stateFile = new File("locator" + port + "state.dat"); |
| if (stateFile.exists()) { |
| stateFile.delete(); |
| } |
| } |
| |
| @Test |
| public void testValidateProps() { |
| Properties props = new Properties(); |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| Config config1 = new DistributionConfigImpl(props, false); |
| MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class); |
| when(metricsSessionBuilder.build(any())).thenReturn(mock(MetricsService.class)); |
| InternalDistributedSystem sys = |
| new InternalDistributedSystem.Builder(config1.toProperties(), metricsSessionBuilder) |
| .build(); |
| try { |
| |
| props.put(MCAST_PORT, "1"); |
| Config config2 = new DistributionConfigImpl(props, false); |
| |
| try { |
| sys.validateSameProperties(config2.toProperties(), true); |
| fail("should have detected different mcast-ports"); |
| } catch (IllegalStateException iex) { |
| // This passes the test |
| } |
| |
| } finally { |
| sys.disconnect(); |
| } |
| } |
| |
| @Test |
| public void testDeprecatedSSLProps() { |
| // ssl-* props are copied to cluster-ssl-*. |
| Properties props = getCommonProperties(); |
| props.setProperty(CLUSTER_SSL_ENABLED, "true"); |
| Config config1 = new DistributionConfigImpl(props, false); |
| Properties props1 = config1.toProperties(); |
| assertEquals("true", props1.getProperty(CLUSTER_SSL_ENABLED)); |
| Config config2 = new DistributionConfigImpl(props1, false); |
| assertEquals(true, config1.sameAs(config2)); |
| Properties props3 = new Properties(props1); |
| props3.setProperty(CLUSTER_SSL_ENABLED, "false"); |
| Config config3 = new DistributionConfigImpl(props3, false); |
| assertEquals(false, config1.sameAs(config3)); |
| } |
| |
| @Test |
| public void testEmptySecurityAuthTokenProp() throws Exception { |
| Properties props = getCommonProperties(); |
| props.setProperty(SECURITY_AUTH_TOKEN_ENABLED_COMPONENTS, ""); |
| DistributionConfig config1 = new DistributionConfigImpl(props, false); |
| assertThat(config1.getSecurityAuthTokenEnabledComponents()).hasSize(0); |
| Properties securityProps = config1.getSecurityProps(); |
| assertThat(securityProps.getProperty(SECURITY_AUTH_TOKEN_ENABLED_COMPONENTS)).isEqualTo(""); |
| assertThat(config1.getSecurityAuthTokenEnabledComponents()).hasSize(0); |
| } |
| |
| @Test |
| public void testSecurityAuthTokenProp() throws Exception { |
| Properties props = getCommonProperties(); |
| props.setProperty(SECURITY_AUTH_TOKEN_ENABLED_COMPONENTS, "management"); |
| DistributionConfig config1 = new DistributionConfigImpl(props, false); |
| assertThat(config1.getSecurityAuthTokenEnabledComponents()).containsExactly("MANAGEMENT"); |
| Properties securityProps = config1.getSecurityProps(); |
| assertThat(securityProps.getProperty(SECURITY_AUTH_TOKEN_ENABLED_COMPONENTS)) |
| .isEqualTo("management"); |
| assertThat(config1.getSecurityAuthTokenEnabledComponents()).containsExactly("MANAGEMENT"); |
| } |
| |
| @Test |
| public void testSSLEnabledComponents() { |
| Properties props = getCommonProperties(); |
| props.setProperty(SSL_ENABLED_COMPONENTS, "cluster,server"); |
| Config config1 = new DistributionConfigImpl(props, false); |
| assertEquals("cluster,server", config1.getAttribute(SSL_ENABLED_COMPONENTS)); |
| } |
| |
| @Rule |
| public ExpectedException illegalArgumentException = ExpectedException.none(); |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testSSLEnabledComponentsWrongComponentName() { |
| Properties props = getCommonProperties(); |
| props.setProperty(SSL_ENABLED_COMPONENTS, "testing"); |
| new DistributionConfigImpl(props, false); |
| illegalArgumentException.expect(IllegalArgumentException.class); |
| illegalArgumentException |
| .expectMessage("There is no registered component for the name: testing"); |
| } |
| |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testSSLEnabledComponentsWithLegacyJMXSSLSettings() { |
| Properties props = getCommonProperties(); |
| props.setProperty(SSL_ENABLED_COMPONENTS, "all"); |
| props.setProperty(JMX_MANAGER_SSL_ENABLED, "true"); |
| new DistributionConfigImpl(props, false); |
| illegalArgumentException.expect(IllegalArgumentException.class); |
| illegalArgumentException.expectMessage( |
| "When using ssl-enabled-components one cannot use any other SSL properties other than " |
| + "cluster-ssl-* or the corresponding aliases"); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testSSLEnabledComponentsWithLegacyGatewaySSLSettings() { |
| Properties props = getCommonProperties(); |
| props.setProperty(SSL_ENABLED_COMPONENTS, "all"); |
| props.setProperty(GATEWAY_SSL_ENABLED, "true"); |
| new DistributionConfigImpl(props, false); |
| |
| illegalArgumentException.expect(IllegalArgumentException.class); |
| illegalArgumentException.expectMessage( |
| "When using ssl-enabled-components one cannot use any other SSL properties other than " |
| + "cluster-ssl-* or the corresponding aliases"); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testSSLEnabledComponentsWithLegacyServerSSLSettings() { |
| Properties props = getCommonProperties(); |
| props.setProperty(SSL_ENABLED_COMPONENTS, "all"); |
| props.setProperty(SERVER_SSL_ENABLED, "true"); |
| new DistributionConfigImpl(props, false); |
| |
| illegalArgumentException.expect(IllegalArgumentException.class); |
| illegalArgumentException.expectMessage( |
| "When using ssl-enabled-components one cannot use any other SSL properties other than " |
| + "cluster-ssl-* or the corresponding aliases"); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testSSLEnabledComponentsWithLegacyHTTPServiceSSLSettings() { |
| Properties props = getCommonProperties(); |
| props.setProperty(SSL_ENABLED_COMPONENTS, "all"); |
| props.setProperty(HTTP_SERVICE_SSL_ENABLED, "true"); |
| new DistributionConfigImpl(props, false); |
| |
| illegalArgumentException.expect(IllegalArgumentException.class); |
| illegalArgumentException.expectMessage( |
| "When using ssl-enabled-components one cannot use any other SSL properties other than " |
| + "cluster-ssl-* or the corresponding aliases"); |
| } |
| |
| @Test |
| public void usesSessionBuilderToCreateMetricsSession() { |
| MetricsService metricsSession = mock(MetricsService.class); |
| MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class); |
| when(metricsSessionBuilder.build(any())).thenReturn(metricsSession); |
| |
| createSystem(getCommonProperties(), metricsSessionBuilder); |
| |
| verify(metricsSessionBuilder).build(system); |
| } |
| |
| @Test |
| public void startsMetricsSession() { |
| MetricsService metricsSession = mock(MetricsService.class); |
| MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class); |
| when(metricsSessionBuilder.build(any())).thenReturn(metricsSession); |
| when(metricsSession.getMeterRegistry()).thenReturn(mock(MeterRegistry.class)); |
| |
| createSystem(getCommonProperties(), metricsSessionBuilder); |
| |
| verify(metricsSession).start(); |
| } |
| |
| @Test |
| public void getMeterRegistry_returnsMetricsSessionMeterRegistry() { |
| MeterRegistry sessionMeterRegistry = mock(MeterRegistry.class); |
| |
| MetricsService metricsSession = mock(MetricsService.class); |
| when(metricsSession.getMeterRegistry()).thenReturn(sessionMeterRegistry); |
| |
| MetricsService.Builder metricsSessionBuilder = mock(MetricsService.Builder.class); |
| when(metricsSessionBuilder.build(any())).thenReturn(metricsSession); |
| when(metricsSession.getMeterRegistry()).thenReturn(sessionMeterRegistry); |
| |
| createSystem(getCommonProperties(), metricsSessionBuilder); |
| |
| assertThat(system.getMeterRegistry()).isSameAs(sessionMeterRegistry); |
| } |
| |
| private Properties getCommonProperties() { |
| Properties props = new Properties(); |
| props.setProperty(MCAST_PORT, "0"); |
| props.setProperty(LOCATORS, ""); |
| return props; |
| } |
| |
| public static String getHostAddress(InetAddress addr) { |
| String address = addr.getHostAddress(); |
| if (addr instanceof Inet4Address || (!addr.isLinkLocalAddress() && !addr.isLoopbackAddress())) { |
| int idx = address.indexOf('%'); |
| if (idx >= 0) { |
| address = address.substring(0, idx); |
| } |
| } |
| return address; |
| } |
| |
| public static InetAddress getIPAddress() { |
| return Boolean.getBoolean("java.net.preferIPv6Addresses") ? getIPv6Address() : getIPv4Address(); |
| } |
| |
| protected static InetAddress getIPv4Address() { |
| InetAddress host = null; |
| try { |
| host = InetAddress.getLocalHost(); |
| if (host instanceof Inet4Address) { |
| return host; |
| } |
| } catch (UnknownHostException e) { |
| String s = "Local host not found"; |
| throw new RuntimeException(s, e); |
| } |
| try { |
| Enumeration i = NetworkInterface.getNetworkInterfaces(); |
| while (i.hasMoreElements()) { |
| NetworkInterface ni = (NetworkInterface) i.nextElement(); |
| Enumeration j = ni.getInetAddresses(); |
| while (j.hasMoreElements()) { |
| InetAddress addr = (InetAddress) j.nextElement(); |
| // gemfire won't form connections using link-local addresses |
| if (!addr.isLinkLocalAddress() && !addr.isLoopbackAddress() |
| && (addr instanceof Inet4Address)) { |
| return addr; |
| } |
| } |
| } |
| String s = "IPv4 address not found"; |
| throw new RuntimeException(s); |
| } catch (SocketException e) { |
| String s = "Problem reading IPv4 address"; |
| throw new RuntimeException(s, e); |
| } |
| } |
| |
| public static InetAddress getIPv6Address() { |
| try { |
| Enumeration i = NetworkInterface.getNetworkInterfaces(); |
| while (i.hasMoreElements()) { |
| NetworkInterface ni = (NetworkInterface) i.nextElement(); |
| Enumeration j = ni.getInetAddresses(); |
| while (j.hasMoreElements()) { |
| InetAddress addr = (InetAddress) j.nextElement(); |
| // gemfire won't form connections using link-local addresses |
| if (!addr.isLinkLocalAddress() && !addr.isLoopbackAddress() |
| && (addr instanceof Inet6Address) && !isIPv6LinkLocalAddress((Inet6Address) addr)) { |
| return addr; |
| } |
| } |
| } |
| String s = "IPv6 address not found"; |
| throw new RuntimeException(s); |
| } catch (SocketException e) { |
| String s = "Problem reading IPv6 address"; |
| throw new RuntimeException(s, e); |
| } |
| } |
| |
| /** |
| * Detect LinkLocal IPv6 address where the interface is missing, ie %[0-9]. |
| * |
| * @see InetAddress#isLinkLocalAddress() |
| */ |
| private static boolean isIPv6LinkLocalAddress(Inet6Address addr) { |
| byte[] addrBytes = addr.getAddress(); |
| return ((addrBytes[0] == (byte) 0xfe) && (addrBytes[1] == (byte) 0x80)); |
| } |
| } |