This is an automated email from the ASF dual-hosted git repository.
jinmeiliao pushed a commit to branch support/1.15
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/support/1.15 by this push:
new 7bc982dcb5 GEODE-10318: do not add duplicate entries in the locators
list (#7703)
7bc982dcb5 is described below
commit 7bc982dcb5c70950a020f797e836db01307768b3
Author: Jinmei Liao <[email protected]>
AuthorDate: Mon May 23 09:37:58 2022 -0700
GEODE-10318: do not add duplicate entries in the locators list (#7703)
* move locator parsing to api package
(cherry picked from commit 7e052cde43208ec0ea62374a95472807d60f444a)
---
.../internal/LocatorIntegrationTest.java | 61 +++++++++
.../distributed/internal/InternalLocator.java | 147 +++++++++++++--------
.../distributed/internal/InternalLocatorTest.java | 53 ++++++++
...st.java => LocatorConfigurationParserTest.java} | 6 +-
.../gms/membership/GMSJoinLeaveJUnitTest.java | 4 +-
.../membership/api/LocatorConfigurationParser.java | 142 ++++++++++++++++++++
.../internal/membership/gms/GMSUtil.java | 117 +---------------
.../membership/gms/locator/GMSLocator.java | 4 +-
.../membership/gms/membership/GMSJoinLeave.java | 4 +-
9 files changed, 360 insertions(+), 178 deletions(-)
diff --git
a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/LocatorIntegrationTest.java
b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/LocatorIntegrationTest.java
new file mode 100644
index 0000000000..2edaafd1d2
--- /dev/null
+++
b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/LocatorIntegrationTest.java
@@ -0,0 +1,61 @@
+/*
+ *
+ * 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.assertj.core.api.Assertions.assertThat;
+
+import java.net.UnknownHostException;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.geode.internal.AvailablePortHelper;
+import org.apache.geode.internal.inet.LocalHostUtil;
+import org.apache.geode.test.junit.rules.LocatorStarterRule;
+
+public class LocatorIntegrationTest {
+ @Rule
+ public LocatorStarterRule locator = new LocatorStarterRule();
+
+ @Test
+ public void locatorConfigurationShouldNotBeModifiedIfExists() throws
UnknownHostException {
+ int port = AvailablePortHelper.getRandomAvailableTCPPort();
+ locator.withPort(port);
+ String hostAddress = LocalHostUtil.getLocalHost().getHostAddress();
+ String originalLocators = hostAddress + "[" + port + "]";
+ locator.withProperty("locators", originalLocators);
+ locator.startLocator();
+
+ String locators = locator.getLocator().getConfig().getLocators();
+ assertThat(locators).isEqualTo(originalLocators);
+ }
+
+ @Test
+ public void locatorConfigurationWillBeModifiedToIncludeItselfWithHostName()
+ throws UnknownHostException {
+ int port = AvailablePortHelper.getRandomAvailableTCPPort();
+ locator.withPort(port);
+ locator.startLocator();
+
+ String locators = locator.getLocator().getConfig().getLocators();
+ String hostAddress = LocalHostUtil.getLocalHost().getCanonicalHostName();
+ assertThat(locators).isEqualTo(hostAddress + "[" + port + "]");
+ }
+
+
+}
diff --git
a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
index 201d3cbc70..68b2ce1f8b 100644
---
a/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
+++
b/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalLocator.java
@@ -24,6 +24,7 @@ import static
org.apache.geode.util.internal.GeodeGlossary.GEMFIRE_PREFIX;
import java.io.File;
import java.io.IOException;
+import java.net.InetAddress;
import java.net.URI;
import java.net.UnknownHostException;
import java.nio.file.Path;
@@ -31,6 +32,7 @@ import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -64,6 +66,7 @@ import org.apache.geode.distributed.Locator;
import
org.apache.geode.distributed.internal.InternalDistributedSystem.ConnectListener;
import
org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.distributed.internal.membership.adapter.ServiceConfig;
+import
org.apache.geode.distributed.internal.membership.api.LocatorConfigurationParser;
import org.apache.geode.distributed.internal.membership.api.MemberIdentifier;
import org.apache.geode.distributed.internal.membership.api.MembershipConfig;
import
org.apache.geode.distributed.internal.membership.api.MembershipConfigurationException;
@@ -71,6 +74,7 @@ import
org.apache.geode.distributed.internal.membership.api.MembershipLocator;
import
org.apache.geode.distributed.internal.membership.api.MembershipLocatorBuilder;
import org.apache.geode.distributed.internal.membership.api.QuorumChecker;
import org.apache.geode.distributed.internal.tcpserver.HostAddress;
+import org.apache.geode.distributed.internal.tcpserver.HostAndPort;
import org.apache.geode.distributed.internal.tcpserver.InfoRequest;
import org.apache.geode.distributed.internal.tcpserver.TcpHandler;
import org.apache.geode.distributed.internal.tcpserver.TcpServer;
@@ -707,71 +711,102 @@ public class InternalLocator extends Locator implements
ConnectListener, LogConf
// LOG: changed from config to info
logger.info("Using existing distributed system: {}", existing);
startCache(existing);
- } else {
+ return;
+ }
- StringBuilder sb = new StringBuilder(100);
- if (hostAddress != null &&
!StringUtils.isEmpty(hostAddress.getHostName())) {
- sb.append(hostAddress.getHostName());
- } else {
- sb.append(LocalHostUtil.getLocalHost().getCanonicalHostName());
- }
- sb.append('[').append(getPort()).append(']');
- String thisLocator = sb.toString();
-
- if (peerLocator) {
- // append this locator to the locators list from the config properties
- boolean setLocatorsProp = false;
- String locatorsConfigValue = distributionConfig.getLocators();
- if (StringUtils.isNotBlank(locatorsConfigValue)) {
- if (!locatorsConfigValue.contains(thisLocator)) {
- locatorsConfigValue = locatorsConfigValue + ',' + thisLocator;
- setLocatorsProp = true;
- }
- } else {
- locatorsConfigValue = thisLocator;
- setLocatorsProp = true;
- }
- if (setLocatorsProp) {
- Properties updateEnv = new Properties();
- updateEnv.setProperty(LOCATORS, locatorsConfigValue);
- distributionConfig.setApiProps(updateEnv);
- String locatorsPropertyName = GEMFIRE_PREFIX + LOCATORS;
- if (System.getProperty(locatorsPropertyName) != null) {
- System.setProperty(locatorsPropertyName, locatorsConfigValue);
- }
- }
- // No longer default mcast-port to zero.
+ HostAddress thisLocator = getHostAddress(hostAddress);
+ if (peerLocator) {
+ String existingLocators = distributionConfig.getLocators();
+ String newLocators = addLocatorIfMissing(existingLocators, thisLocator,
getPort());
+ if (!newLocators.equals(existingLocators)) {
+ setLocatorProperties(newLocators);
}
+ }
- Properties distributedSystemProperties = new Properties();
- // LogWriterAppender is now shared via that class
- // using a DistributionConfig earlier in this method
- distributedSystemProperties.put(DistributionConfig.DS_CONFIG_NAME,
distributionConfig);
-
- logger.info("Starting distributed system");
-
- internalDistributedSystem =
- InternalDistributedSystem
- .connectInternal(distributedSystemProperties, null,
- new InternalDistributedSystemMetricsService.Builder(),
- membershipLocator);
-
- if (peerLocator) {
- // We've created a peer location message handler - it needs to be
connected to
- // the membership service in order to get membership view notifications
- membershipLocator
- .setMembership(internalDistributedSystem.getDM()
- .getDistribution().getMembership());
- }
+ Properties distributedSystemProperties = new Properties();
+ // LogWriterAppender is now shared via that class
+ // using a DistributionConfig earlier in this method
+ distributedSystemProperties.put(DistributionConfig.DS_CONFIG_NAME,
distributionConfig);
+
+ logger.info("Starting distributed system");
+
+ internalDistributedSystem =
+ InternalDistributedSystem
+ .connectInternal(distributedSystemProperties, null,
+ new InternalDistributedSystemMetricsService.Builder(),
+ membershipLocator);
+
+ if (peerLocator) {
+ // We've created a peer location message handler - it needs to be
connected to
+ // the membership service in order to get membership view notifications
+ membershipLocator
+ .setMembership(internalDistributedSystem.getDM()
+ .getDistribution().getMembership());
+ }
+
+ internalDistributedSystem.addDisconnectListener(sys -> stop(false, false,
false));
+
+ startCache(internalDistributedSystem);
- internalDistributedSystem.addDisconnectListener(sys -> stop(false,
false, false));
+ logger.info("Locator started on {}[{}]", thisLocator, getPort());
- startCache(internalDistributedSystem);
+ }
+
+ HostAddress getHostAddress(HostAddress hostAddress) throws
UnknownHostException {
+ HostAddress thisLocator;
+ if (hostAddress != null &&
!StringUtils.isEmpty(hostAddress.getHostName())) {
+ thisLocator = hostAddress;
+ } else {
+ thisLocator = new HostAddress(LocalHostUtil.getLocalHost());
+ }
+ return thisLocator;
+ }
+
+ /**
+ * add this locator to the locators list if not already in, note the
locator's
+ * hostname is used, but if it resoves to be the same as what's already in
the
+ * list, what's specified by the user is preserved
+ *
+ * @param existingLocators the existing configured locators
+ * @param thisLocator this locator's address
+ * @param port this locator's port
+ * @return the comma separated list of locators with this locator added
+ * if this locator is not already in the list
+ */
+ String addLocatorIfMissing(String existingLocators, HostAddress thisLocator,
int port)
+ throws IOException {
+ String thisLocatorHostnameAndPort = String.format("%s[%d]",
thisLocator.getHostName(), port);
+ if (StringUtils.isBlank(existingLocators)) {
+ return thisLocatorHostnameAndPort;
+ }
+
+ List<HostAndPort> hostAndPorts;
+ try {
+ hostAndPorts =
LocatorConfigurationParser.parseLocators(existingLocators, (InetAddress) null);
+ } catch (MembershipConfigurationException e) {
+ throw new IOException(e.getMessage(), e);
+ }
- logger.info("Locator started on {}", thisLocator);
+ if (hostAndPorts.stream().anyMatch(
+ (hp) -> thisLocator.getAddress().equals(hp.getAddress())
+ && port == hp.getPort())) {
+ return existingLocators;
}
+ // if not found in existing locators
+ return existingLocators + "," + thisLocatorHostnameAndPort;
}
+ private void setLocatorProperties(String locatorsConfigValue) {
+ Properties updateEnv = new Properties();
+ updateEnv.setProperty(LOCATORS, locatorsConfigValue);
+ distributionConfig.setApiProps(updateEnv);
+ String locatorsPropertyName = GEMFIRE_PREFIX + LOCATORS;
+ if (System.getProperty(locatorsPropertyName) != null) {
+ System.setProperty(locatorsPropertyName, locatorsConfigValue);
+ }
+ }
+
+
private void startCache(DistributedSystem system) throws IOException {
InternalCache internalCache = GemFireCacheImpl.getInstance();
if (internalCache == null) {
diff --git
a/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalLocatorTest.java
b/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalLocatorTest.java
index fd678c805e..d7b59d20ea 100644
---
a/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalLocatorTest.java
+++
b/geode-core/src/test/java/org/apache/geode/distributed/internal/InternalLocatorTest.java
@@ -15,6 +15,7 @@
package org.apache.geode.distributed.internal;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
@@ -33,9 +34,11 @@ import org.junit.Test;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.internal.HttpService;
+import org.apache.geode.distributed.internal.tcpserver.HostAddress;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.internal.cache.InternalCacheForClientAccess;
import org.apache.geode.internal.cache.InternalRegionFactory;
+import org.apache.geode.internal.inet.LocalHostUtil;
import org.apache.geode.internal.security.SecurableCommunicationChannel;
import org.apache.geode.logging.internal.LoggingSession;
import org.apache.geode.management.internal.AgentUtil;
@@ -67,6 +70,8 @@ public class InternalLocatorTest {
when(distributionConfig.getSecurableCommunicationChannels())
.thenReturn(new SecurableCommunicationChannel[] {});
when(distributionConfig.getSecurityAuthTokenEnabledComponents()).thenReturn(new
String[] {});
+ when(distributionConfig.getSSLProtocols()).thenReturn("any");
+ when(distributionConfig.getClusterSSLProtocols()).thenReturn("any");
when(cache.createInternalRegionFactory(RegionShortcut.REPLICATE)).thenReturn(regionFactory);
when(cache.getOptionalService(HttpService.class))
.thenReturn(Optional.of(httpService));
@@ -133,4 +138,52 @@ public class InternalLocatorTest {
verify(httpService, never()).addWebApplication(eq("/management"), any(),
any());
}
+ @Test
+ public void getHostAddress() throws Exception {
+ // use localhost if no bindAddress
+ HostAddress locator = internalLocator.getHostAddress(null);
+ assertThat(locator.getAddress()).isEqualTo(LocalHostUtil.getLocalHost());
+
+ // use bindAddress name
+ HostAddress bindAddress = new HostAddress("test");
+ locator = internalLocator.getHostAddress(bindAddress);
+ assertThat(locator).isEqualTo(bindAddress);
+ }
+
+ @Test
+ public void addLocatorToBlankConfig() throws Exception {
+ String localHostname = LocalHostUtil.getCanonicalLocalHostName();
+ HostAddress localhost = new HostAddress(LocalHostUtil.getLocalHost());
+ String locator = internalLocator.addLocatorIfMissing(null, localhost,
1234);
+ assertThat(locator).isEqualTo(localHostname + "[1234]");
+ }
+
+ @Test
+ public void configurePeerLocatorWithNoMatchLocatorList() throws Exception {
+ String localHostname = LocalHostUtil.getCanonicalLocalHostName();
+ HostAddress localhost = new HostAddress(LocalHostUtil.getLocalHost());
+ String existing = "10.10.10.10[12345]";
+ String locator = internalLocator.addLocatorIfMissing(existing, localhost,
1234);
+ assertThat(locator).isEqualTo(existing + "," + localHostname + "[1234]");
+ }
+
+ @Test
+ public void configurePeerLocatorWithMatchingLocatorList() throws Exception {
+ HostAddress localhost = new HostAddress(LocalHostUtil.getLocalHost());
+ String localAddress = LocalHostUtil.getLocalHost().getHostAddress();
+ String existing = localAddress + "[12345]";
+ String locator = internalLocator.addLocatorIfMissing(existing, localhost,
12345);
+ // what's returned is what's specified in the original configuration
+ assertThat(locator).isEqualTo(existing);
+ }
+
+ @Test
+ public void configurePeerLocatorWithMatchingAddressButNoMatchingPort()
throws Exception {
+ HostAddress localhost = new HostAddress(LocalHostUtil.getLocalHost());
+ String localAddress = LocalHostUtil.getLocalHost().getHostAddress();
+ String existing = localAddress + "[11110]";
+ String locator = internalLocator.addLocatorIfMissing(existing, localhost,
12345);
+ // what's returned is what's specified in the original configuration
+ assertThat(locator).isEqualTo(existing + "," + localhost.getHostName() +
"[12345]");
+ }
}
diff --git
a/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/GMSUtilTest.java
b/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/LocatorConfigurationParserTest.java
similarity index 97%
rename from
geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/GMSUtilTest.java
rename to
geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/LocatorConfigurationParserTest.java
index d927c21ac2..90fa55caa6 100644
---
a/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/GMSUtilTest.java
+++
b/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/LocatorConfigurationParserTest.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -11,11 +12,12 @@
* 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.membership.gms;
-import static
org.apache.geode.distributed.internal.membership.gms.GMSUtil.parseLocators;
+import static
org.apache.geode.distributed.internal.membership.api.LocatorConfigurationParser.parseLocators;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -31,7 +33,7 @@ import
org.apache.geode.distributed.internal.tcpserver.HostAndPort;
import org.apache.geode.test.junit.runners.GeodeParamsRunner;
@RunWith(GeodeParamsRunner.class)
-public class GMSUtilTest {
+public class LocatorConfigurationParserTest {
static final int PORT = 1234; // any old port--no need to have anything
actually bound here
diff --git
a/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
b/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
index 55318cd3af..94fe9cb0fb 100644
---
a/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
+++
b/geode-membership/src/integrationTest/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeaveJUnitTest.java
@@ -57,6 +57,7 @@ import org.mockito.internal.verification.Times;
import org.mockito.verification.Timeout;
import org.apache.geode.distributed.internal.membership.api.Authenticator;
+import
org.apache.geode.distributed.internal.membership.api.LocatorConfigurationParser;
import org.apache.geode.distributed.internal.membership.api.MemberDataBuilder;
import org.apache.geode.distributed.internal.membership.api.MemberIdentifier;
import
org.apache.geode.distributed.internal.membership.api.MemberIdentifierFactoryImpl;
@@ -64,7 +65,6 @@ import
org.apache.geode.distributed.internal.membership.api.MemberStartupExcepti
import org.apache.geode.distributed.internal.membership.api.MembershipConfig;
import
org.apache.geode.distributed.internal.membership.api.MembershipConfigurationException;
import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
-import org.apache.geode.distributed.internal.membership.gms.GMSUtil;
import
org.apache.geode.distributed.internal.membership.gms.MemberIdentifierImpl;
import org.apache.geode.distributed.internal.membership.gms.Services;
import org.apache.geode.distributed.internal.membership.gms.Services.Stopper;
@@ -443,7 +443,7 @@ public class GMSJoinLeaveJUnitTest {
@Test
public void multipleLocatorsWithSameAddressAreCanonicalized() throws
Exception {
- List<HostAndPort> locators = GMSUtil.parseLocators(
+ List<HostAndPort> locators = LocatorConfigurationParser.parseLocators(
"localhost[1234],localhost[1234],localhost[1234]", (InetAddress) null);
assertThat(locators.size()).isEqualTo(1);
}
diff --git
a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/api/LocatorConfigurationParser.java
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/api/LocatorConfigurationParser.java
new file mode 100644
index 0000000000..609d0a5698
--- /dev/null
+++
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/api/LocatorConfigurationParser.java
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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.membership.api;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.geode.distributed.internal.tcpserver.HostAndPort;
+import org.apache.geode.internal.inet.LocalHostUtil;
+
+public class LocatorConfigurationParser {
+ /**
+ * parse locators & check that the resulting address is compatible with the
given address
+ *
+ * @param locatorsString a DistributionConfig "locators" string
+ * @param bindAddress optional address to check for loopback compatibility
+ * @return addresses of locators
+ */
+ public static List<HostAndPort> parseLocators(String locatorsString, String
bindAddress)
+ throws MembershipConfigurationException {
+ InetAddress addr = null;
+
+ try {
+ if (bindAddress == null || bindAddress.trim().length() == 0) {
+ addr = LocalHostUtil.getLocalHost();
+ } else {
+ addr = InetAddress.getByName(bindAddress);
+ }
+ } catch (UnknownHostException e) {
+ // ignore
+ }
+ return parseLocators(locatorsString, addr);
+ }
+
+ /**
+ * parse locators & check that the resulting address is compatible with the
given address
+ *
+ * @param locatorsString a DistributionConfig "locators" string
+ * @param bindAddress optional address to check for loopback compatibility
+ * @return addresses of locators
+ */
+ public static List<HostAndPort> parseLocators(String locatorsString,
InetAddress bindAddress)
+ throws MembershipConfigurationException {
+ List<HostAndPort> result = new ArrayList<>(2);
+ Set<InetSocketAddress> inetAddresses = new HashSet<>();
+ final boolean isLoopback = ((bindAddress != null) &&
bindAddress.isLoopbackAddress());
+
+ StringTokenizer parts = new StringTokenizer(locatorsString, ",");
+ while (parts.hasMoreTokens()) {
+ String str = parts.nextToken();
+
+ HostAndPort hostAndPort = parseLocator(str);
+ String host = hostAndPort.getHostName();
+ final InetSocketAddress isa = new InetSocketAddress(host,
hostAndPort.getPort());
+
+ if (isLoopback) {
+ final InetAddress locatorAddress = isa.getAddress();
+ if (locatorAddress == null) {
+ throw new MembershipConfigurationException("This process is
attempting to use a locator" +
+ " at an unknown address or FQDN: " + host);
+ }
+
+ if (!locatorAddress.isLoopbackAddress()) {
+ throw new MembershipConfigurationException(
+ "This process is attempting to join with a loopback address (" +
bindAddress
+ + ") using a locator that does not have a local address (" +
isa
+ + "). On Unix this usually means that /etc/hosts is
misconfigured.");
+ }
+ }
+ if (!inetAddresses.contains(isa)) {
+ inetAddresses.add(isa);
+ result.add(hostAndPort);
+ }
+ }
+
+ return result;
+ }
+
+ public static HostAndPort parseLocator(String locatorHostAndPort)
+ throws MembershipConfigurationException {
+ final int portSpecificationStart = locatorHostAndPort.indexOf('[');
+
+ if (portSpecificationStart == -1) {
+ throw createBadPortException(locatorHostAndPort);
+ }
+
+ String host = locatorHostAndPort.substring(0, portSpecificationStart);
+
+ int idx = host.lastIndexOf('@');
+ if (idx < 0) {
+ idx = host.lastIndexOf(':');
+ }
+ String start = host.substring(0, idx > -1 ? idx : host.length());
+ if (start.indexOf(':') >= 0) { // a single numeric ipv6 address
+ idx = host.lastIndexOf('@');
+ }
+ if (idx >= 0) {
+ host = host.substring(idx + 1);
+ }
+
+ int startIdx = portSpecificationStart + 1;
+ int endIdx = locatorHostAndPort.indexOf(']');
+
+ if (endIdx == -1) {
+ throw createBadPortException(locatorHostAndPort);
+ }
+
+ final int port;
+ try {
+ port = Integer.parseInt(locatorHostAndPort.substring(startIdx, endIdx));
+ } catch (NumberFormatException e) {
+ throw createBadPortException(locatorHostAndPort);
+ }
+ return new HostAndPort(host, port);
+ }
+
+ private static MembershipConfigurationException createBadPortException(final
String str) {
+ return new MembershipConfigurationException("This process is attempting to
use a locator" +
+ " with a malformed port specification: " + str);
+ }
+}
diff --git
a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java
index f9e60e43b8..bea1f32ff2 100644
---
a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java
+++
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/GMSUtil.java
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -11,15 +12,13 @@
* 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.membership.gms;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -27,9 +26,6 @@ import java.util.Set;
import java.util.StringTokenizer;
import org.apache.geode.distributed.internal.membership.api.MemberIdentifier;
-import
org.apache.geode.distributed.internal.membership.api.MembershipConfigurationException;
-import org.apache.geode.distributed.internal.tcpserver.HostAndPort;
-import org.apache.geode.internal.inet.LocalHostUtil;
import org.apache.geode.internal.serialization.DeserializationContext;
import org.apache.geode.internal.serialization.SerializationContext;
import org.apache.geode.internal.serialization.StaticSerialization;
@@ -39,29 +35,6 @@ import
org.apache.geode.internal.serialization.StaticSerialization;
*/
public class GMSUtil {
- /**
- * parse locators & check that the resulting address is compatible with the
given address
- *
- * @param locatorsString a DistributionConfig "locators" string
- * @param bindAddress optional address to check for loopback compatibility
- * @return addresses of locators
- */
- public static List<HostAndPort> parseLocators(String locatorsString, String
bindAddress)
- throws MembershipConfigurationException {
- InetAddress addr = null;
-
- try {
- if (bindAddress == null || bindAddress.trim().length() == 0) {
- addr = LocalHostUtil.getLocalHost();
- } else {
- addr = InetAddress.getByName(bindAddress);
- }
- } catch (UnknownHostException e) {
- // ignore
- }
- return parseLocators(locatorsString, addr);
- }
-
public static <ID extends MemberIdentifier> Set<ID>
readHashSetOfMemberIDs(DataInput in,
DeserializationContext context)
throws IOException, ClassNotFoundException {
@@ -77,92 +50,8 @@ public class GMSUtil {
}
/**
- * parse locators & check that the resulting address is compatible with the
given address
- *
- * @param locatorsString a DistributionConfig "locators" string
- * @param bindAddress optional address to check for loopback compatibility
- * @return addresses of locators
+ * Parses comma-separated-roles/groups into array of groups (strings).
*/
- public static List<HostAndPort> parseLocators(String locatorsString,
InetAddress bindAddress)
- throws MembershipConfigurationException {
- List<HostAndPort> result = new ArrayList<>(2);
- Set<InetSocketAddress> inetAddresses = new HashSet<>();
- String host;
- final boolean isLoopback = ((bindAddress != null) &&
bindAddress.isLoopbackAddress());
-
- StringTokenizer parts = new StringTokenizer(locatorsString, ",");
- while (parts.hasMoreTokens()) {
- String str = parts.nextToken();
-
- final int portSpecificationStart = str.indexOf('[');
-
- if (portSpecificationStart == -1) {
- throw createBadPortException(str);
- }
-
- host = str.substring(0, portSpecificationStart);
-
- int idx = host.lastIndexOf('@');
- if (idx < 0) {
- idx = host.lastIndexOf(':');
- }
- String start = host.substring(0, idx > -1 ? idx : host.length());
- if (start.indexOf(':') >= 0) { // a single numeric ipv6 address
- idx = host.lastIndexOf('@');
- }
- if (idx >= 0) {
- host = host.substring(idx + 1);
- }
-
- int startIdx = portSpecificationStart + 1;
- int endIdx = str.indexOf(']');
-
- if (endIdx == -1) {
- throw createBadPortException(str);
- }
-
- final int port;
-
- try {
- port = Integer.parseInt(str.substring(startIdx, endIdx));
- } catch (NumberFormatException e) {
- throw createBadPortException(str);
- }
-
- final InetSocketAddress isa = new InetSocketAddress(host, port);
-
- if (isLoopback) {
- final InetAddress locatorAddress = isa.getAddress();
-
- if (locatorAddress == null) {
- throw new MembershipConfigurationException("This process is
attempting to use a locator" +
- " at an unknown address or FQDN: " + host);
- }
-
- if (!locatorAddress.isLoopbackAddress()) {
- throw new MembershipConfigurationException(
- "This process is attempting to join with a loopback address (" +
bindAddress
- + ") using a locator that does not have a local address (" +
isa
- + "). On Unix this usually means that /etc/hosts is
misconfigured.");
- }
- }
-
- HostAndPort hostAndPort = new HostAndPort(host, port);
- if (!inetAddresses.contains(isa)) {
- inetAddresses.add(isa);
- result.add(hostAndPort);
- }
- }
-
- return result;
- }
-
- private static MembershipConfigurationException createBadPortException(final
String str) {
- return new MembershipConfigurationException("This process is attempting to
use a locator" +
- " with a malformed port specification: " + str);
- }
-
- /** Parses comma-separated-roles/groups into array of groups (strings). */
public static String[] parseGroups(String csvRoles, String csvGroups) {
List<String> groups = new ArrayList<>();
parseCsv(groups, csvRoles);
diff --git
a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java
index 821891a1ca..cd5b18955b 100644
---
a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java
+++
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/GMSLocator.java
@@ -36,11 +36,11 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.logging.log4j.Logger;
import org.apache.geode.annotations.VisibleForTesting;
+import
org.apache.geode.distributed.internal.membership.api.LocatorConfigurationParser;
import org.apache.geode.distributed.internal.membership.api.MemberIdentifier;
import
org.apache.geode.distributed.internal.membership.api.MembershipConfigurationException;
import
org.apache.geode.distributed.internal.membership.api.MembershipLocatorStatistics;
import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
-import org.apache.geode.distributed.internal.membership.gms.GMSUtil;
import org.apache.geode.distributed.internal.membership.gms.Services;
import org.apache.geode.distributed.internal.membership.gms.interfaces.Locator;
import
org.apache.geode.distributed.internal.membership.gms.messenger.GMSMemberWrapper;
@@ -121,7 +121,7 @@ public class GMSLocator<ID extends MemberIdentifier>
implements Locator<ID>, Tcp
if (this.locatorString == null || this.locatorString.isEmpty()) {
locators = new ArrayList<>(0);
} else {
- locators = GMSUtil.parseLocators(locatorString,
+ locators = LocatorConfigurationParser.parseLocators(locatorString,
bindAddress == null ? null : bindAddress.getAddress());
}
this.locatorStats = locatorStats;
diff --git
a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
index 31879f815d..48e5ed1447 100644
---
a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
+++
b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave.java
@@ -41,13 +41,13 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.geode.annotations.VisibleForTesting;
+import
org.apache.geode.distributed.internal.membership.api.LocatorConfigurationParser;
import org.apache.geode.distributed.internal.membership.api.MemberIdentifier;
import
org.apache.geode.distributed.internal.membership.api.MemberStartupException;
import
org.apache.geode.distributed.internal.membership.api.MembershipClosedException;
import org.apache.geode.distributed.internal.membership.api.MembershipConfig;
import
org.apache.geode.distributed.internal.membership.api.MembershipConfigurationException;
import org.apache.geode.distributed.internal.membership.gms.GMSMembershipView;
-import org.apache.geode.distributed.internal.membership.gms.GMSUtil;
import org.apache.geode.distributed.internal.membership.gms.Services;
import
org.apache.geode.distributed.internal.membership.gms.interfaces.JoinLeave;
import
org.apache.geode.distributed.internal.membership.gms.locator.FindCoordinatorRequest;
@@ -1912,7 +1912,7 @@ public class GMSJoinLeave<ID extends MemberIdentifier>
implements JoinLeave<ID>
config.isNetworkPartitionDetectionEnabled();
String bindAddr = config.getBindAddress();
- locators = GMSUtil.parseLocators(config.getLocators(), bindAddr);
+ locators = LocatorConfigurationParser.parseLocators(config.getLocators(),
bindAddr);
if (logger.isDebugEnabled()) {
logger.debug("Parsed locators are {}", locators);
}