From 0af626462642c6352840cd6e81a5265c74045c7f Mon Sep 17 00:00:00 2001 From: Bruce Schuchardt Date: Mon, 2 Mar 2020 13:09:07 -0800 Subject: [PATCH] GEODE-7808: standardize on use of HostAndPort to form client-side connections (#4743) * Squashed merge of feature/GEODE-7808 removed HostAddress renamed LocatorAddress to HostAndPort modified TcpClient methods to take a HostAndPort argument instead of InetAddress modified SocketCreator to take a HostAndPort argument instead of InetAddress * GEODE-7808 - standardize on use of HostAndPort for connection formation This continues a previous PR that passed and was approved for merge. This commit raises up several methods from SocketCreator into the TcpSocketCreator interface. This is an intermediate commit. A subsequent commit will refactor TcpSocketCreator to separate the client and server methods for creating server-sockets and client connections to server-sockets. * refactored socket-creators to separate concerns ServerSocketCreator holds methods for non-client comms ClientSocketCreator holds methods that clients should use for comms AdvancedSocketCreator holds methods for people who need to get around the limitations of the other two interfaces * adding missing interface * move code out of inner-classes into first-class classes * renaming interfaces and methods to be less confusing --- .../geode/metrics/CacheCommonTagsTest.java | 3 +- .../LocatorLoadBalancingDUnitTest.java | 6 +- .../cache30/ClientMembershipDUnitTest.java | 3 - .../AutoConnectionSourceImplJUnitTest.java | 28 +- .../LauncherIntegrationTestCase.java | 3 +- .../distributed/LocatorIntegrationTest.java | 4 +- .../TCPClientSSLIntegrationTest.java | 12 +- .../tcpserver/TCPServerSSLJUnitTest.java | 5 +- .../ClientSocketFactoryIntegrationTest.java | 4 +- .../net/SSLSocketIntegrationTest.java | 13 +- .../GemFireStatSamplerIntegrationTest.java | 3 +- .../SimpleStatSamplerIntegrationTest.java | 3 +- ...cketParameterExtensionIntegrationTest.java | 11 +- .../DistributionLocatorConfigImpl.java | 8 +- .../internal/DistributionLocatorImpl.java | 3 +- .../internal/ManagedEntityConfigImpl.java | 3 +- .../jmx/internal/MX4JServerSocketFactory.java | 10 +- .../internal/AutoConnectionSourceImpl.java | 47 ++- .../cache/client/internal/ConnectionImpl.java | 7 +- .../geode/cache/client/internal/PoolImpl.java | 24 +- .../org/apache/geode/distributed/Locator.java | 3 +- .../geode/distributed/LocatorLauncher.java | 4 +- .../internal/DistributionConfigImpl.java | 3 +- .../membership/InternalDistributedMember.java | 30 +- .../apache/geode/internal/AbstractConfig.java | 2 +- .../apache/geode/internal/DSFIDFactory.java | 2 + .../geode/internal/DistributionLocator.java | 6 +- .../apache/geode/internal/SystemAdmin.java | 9 +- .../admin/remote/DistributionLocatorId.java | 29 +- .../internal/cache/GemFireCacheImpl.java | 8 +- .../geode/internal/cache/PoolFactoryImpl.java | 79 ++-- .../persistence/PersistentMemberPattern.java | 3 +- .../cache/tier/sockets/AcceptorImpl.java | 5 +- .../tier/sockets/CacheClientUpdater.java | 4 +- .../cache/wan/AbstractGatewaySender.java | 2 +- .../internal/net/SCAdvancedSocketCreator.java | 119 ++++++ .../internal/net/SCClientSocketCreator.java | 20 +- .../internal/net/SCServerSocketCreator.java | 109 ++++++ .../geode/internal/net/SocketCreator.java | 367 ++++-------------- .../internal/statistics/HostStatSampler.java | 3 +- .../statistics/StatArchiveWriter.java | 3 +- .../apache/geode/internal/tcp/TCPConduit.java | 7 +- ...ContextAwareSSLRMIClientSocketFactory.java | 5 +- .../internal/JmxManagerLocatorRequest.java | 8 +- .../management/internal/ManagementAgent.java | 8 +- .../internal/api/GeodeConnectionConfig.java | 4 +- .../ClusterConfigurationStatusRetriever.java | 11 +- .../sanctioned-geode-core-serializables.txt | 8 +- .../cache/client/internal/PoolImplTest.java | 4 +- .../internal/cache/CacheServerImplTest.java | 5 + .../sockets/CacheClientUpdaterJUnitTest.java | 6 +- .../internal/net/SocketCreatorJUnitTest.java | 8 +- .../geode/internal/tcp/TCPConduitTest.java | 3 +- .../tier/sockets/DurableClientTestBase.java | 3 +- .../tier/sockets/DurableClientTestCase.java | 11 +- .../client/internal/LocatorTestBase.java | 10 +- .../test/dunit/rules/DistributedRule.java | 1 - .../internal/membership/gms/GMSUtilTest.java | 36 +- .../gms/membership/GMSJoinLeaveJUnitTest.java | 12 +- .../internal/membership/gms/GMSUtil.java | 14 +- .../membership/gms/MemberDataBuilderImpl.java | 4 +- .../membership/gms/MemberIdentifierImpl.java | 4 +- .../membership/gms/fd/GMSHealthMonitor.java | 7 +- .../membership/gms/locator/GMSLocator.java | 13 +- .../gms/locator/MembershipLocatorImpl.java | 4 +- .../gms/membership/GMSJoinLeave.java | 9 +- .../CacheConnectionIntegrationTest.java | 4 +- .../acceptance/CacheOperationsJUnitTest.java | 4 +- .../DataSerializableFixedID.java | 1 + .../serialization/StaticSerialization.java | 1 + .../TcpServerGossipVersionDUnitTest.java | 3 +- .../tcpserver/TcpServerJUnitTest.java | 30 +- .../TcpServerProductVersionDUnitTest.java | 17 +- .../tcpserver/AdvancedSocketCreator.java | 61 +++ .../tcpserver/AdvancedSocketCreatorImpl.java | 180 +++++++++ .../tcpserver/ClientSocketCreator.java | 48 +++ .../tcpserver/ClientSocketCreatorImpl.java | 54 +++ .../tcpserver/ClusterSocketCreator.java | 66 ++++ .../internal/tcpserver/HostAndPort.java | 154 ++++++++ .../internal/tcpserver/LocatorAddress.java | 91 ----- .../tcpserver/ServerSocketCreatorImpl.java | 96 +++++ .../internal/tcpserver/TcpClient.java | 64 +-- .../internal/tcpserver/TcpServer.java | 6 +- .../internal/tcpserver/TcpSocketCreator.java | 38 +- .../tcpserver/TcpSocketCreatorImpl.java | 191 +-------- ...rAddressTest.java => HostAndPortTest.java} | 40 +- ...ANHostNameVerificationDistributedTest.java | 31 +- .../locator/wan/LocatorDiscovery.java | 11 +- .../wan/LocatorMembershipListenerImpl.java | 6 +- .../wan/LocatorMembershipListenerTest.java | 4 +- ...rEventRemoteDispatcherIntegrationTest.java | 17 - 91 files changed, 1431 insertions(+), 1002 deletions(-) create mode 100644 geode-core/src/main/java/org/apache/geode/internal/net/SCAdvancedSocketCreator.java rename geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/HostAddress.java => geode-core/src/main/java/org/apache/geode/internal/net/SCClientSocketCreator.java (58%) create mode 100644 geode-core/src/main/java/org/apache/geode/internal/net/SCServerSocketCreator.java create mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreator.java create mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreatorImpl.java create mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreator.java create mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreatorImpl.java create mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClusterSocketCreator.java create mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/HostAndPort.java delete mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/LocatorAddress.java create mode 100644 geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ServerSocketCreatorImpl.java rename geode-tcp-server/src/test/java/org/apache/geode/distributed/internal/tcpserver/{LocatorAddressTest.java => HostAndPortTest.java} (56%) diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/CacheCommonTagsTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/CacheCommonTagsTest.java index 1ca677cba8ae..58a1cfd1439f 100644 --- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/CacheCommonTagsTest.java +++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/CacheCommonTagsTest.java @@ -30,7 +30,6 @@ import org.apache.geode.cache.CacheFactory; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.inet.LocalHostUtil; -import org.apache.geode.internal.net.SocketCreator; public class CacheCommonTagsTest { @@ -57,7 +56,7 @@ public void metersHaveHostTag() throws UnknownHostException { assertThat(meter.getId().getTags()) .as("Tags for meter with name " + meterId.getName()) - .contains(Tag.of("host", SocketCreator.getHostName(LocalHostUtil.getLocalHost()))); + .contains(Tag.of("host", LocalHostUtil.getLocalHost().getHostName())); } } diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/LocatorLoadBalancingDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/LocatorLoadBalancingDUnitTest.java index 54f552f133c3..f88ba3ca848b 100644 --- a/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/LocatorLoadBalancingDUnitTest.java +++ b/geode-core/src/distributedTest/java/org/apache/geode/cache/client/internal/LocatorLoadBalancingDUnitTest.java @@ -18,7 +18,6 @@ import java.io.IOException; import java.io.Serializable; -import java.net.InetAddress; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -45,6 +44,7 @@ import org.apache.geode.distributed.internal.InternalLocator; import org.apache.geode.distributed.internal.ServerLocation; import org.apache.geode.distributed.internal.ServerLocator; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.cache.CacheServerImpl; @@ -181,8 +181,8 @@ private Object issueRequest(final String hostName, final int locatorPort, .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR), InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()) - .requestToServer(InetAddress.getByName(hostName), - locatorPort, + .requestToServer(new HostAndPort(hostName, + locatorPort), request, 10000, replyExpected); } diff --git a/geode-core/src/distributedTest/java/org/apache/geode/cache30/ClientMembershipDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/cache30/ClientMembershipDUnitTest.java index e69cbbee9ec9..bd339350a816 100644 --- a/geode-core/src/distributedTest/java/org/apache/geode/cache30/ClientMembershipDUnitTest.java +++ b/geode-core/src/distributedTest/java/org/apache/geode/cache30/ClientMembershipDUnitTest.java @@ -838,9 +838,6 @@ public void memberCrashed(ClientMembershipEvent event) { ClientCache clientCache = (ClientCache) getCache(); Set servers = clientCache.getCurrentServers(); assertTrue(!servers.isEmpty()); - InetSocketAddress serverAddr = servers.iterator().next(); - InetSocketAddress expectedAddr = new InetSocketAddress(serverMember.getHost(), ports[0]); - assertEquals(expectedAddr, serverAddr); // now check listener results assertTrue(fired[JOINED]); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java index 7399f0e1edfa..7534ecd2e81a 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImplJUnitTest.java @@ -68,7 +68,7 @@ import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.ProtocolCheckerImpl; import org.apache.geode.distributed.internal.ServerLocation; -import org.apache.geode.distributed.internal.tcpserver.LocatorAddress; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.distributed.internal.tcpserver.TcpHandler; import org.apache.geode.distributed.internal.tcpserver.TcpServer; @@ -81,7 +81,6 @@ import org.apache.geode.internal.security.SecurableCommunicationChannel; import org.apache.geode.management.membership.ClientMembershipEvent; import org.apache.geode.management.membership.ClientMembershipListener; -import org.apache.geode.test.dunit.NetworkUtils; import org.apache.geode.test.junit.categories.ClientServerTest; import org.apache.geode.util.internal.GeodeGlossary; @@ -123,8 +122,8 @@ public void setUp() throws Exception { InetAddress ia = InetAddress.getLocalHost(); InetSocketAddress isa = new InetSocketAddress(ia, port); locators.add(isa); - List la = new ArrayList<>(); - la.add(new LocatorAddress(isa, ia.getHostName())); + List la = new ArrayList<>(); + la.add(new HostAndPort(ia.getHostName(), port)); source = new AutoConnectionSourceImpl(la, "", 60 * 1000); source.start(pool); } @@ -163,7 +162,7 @@ private void issueStopRequest(final int port) .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR), InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()) - .stop(InetAddress.getLocalHost(), port); + .stop(new HostAndPort(InetAddress.getLocalHost().getHostName(), port)); } /** @@ -179,18 +178,18 @@ public void testAddBadLocator() { InetSocketAddress floc2 = new InetSocketAddress("fakeLocalHost2", port); locators.add(floc1); locators.add(floc2); - List la = new ArrayList<>(); - la.add(new LocatorAddress(floc1, floc1.getHostName())); - la.add(new LocatorAddress(floc2, floc2.getHostName())); + List la = new ArrayList<>(); + la.add(new HostAndPort(floc1.getHostName(), floc1.getPort())); + la.add(new HostAndPort(floc2.getHostName(), floc2.getPort())); AutoConnectionSourceImpl src = new AutoConnectionSourceImpl(la, "", 60 * 1000); InetSocketAddress b1 = new InetSocketAddress("fakeLocalHost1", port); InetSocketAddress b2 = new InetSocketAddress("fakeLocalHost3", port); - Set bla = new HashSet<>(); - bla.add(new LocatorAddress(b1, b1.getHostName())); - bla.add(new LocatorAddress(b2, b2.getHostName())); + Set bla = new HashSet<>(); + bla.add(new HostAndPort(b1.getHostName(), b1.getPort())); + bla.add(new HostAndPort(b2.getHostName(), b2.getPort())); src.addbadLocators(la, bla); @@ -212,13 +211,12 @@ public void testNoRespondingLocators() { @Test public void testSourceHandlesToDataException() throws IOException, ClassNotFoundException { TcpClient mockConnection = mock(TcpClient.class); - when(mockConnection.requestToServer(isA(InetSocketAddress.class), any(Object.class), + when(mockConnection.requestToServer(isA(HostAndPort.class), any(Object.class), isA(Integer.class), isA(Boolean.class))).thenThrow(new ToDataException("testing")); try { - InetSocketAddress address = new InetSocketAddress(NetworkUtils.getServerHostName(), 1234); - source.queryOneLocatorUsingConnection(new LocatorAddress(address, "locator[1234]"), mock( + source.queryOneLocatorUsingConnection(new HostAndPort("locator[1234]", 1234), mock( ServerLocationRequest.class), mockConnection); - verify(mockConnection).requestToServer(isA(InetSocketAddress.class), + verify(mockConnection).requestToServer(isA(HostAndPort.class), isA(ServerLocationRequest.class), isA(Integer.class), isA(Boolean.class)); } catch (NoAvailableLocatorsException expected) { // do nothing diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java index 99d28f356caa..6787ac7a84b7 100755 --- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/LauncherIntegrationTestCase.java @@ -293,7 +293,8 @@ private void givenPortInUse(final int port, InetAddress bindAddress) { try { socket = SocketCreatorFactory .createNonDefaultInstance(false, false, null, null, System.getProperties()) - .createServerSocket(port, 50, bindAddress, -1); + .forCluster() + .createServerSocket(port, 50, bindAddress); assertThat(socket.isBound()).isTrue(); assertThat(socket.isClosed()).isFalse(); assertThat(isPortAvailable(port, SOCKET)).isFalse(); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorIntegrationTest.java index e38223ebbb60..8f1c3a1f4bd7 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/LocatorIntegrationTest.java @@ -29,7 +29,6 @@ import java.io.File; import java.io.IOException; -import java.net.InetAddress; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -51,6 +50,7 @@ import org.apache.geode.distributed.internal.InternalLocator; import org.apache.geode.distributed.internal.ServerLocation; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.AvailablePortHelper; import org.apache.geode.internal.InternalDataSerializer; @@ -174,7 +174,7 @@ public void testBasicInfo() throws Exception { .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR), InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()); - String[] info = client.getInfo(InetAddress.getLocalHost(), boundPort); + String[] info = client.getInfo(new HostAndPort("localhost", boundPort)); assertThat(info).isNotNull(); assertThat(info.length).isGreaterThanOrEqualTo(1); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java index ef05022a661c..2ea1eb76c392 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPClientSSLIntegrationTest.java @@ -146,7 +146,8 @@ public void clientConnectsIfServerCertificateHasHostname() throws Exception { startServerAndClient(serverCertificate, clientCertificate, true); String response = - (String) client.requestToServer(localhost, port, Boolean.valueOf(false), 5 * 1000); + (String) client.requestToServer(new HostAndPort(localhost.getHostName(), port), + Boolean.valueOf(false), 5 * 1000); assertThat(response).isEqualTo("Running!"); } @@ -165,7 +166,8 @@ public void clientChooseToDisableHasHostnameValidation() throws Exception { startServerAndClient(serverCertificate, clientCertificate, false); String response = - (String) client.requestToServer(localhost, port, Boolean.valueOf(false), 5 * 1000); + (String) client.requestToServer(new HostAndPort(localhost.getHostName(), port), + Boolean.valueOf(false), 5 * 1000); assertThat(response).isEqualTo("Running!"); } @@ -184,7 +186,8 @@ public void clientFailsToConnectIfServerCertificateNoHostname() throws Exception startServerAndClient(serverCertificate, clientCertificate, true); assertThatExceptionOfType(IllegalStateException.class) - .isThrownBy(() -> client.requestToServer(localhost, port, Boolean.valueOf(false), 5 * 1000)) + .isThrownBy(() -> client.requestToServer(new HostAndPort(localhost.getHostName(), port), + Boolean.valueOf(false), 5 * 1000)) .withCauseInstanceOf(SSLHandshakeException.class) .withStackTraceContaining("No name matching " + localhost.getHostName() + " found"); } @@ -205,7 +208,8 @@ public void clientFailsToConnectIfServerCertificateWrongHostname() throws Except startServerAndClient(serverCertificate, clientCertificate, true); assertThatExceptionOfType(IllegalStateException.class) - .isThrownBy(() -> client.requestToServer(localhost, port, Boolean.valueOf(false), 5 * 1000)) + .isThrownBy(() -> client.requestToServer(new HostAndPort(localhost.getHostName(), port), + Boolean.valueOf(false), 5 * 1000)) .withCauseInstanceOf(SSLHandshakeException.class) .withStackTraceContaining("No subject alternative DNS name matching " + localhost.getHostName() + " found."); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java index 515321f76ff1..1a5eac5194c4 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/distributed/internal/tcpserver/TCPServerSSLJUnitTest.java @@ -109,7 +109,7 @@ public void teardown() throws ConnectException, InterruptedException { */ socketCreator.setFailTLSHandshake(false); - getTcpClient().stop(localhost, port); + getTcpClient().stop(new HostAndPort(localhost.getHostAddress(), port)); server.join(60 * 1000); @@ -121,7 +121,8 @@ public void testSSLSocketTimeOut() throws IOException, ClassNotFoundException { try { - getTcpClient().requestToServer(localhost, port, Boolean.valueOf(false), 5 * 1000); + getTcpClient().requestToServer(new HostAndPort(localhost.getHostAddress(), port), + Boolean.valueOf(false), 5 * 1000); throw new AssertionError("expected to get an exception but didn't"); } catch (final IllegalStateException | IOException t) { diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/net/ClientSocketFactoryIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/net/ClientSocketFactoryIntegrationTest.java index 7276dc46b6db..c35a59b3f2c5 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/internal/net/ClientSocketFactoryIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/net/ClientSocketFactoryIntegrationTest.java @@ -35,6 +35,7 @@ import org.apache.geode.distributed.ClientSocketFactory; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionConfigImpl; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.test.junit.categories.ClientServerTest; /** @@ -82,7 +83,8 @@ public void tearDown() throws Exception { @Test public void testClientSocketFactory() throws Exception { assertThatThrownBy(() -> this.socket = SocketCreatorFactory - .getSocketCreatorForComponent(CLUSTER).connectForClient("localhost", 12345, 0)) + .getSocketCreatorForComponent(CLUSTER).forClient() + .connect(new HostAndPort("localhost", 12345), 0)) .isExactlyInstanceOf(IOException.class).hasMessage(EXCEPTION_MESSAGE); assertThat(invokedCreateSocket).isTrue(); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java index 481313e43bf4..7f9f3f2f3fdd 100755 --- a/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/net/SSLSocketIntegrationTest.java @@ -72,6 +72,7 @@ import org.apache.geode.distributed.internal.DMStats; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionConfigImpl; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.ByteBufferOutputStream; import org.apache.geode.internal.inet.LocalHostUtil; import org.apache.geode.internal.security.SecurableCommunicationChannel; @@ -176,11 +177,12 @@ public void socketCreatorShouldUseSsl() throws Exception { @Test public void securedSocketTransmissionShouldWork() throws Exception { - this.serverSocket = this.socketCreator.createServerSocket(0, 0, this.localHost); + this.serverSocket = this.socketCreator.forCluster().createServerSocket(0, 0, this.localHost); this.serverThread = startServer(this.serverSocket, 15000); int serverPort = this.serverSocket.getLocalPort(); - this.clientSocket = this.socketCreator.connectForServer(this.localHost, serverPort); + this.clientSocket = this.socketCreator.forCluster() + .connect(new HostAndPort(this.localHost.getHostAddress(), serverPort), 0, null); // transmit expected string from Client to Server ObjectOutputStream output = new ObjectOutputStream(this.clientSocket.getOutputStream()); @@ -324,7 +326,7 @@ private void readMessageFromNIOSSLClient(Socket socket, ByteBuffer buffer, NioSs @Test(expected = SocketTimeoutException.class) public void handshakeCanTimeoutOnServer() throws Throwable { - this.serverSocket = this.socketCreator.createServerSocket(0, 0, this.localHost); + this.serverSocket = this.socketCreator.forCluster().createServerSocket(0, 0, this.localHost); this.serverThread = startServer(this.serverSocket, 1000); int serverPort = this.serverSocket.getLocalPort(); @@ -407,8 +409,9 @@ public void run() { try { await("connect to server socket").until(() -> { try { - Socket clientSocket = socketCreator.connectForClient( - LocalHostUtil.getLocalHost().getHostAddress(), serverSocketPort, 500); + Socket clientSocket = socketCreator.forClient().connect( + new HostAndPort(LocalHostUtil.getLocalHost().getHostAddress(), serverSocketPort), + 500); clientSocket.close(); System.err.println( "client successfully connected to server but should not have been able to do so"); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/GemFireStatSamplerIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/GemFireStatSamplerIntegrationTest.java index ffe275a85fa7..812856750725 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/GemFireStatSamplerIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/GemFireStatSamplerIntegrationTest.java @@ -34,7 +34,6 @@ import static org.apache.geode.internal.cache.control.HeapMemoryMonitor.getTenuredMemoryPoolMXBean; import static org.apache.geode.internal.cache.control.HeapMemoryMonitor.getTenuredPoolStatistics; import static org.apache.geode.internal.inet.LocalHostUtil.getLocalHost; -import static org.apache.geode.internal.net.SocketCreator.getHostName; import static org.apache.geode.internal.statistics.HostStatSampler.TEST_FILE_SIZE_LIMIT_IN_KB_PROPERTY; import static org.apache.geode.test.awaitility.GeodeAwaitility.await; import static org.assertj.core.api.Assertions.assertThat; @@ -136,7 +135,7 @@ public void testInitialization() throws Exception { .isLessThanOrEqualTo(currentTimeMillis()); assertThat(statSampler.getSystemDirectoryPath()) .as("system directory path") - .isEqualTo(getHostName(getLocalHost())); + .isEqualTo(getLocalHost().getHostName()); assertThat(statSampler.getVMStats()) .as("vm stats") diff --git a/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/SimpleStatSamplerIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/SimpleStatSamplerIntegrationTest.java index c8b7040c8f8a..ecfb5f301663 100755 --- a/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/SimpleStatSamplerIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/internal/statistics/SimpleStatSamplerIntegrationTest.java @@ -36,7 +36,6 @@ import org.apache.geode.Statistics; import org.apache.geode.StatisticsType; import org.apache.geode.internal.inet.LocalHostUtil; -import org.apache.geode.internal.net.SocketCreator; import org.apache.geode.internal.stats50.VMStats50; import org.apache.geode.test.junit.categories.StatisticsTest; @@ -100,7 +99,7 @@ public void testBasics() throws Exception { assertTrue(statsCount > 0); assertTrue(statSampler.getSystemStartTime() <= System.currentTimeMillis()); - assertEquals(SocketCreator.getHostName(LocalHostUtil.getLocalHost()), + assertEquals(LocalHostUtil.getLocalHost().getHostName(), statSampler.getSystemDirectoryPath()); VMStatsContract vmStats = statSampler.getVMStats(); diff --git a/geode-core/src/integrationTest/java/org/apache/geode/net/SSLSocketParameterExtensionIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/net/SSLSocketParameterExtensionIntegrationTest.java index 18c67d468abc..6f84f51120f3 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/net/SSLSocketParameterExtensionIntegrationTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/net/SSLSocketParameterExtensionIntegrationTest.java @@ -58,6 +58,7 @@ import org.apache.geode.cache.CacheFactory; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionConfigImpl; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.net.SocketCreator; import org.apache.geode.internal.net.SocketCreatorFactory; @@ -141,11 +142,12 @@ public void tearDown() throws Exception { @Test public void securedSocketCheckExtensions() throws Exception { - this.serverSocket = this.socketCreator.createServerSocket(0, 0, this.localHost); + this.serverSocket = this.socketCreator.forCluster().createServerSocket(0, 0, this.localHost); this.serverThread = startServer(this.serverSocket, 15000); int serverPort = this.serverSocket.getLocalPort(); - this.clientSocket = this.socketCreator.connectForServer(this.localHost, serverPort); + this.clientSocket = this.socketCreator.forCluster() + .connect(new HostAndPort(this.localHost.getHostAddress(), serverPort)); SSLSocket sslSocket = (SSLSocket) this.clientSocket; @@ -185,8 +187,9 @@ private Thread startServer(final ServerSocket serverSocket, int timeoutMillis) t Thread serverThread = new Thread(new MyThreadGroup(this.testName.getMethodName()), () -> { try { Socket socket = serverSocket.accept(); - SocketCreatorFactory.getSocketCreatorForComponent(CLUSTER).handshakeIfSocketIsSSL(socket, - timeoutMillis); + SocketCreatorFactory.getSocketCreatorForComponent(CLUSTER).forCluster() + .handshakeIfSocketIsSSL(socket, + timeoutMillis); assertThat(socket.getSoTimeout()).isEqualTo(0); ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); diff --git a/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorConfigImpl.java b/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorConfigImpl.java index 60dacb160a58..b735ca658d19 100644 --- a/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorConfigImpl.java +++ b/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorConfigImpl.java @@ -15,7 +15,6 @@ package org.apache.geode.admin.internal; import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; -import static org.apache.geode.internal.net.InetAddressUtilsWithLogging.toInetAddress; import static org.apache.geode.internal.net.InetAddressUtilsWithLogging.validateHost; import java.net.InetAddress; @@ -24,6 +23,7 @@ import org.apache.geode.GemFireConfigException; import org.apache.geode.admin.DistributionLocator; import org.apache.geode.admin.DistributionLocatorConfig; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.net.SocketCreatorFactory; @@ -65,8 +65,6 @@ public class DistributionLocatorConfigImpl extends ManagedEntityConfigImpl * Contacts a distribution locator on the given host and port and creates a * DistributionLocatorConfig for it. * - * @see TcpClient#getLocatorInfo - * * @return null if the locator cannot be contacted */ static DistributionLocatorConfig createConfigFor(String host, int port, InetAddress bindAddress) { @@ -78,9 +76,9 @@ static DistributionLocatorConfig createConfigFor(String host, int port, InetAddr InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()); if (bindAddress != null) { - info = client.getInfo(bindAddress, port); + info = client.getInfo(new HostAndPort(bindAddress.getHostAddress(), port)); } else { - info = client.getInfo(toInetAddress(host), port); + info = client.getInfo(new HostAndPort(host, port)); } if (info == null) { return null; diff --git a/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorImpl.java b/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorImpl.java index 419cf607e066..88669751d59f 100755 --- a/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorImpl.java +++ b/geode-core/src/main/java/org/apache/geode/admin/internal/DistributionLocatorImpl.java @@ -212,7 +212,8 @@ public boolean isRunning() { found = locator.getHost().getHostName().equals(inetAddr.getHostName()); if (!found) { found = - locator.getHost().getAddress().getHostAddress().equals(inetAddr.getHostAddress()); + locator.getHost().getSocketInetAddress().getAddress() + .getHostAddress().equals(inetAddr.getHostAddress()); } } catch (UnknownHostException e) { // try config host as if it is an IP address instead of host name diff --git a/geode-core/src/main/java/org/apache/geode/admin/internal/ManagedEntityConfigImpl.java b/geode-core/src/main/java/org/apache/geode/admin/internal/ManagedEntityConfigImpl.java index 540981abf209..37ed0fbd7847 100644 --- a/geode-core/src/main/java/org/apache/geode/admin/internal/ManagedEntityConfigImpl.java +++ b/geode-core/src/main/java/org/apache/geode/admin/internal/ManagedEntityConfigImpl.java @@ -25,7 +25,6 @@ import org.apache.geode.internal.GemFireVersion; import org.apache.geode.internal.admin.GemFireVM; import org.apache.geode.internal.inet.LocalHostUtil; -import org.apache.geode.internal.net.SocketCreator; /** * The abstract superclass of objects that configure a managed entity such as a GemFire cache server @@ -115,7 +114,7 @@ protected ManagedEntityConfigImpl() { * GemFireVM */ protected ManagedEntityConfigImpl(GemFireVM vm) { - this.host = SocketCreator.getHostName(vm.getHost()); + this.host = vm.getHost().getHostName(); this.workingDirectory = vm.getWorkingDirectory().getAbsolutePath(); this.productDirectory = vm.getGeodeHomeDir().getAbsolutePath(); this.remoteCommand = null; diff --git a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MX4JServerSocketFactory.java b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MX4JServerSocketFactory.java index ff7c2828f1c6..33f6eb83bd76 100644 --- a/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MX4JServerSocketFactory.java +++ b/geode-core/src/main/java/org/apache/geode/admin/jmx/internal/MX4JServerSocketFactory.java @@ -105,10 +105,11 @@ public MX4JServerSocketFactory(boolean useSSL, boolean needClientAuth, String pr public ServerSocket createServerSocket(int port, int backlog, String bindAddress) throws IOException { if ("".equals(bindAddress)) { - return socketCreator.createServerSocket(port, backlog); + return socketCreator.forCluster().createServerSocket(port, backlog); } else { - return socketCreator.createServerSocket(port, backlog, toInetAddress(bindAddress)); + return socketCreator.forCluster().createServerSocket(port, backlog, + toInetAddress(bindAddress)); } } @@ -120,9 +121,10 @@ public ServerSocket createServerSocket(int port, int backlog, String bindAddress public ServerSocket createServerSocket(int port) throws IOException { ServerSocket sock = null; if ("".equals(bindAddress)) { - sock = socketCreator.createServerSocket(port, this.backlog); + sock = socketCreator.forCluster().createServerSocket(port, this.backlog); } else { - sock = socketCreator.createServerSocket(port, this.backlog, toInetAddress(this.bindAddress)); + sock = socketCreator.forCluster().createServerSocket(port, this.backlog, + toInetAddress(this.bindAddress)); } if (logger.isDebugEnabled()) { diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java index 1714af33790d..94336f35ce38 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java +++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java @@ -49,7 +49,7 @@ import org.apache.geode.cache.client.internal.locator.ServerLocationRequest; import org.apache.geode.cache.client.internal.locator.ServerLocationResponse; import org.apache.geode.distributed.internal.ServerLocation; -import org.apache.geode.distributed.internal.tcpserver.LocatorAddress; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID; @@ -74,7 +74,7 @@ public class AutoConnectionSourceImpl implements ConnectionSource { private static final LocatorListRequest LOCATOR_LIST_REQUEST = new LocatorListRequest(); @Immutable - private static final Comparator SOCKET_ADDRESS_COMPARATOR = + private static final Comparator SOCKET_ADDRESS_COMPARATOR = (address, otherAddress) -> { InetSocketAddress inetSocketAddress = address.getSocketInetAddress(); InetSocketAddress otherInetSocketAddress = otherAddress.getSocketInetAddress(); @@ -92,7 +92,7 @@ public class AutoConnectionSourceImpl implements ConnectionSource { return inetSocketAddress.getPort() - otherInetSocketAddress.getPort(); } }; - private final List initialLocators; + private final List initialLocators; private final String serverGroup; private AtomicReference locators = new AtomicReference<>(); @@ -108,7 +108,7 @@ public class AutoConnectionSourceImpl implements ConnectionSource { */ private final Map locatorState = new HashMap<>(); - public AutoConnectionSourceImpl(List contacts, String serverGroup, + public AutoConnectionSourceImpl(List contacts, String serverGroup, int handshakeTimeout) { this.locators.set(new LocatorList(new ArrayList<>(contacts))); this.onlineLocators.set(new LocatorList(Collections.emptyList())); @@ -195,19 +195,19 @@ public List getOnlineLocators() { } - private ServerLocationResponse queryOneLocator(LocatorAddress locator, + private ServerLocationResponse queryOneLocator(HostAndPort locator, ServerLocationRequest request) { return queryOneLocatorUsingConnection(locator, request, tcpClient); } - ServerLocationResponse queryOneLocatorUsingConnection(LocatorAddress locator, + ServerLocationResponse queryOneLocatorUsingConnection(HostAndPort locator, ServerLocationRequest request, TcpClient locatorConnection) { Object returnObj = null; try { pool.getStats().incLocatorRequests(); - returnObj = locatorConnection.requestToServer(locator.getSocketInetAddress(), request, + returnObj = locatorConnection.requestToServer(locator, request, connectionTimeout, true); ServerLocationResponse response = (ServerLocationResponse) returnObj; pool.getStats().incLocatorResponses(); @@ -240,7 +240,7 @@ private ServerLocationResponse queryLocators(ServerLocationRequest request) { final boolean isDebugEnabled = logger.isDebugEnabled(); do { - LocatorAddress hostAddress = (LocatorAddress) controllerItr.next(); + HostAndPort hostAddress = (HostAndPort) controllerItr.next(); if (isDebugEnabled) { logger.debug("Sending query to locator {}: {}", hostAddress, request); } @@ -259,14 +259,13 @@ private void updateLocatorList(LocatorListResponse response) { isBalanced = response.isBalanced(); List locatorResponse = response.getLocators(); - List newLocatorAddresses = new ArrayList<>(locatorResponse.size()); - List newOnlineLocators = new ArrayList<>(locatorResponse.size()); + List newLocatorAddresses = new ArrayList<>(locatorResponse.size()); + List newOnlineLocators = new ArrayList<>(locatorResponse.size()); - Set badLocators = new HashSet<>(initialLocators); + Set badLocators = new HashSet<>(initialLocators); for (ServerLocation locator : locatorResponse) { - InetSocketAddress address = new InetSocketAddress(locator.getHostName(), locator.getPort()); - LocatorAddress hostAddress = new LocatorAddress(address, locator.getHostName()); + HostAndPort hostAddress = new HostAndPort(locator.getHostName(), locator.getPort()); newLocatorAddresses.add(hostAddress); newOnlineLocators.add(hostAddress); badLocators.remove(hostAddress); @@ -305,10 +304,10 @@ private void updateLocatorList(LocatorListResponse response) { * This method will add bad locator only when locator with hostname and port is not already in * list. */ - protected void addbadLocators(List newLocators, Set badLocators) { - for (LocatorAddress badloc : badLocators) { + protected void addbadLocators(List newLocators, Set badLocators) { + for (HostAndPort badloc : badLocators) { boolean addIt = true; - for (LocatorAddress goodloc : newLocators) { + for (HostAndPort goodloc : newLocators) { boolean isSameHost = badloc.getHostName().equals(goodloc.getHostName()); if (isSameHost && badloc.getPort() == goodloc.getPort()) { // ip has been changed so don't add this in current @@ -374,23 +373,23 @@ long getLocatorUpdateInterval() { * A list of locators, which remembers the last known good locator. */ private static class LocatorList { - protected final List locators; + protected final List locators; AtomicInteger currentLocatorIndex = new AtomicInteger(); - LocatorList(List locators) { + LocatorList(List locators) { locators.sort(SOCKET_ADDRESS_COMPARATOR); this.locators = Collections.unmodifiableList(locators); } public List getLocators() { List locs = new ArrayList<>(); - for (LocatorAddress la : locators) { + for (HostAndPort la : locators) { locs.add(la.getSocketInetAddress()); } return locs; } - List getLocatorAddresses() { + List getLocatorAddresses() { return locators; } @@ -398,7 +397,7 @@ public int size() { return locators.size(); } - public Iterator iterator() { + public Iterator iterator() { return new LocatorIterator(); } @@ -413,7 +412,7 @@ public String toString() { * controller. * */ - protected class LocatorIterator implements Iterator { + protected class LocatorIterator implements Iterator { private int startLocator = currentLocatorIndex.get(); private int locatorNum = 0; @@ -423,12 +422,12 @@ public boolean hasNext() { } @Override - public LocatorAddress next() { + public HostAndPort next() { if (!hasNext()) { return null; } else { int index = (locatorNum + startLocator) % locators.size(); - LocatorAddress nextLocator = locators.get(index); + HostAndPort nextLocator = locators.get(index); currentLocatorIndex.set(index); locatorNum++; return nextLocator; diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java index c149a7207e7c..6409cdd5b050 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java +++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/ConnectionImpl.java @@ -32,6 +32,7 @@ import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.ServerLocation; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.cache.tier.ClientSideHandshake; import org.apache.geode.internal.cache.tier.CommunicationMode; import org.apache.geode.internal.cache.tier.sockets.ServerConnection; @@ -87,8 +88,10 @@ public ServerQueueStatus connect(EndpointManager endpointManager, ServerLocation ClientSideHandshake handshake, int socketBufferSize, int handshakeTimeout, int readTimeout, CommunicationMode communicationMode, GatewaySender sender, SocketCreator sc) throws IOException { - theSocket = sc.connectForClient(location.getHostName(), location.getPort(), handshakeTimeout, - socketBufferSize); + theSocket = + sc.forClient().connect(new HostAndPort(location.getHostName(), location.getPort()), + handshakeTimeout, + socketBufferSize); theSocket.setTcpNoDelay(true); theSocket.setSendBufferSize(socketBufferSize); diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java b/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java index 4e94a8d024a1..9f2abca9ba88 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java +++ b/geode-core/src/main/java/org/apache/geode/cache/client/internal/PoolImpl.java @@ -28,6 +28,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import org.apache.logging.log4j.Logger; @@ -54,7 +55,7 @@ import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.ServerLocation; -import org.apache.geode.distributed.internal.tcpserver.LocatorAddress; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.admin.ClientStatsManager; import org.apache.geode.internal.cache.EventID; import org.apache.geode.internal.cache.InternalCache; @@ -112,9 +113,9 @@ public class PoolImpl implements InternalPool { private final int subscriptionAckInterval; private final int subscriptionTimeoutMultiplier; private final String serverGroup; - private final List locatorAddresses; - private final List locators; - private final List servers; + private final List locatorAddresses; + private final List locators; + private final List servers; private final boolean startDisabled; private final boolean usedByGateway; private final int maxConnections; @@ -157,7 +158,7 @@ public class PoolImpl implements InternalPool { private final ThreadsMonitoring threadMonitoring; public static PoolImpl create(PoolManagerImpl pm, String name, Pool attributes, - List locatorAddresses, InternalDistributedSystem distributedSystem, + List locatorAddresses, InternalDistributedSystem distributedSystem, InternalCache cache, ThreadsMonitoring tMonitoring) { PoolImpl pool = new PoolImpl(pm, name, attributes, locatorAddresses, distributedSystem, cache, tMonitoring); @@ -187,7 +188,7 @@ private void finishCreate(PoolManagerImpl pm) { } protected PoolImpl(PoolManagerImpl pm, String name, Pool attributes, - List locatorAddresses, InternalDistributedSystem distributedSystem, + List locatorAddresses, InternalDistributedSystem distributedSystem, InternalCache cache, ThreadsMonitoring threadMonitoring) { this.pm = pm; this.name = name; @@ -224,8 +225,11 @@ protected PoolImpl(PoolManagerImpl pm, String name, Pool attributes, } serverGroup = attributes.getServerGroup(); multiuserSecureModeEnabled = attributes.getMultiuserAuthentication(); - locators = attributes.getLocators(); - servers = attributes.getServers(); + locators = attributes.getLocators().stream() + .map(x -> new HostAndPort(x.getHostName(), x.getPort())).collect(Collectors.toList()); + servers = attributes.getServers().stream() + .map(x -> new HostAndPort(x.getHostName(), x.getPort())).collect( + Collectors.toList()); startDisabled = ((PoolFactoryImpl.PoolAttributes) attributes).startDisabled || !pm.isNormal(); usedByGateway = ((PoolFactoryImpl.PoolAttributes) attributes).isGateway(); @@ -478,7 +482,7 @@ public boolean getMultiuserAuthentication() { @Override public List getLocators() { - return locators; + return locators.stream().map(x -> x.getSocketInetAddress()).collect(Collectors.toList()); } @Override @@ -488,7 +492,7 @@ public List getOnlineLocators() { @Override public List getServers() { - return servers; + return servers.stream().map(x -> x.getSocketInetAddress()).collect(Collectors.toList()); } public GatewaySender getGatewaySender() { diff --git a/geode-core/src/main/java/org/apache/geode/distributed/Locator.java b/geode-core/src/main/java/org/apache/geode/distributed/Locator.java index f7cf0d1f4fac..3d5df2aa2f4e 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/Locator.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/Locator.java @@ -23,7 +23,6 @@ import org.apache.geode.distributed.internal.InternalLocator; import org.apache.geode.internal.inet.LocalHostUtil; -import org.apache.geode.internal.net.SocketCreator; /** * Represents a distribution locator server that provides discovery information to members and @@ -386,7 +385,7 @@ public String asString() { Object ba = this.bindAddress; if (ba == null) { try { - ba = SocketCreator.getHostName(LocalHostUtil.getLocalHost()); + ba = LocalHostUtil.getLocalHost().getHostName(); } catch (java.net.UnknownHostException uh) { } } diff --git a/geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java b/geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java index f5860c920aaf..21accc1adcd1 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/LocatorLauncher.java @@ -60,6 +60,7 @@ import org.apache.geode.cache.client.internal.locator.LocatorStatusRequest; import org.apache.geode.cache.client.internal.locator.LocatorStatusResponse; import org.apache.geode.distributed.internal.InternalLocator; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.distributed.internal.tcpserver.TcpSocketCreator; import org.apache.geode.internal.DistributionLocator; @@ -324,7 +325,8 @@ private static LocatorStatusResponse statusLocator( InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()); - return (LocatorStatusResponse) client.requestToServer(bindAddress, port, + return (LocatorStatusResponse) client.requestToServer( + new HostAndPort(bindAddress == null ? null : bindAddress.getCanonicalHostName(), port), new LocatorStatusRequest(), timeout, true); } catch (ClassNotFoundException e) { throw new RuntimeException(e); diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java index 8a599baecfae..e039a2a2d5f9 100644 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java @@ -89,7 +89,6 @@ import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.internal.ConfigSource; import org.apache.geode.internal.inet.LocalHostUtil; -import org.apache.geode.internal.net.SocketCreator; import org.apache.geode.internal.process.ProcessLauncherContext; import org.apache.geode.internal.security.SecurableCommunicationChannel; import org.apache.geode.security.AuthTokenEnabledComponents; @@ -1777,7 +1776,7 @@ public String getStartLocator() { return bindAddress + "[" + startLocatorPort + "]"; } try { - return SocketCreator.getHostName(LocalHostUtil.getLocalHost()) + "[" + startLocatorPort + return LocalHostUtil.getLocalHost().getHostName() + "[" + startLocatorPort + "]"; } catch (UnknownHostException ignore) { // punt and use this.startLocator instead diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/InternalDistributedMember.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/InternalDistributedMember.java index ac2bf6b57eb6..37a1b979ae21 100755 --- a/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/InternalDistributedMember.java +++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/membership/InternalDistributedMember.java @@ -33,8 +33,6 @@ import org.apache.geode.InternalGemFireError; import org.apache.geode.annotations.Immutable; import org.apache.geode.annotations.VisibleForTesting; -import org.apache.geode.annotations.internal.MutableForTesting; -import org.apache.geode.cache.client.ServerConnectivityException; import org.apache.geode.distributed.DistributedMember; import org.apache.geode.distributed.DurableClientAttributes; import org.apache.geode.distributed.Role; @@ -66,11 +64,6 @@ public class InternalDistributedMember public static final MemberIdentifierFactoryImpl MEMBER_IDENTIFIER_FACTORY = new MemberIdentifierFactoryImpl(); - /** Retrieves an InetAddress given the provided hostname */ - @MutableForTesting - protected static HostnameResolver hostnameResolver = - (location) -> InetAddress.getByName(location.getHostName()); - private final MemberIdentifier memberIdentifier; @VisibleForTesting @@ -107,7 +100,7 @@ public InternalDistributedMember(InetAddress i, int membershipPort, boolean spli } private static String getHostName(InetAddress i) { - return SocketCreator.resolve_dns ? SocketCreator.getHostName(i) : i.getHostAddress(); + return SocketCreator.resolve_dns ? i.getHostName() : i.getHostAddress(); } /** @@ -145,7 +138,8 @@ public InternalDistributedMember(String i, int p) { /** * Creates a new InternalDistributedMember for use in notifying listeners in client - * caches. The version information in the ID is set to Version.CURRENT. + * caches. The version information in the ID is set to Version.CURRENT and the host name + * is left unresolved (DistributedMember doesn't expose the InetAddress). * * @param location the coordinates of the server */ @@ -153,23 +147,13 @@ public InternalDistributedMember(String i, int p) { public InternalDistributedMember(ServerLocation location) { memberIdentifier = MEMBER_IDENTIFIER_FACTORY.create( - MemberDataBuilder.newBuilder(getInetAddress(location), location.getHostName()) + MemberDataBuilder.newBuilderForLocalHost(location.getHostName()) .setMembershipPort(location.getPort()) .setNetworkPartitionDetectionEnabled(false) .setPreferredForCoordinator(true) .build()); } - private static InetAddress getInetAddress(ServerLocation location) { - final InetAddress addr; - try { - addr = hostnameResolver.getInetAddress(location); - } catch (UnknownHostException e) { - throw new ServerConnectivityException("Unable to resolve server location " + location, e); - } - return addr; - } - /** * Create a InternalDistributedMember referring to the current host (as defined by the given * string) with additional info including optional connection name and an optional unique string. @@ -267,10 +251,6 @@ public static InternalDistributedMember readEssentialData(DataInput in) return mbr; } - public static void setHostnameResolver(final HostnameResolver hostnameResolver) { - InternalDistributedMember.hostnameResolver = hostnameResolver; - } - /** * Returns this client member's durable attributes or null if no durable attributes were created. */ @@ -332,7 +312,7 @@ private void defaultToCurrentHost() { memberIdentifier.setProcessId(OSProcess.getId()); try { if (SocketCreator.resolve_dns) { - setHostName(SocketCreator.getHostName(LocalHostUtil.getLocalHost())); + setHostName(LocalHostUtil.getLocalHost().getHostName()); } else { setHostName(LocalHostUtil.getLocalHost().getHostAddress()); } diff --git a/geode-core/src/main/java/org/apache/geode/internal/AbstractConfig.java b/geode-core/src/main/java/org/apache/geode/internal/AbstractConfig.java index 75b0b16b53d3..37188fb4de52 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/AbstractConfig.java +++ b/geode-core/src/main/java/org/apache/geode/internal/AbstractConfig.java @@ -203,7 +203,7 @@ public String getAttribute(String name) { // on Windows getHostName on mcast addrs takes ~5 seconds addrName = addr.getHostAddress(); } else { - addrName = SocketCreator.getHostName(addr); + addrName = addr.getHostName(); } return addrName; } diff --git a/geode-core/src/main/java/org/apache/geode/internal/DSFIDFactory.java b/geode-core/src/main/java/org/apache/geode/internal/DSFIDFactory.java index 81ee359fcc99..993ad3ea056b 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/DSFIDFactory.java +++ b/geode-core/src/main/java/org/apache/geode/internal/DSFIDFactory.java @@ -96,6 +96,7 @@ import org.apache.geode.distributed.internal.membership.gms.messages.SuspectMembersMessage; import org.apache.geode.distributed.internal.membership.gms.messages.ViewAckMessage; import org.apache.geode.distributed.internal.streaming.StreamingOperation.StreamingReplyMessage; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.admin.ClientMembershipMessage; import org.apache.geode.internal.admin.remote.AddHealthListenerRequest; import org.apache.geode.internal.admin.remote.AddHealthListenerResponse; @@ -972,6 +973,7 @@ private void registerDSFIDTypes(DSFIDSerializer serializer) { serializer.registerDSFID(GATEWAY_SENDER_QUEUE_ENTRY_SYNCHRONIZATION_ENTRY, GatewaySenderQueueEntrySynchronizationOperation.GatewaySenderQueueEntrySynchronizationEntry.class); serializer.registerDSFID(ABORT_BACKUP_REQUEST, AbortBackupRequest.class); + serializer.registerDSFID(HOST_AND_PORT, HostAndPort.class); } /** diff --git a/geode-core/src/main/java/org/apache/geode/internal/DistributionLocator.java b/geode-core/src/main/java/org/apache/geode/internal/DistributionLocator.java index 82c0e26ae64e..2842794f5890 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/DistributionLocator.java +++ b/geode-core/src/main/java/org/apache/geode/internal/DistributionLocator.java @@ -27,6 +27,7 @@ import org.apache.geode.annotations.internal.MakeNotStatic; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.InternalLocator; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.net.SocketCreatorFactory; import org.apache.geode.internal.security.SecurableCommunicationChannel; @@ -73,8 +74,9 @@ public static void stop(InetAddress addr, int port) { new TcpClient(SocketCreatorFactory .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR), InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), - InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()).stop(addr, - port); + InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()) + .stop(new HostAndPort(addr.getHostName(), + port)); } catch (ConnectException ignore) { // must not be running } diff --git a/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java b/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java index 33a15a5e6c5d..75b7821118a7 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java +++ b/geode-core/src/main/java/org/apache/geode/internal/SystemAdmin.java @@ -79,6 +79,7 @@ import org.apache.geode.distributed.internal.HighPriorityAckedMessage; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.admin.remote.TailLogResponse; import org.apache.geode.internal.cache.DiskStoreImpl; @@ -261,8 +262,10 @@ public void locatorStop(File directory, String portOption, String addressOption, if (Thread.interrupted()) throw new InterruptedException(); InetAddress addr = null; // fix for bug 30810 - if (addressOption == null) + if (addressOption == null) { addressOption = ""; + } + addressOption = addressOption.trim(); if (!addressOption.equals("")) { // make sure its a valid ip address try { @@ -289,7 +292,7 @@ public void locatorStop(File directory, String portOption, String addressOption, if (portOption == null || portOption.trim().length() == 0) { port = info.getManagerPort(); } - if (addressOption.trim().length() == 0) { + if (addr == null) { addr = info.getManagerAddress(); } @@ -298,7 +301,7 @@ public void locatorStop(File directory, String portOption, String addressOption, .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR), InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()) - .stop(addr, port); + .stop(new HostAndPort(addr.getHostName(), port)); } catch (java.net.ConnectException ce) { System.out.println( "Unable to connect to Locator process. Possible causes are that an incorrect bind address/port combination was specified to the stop-locator command or the process is unresponsive."); diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/DistributionLocatorId.java b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/DistributionLocatorId.java index c6f0874890a5..a0526c057716 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/admin/remote/DistributionLocatorId.java +++ b/geode-core/src/main/java/org/apache/geode/internal/admin/remote/DistributionLocatorId.java @@ -16,21 +16,19 @@ package org.apache.geode.internal.admin.remote; import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.validator.routines.InetAddressValidator; import org.apache.geode.InternalGemFireException; import org.apache.geode.distributed.Locator; import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.inet.LocalHostUtil; -import org.apache.geode.internal.net.SocketCreator; /** * Identifies the host, port, and bindAddress a distribution locator is listening on. @@ -221,24 +219,15 @@ public int getPort() { * ipString Otherwise we create InetAddress each time. * **/ - public InetSocketAddress getHost() throws UnknownHostException { - if (this.hostname != null) { - boolean isIpString = InetAddressValidator.getInstance().isValid(this.hostname); - if (isIpString) { - if (this.host == null) { - this.host = InetAddress.getByName(this.hostname); - } - return new InetSocketAddress(this.host, this.port); - } - } - - if (this.hostname == null) { - if (this.host != null) { - return new InetSocketAddress(this.host, this.port); - } + public HostAndPort getHost() throws UnknownHostException { + if (host == null && hostname == null) { throw new UnknownHostException("locator ID has no hostname or resolved inet address"); } - return new InetSocketAddress(this.hostname, this.port); + String addr = hostname; + if (host != null) { + addr = host.getHostName(); + } + return new HostAndPort(addr, port); } /** returns the host name */ @@ -303,7 +292,7 @@ public String toString() { if (isMcastId()) { sb.append(this.host.getHostAddress()); } else { - sb.append(SocketCreator.getHostName(this.host)); + sb.append(this.host.getHostName()); } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java index 06ceb62dc1c4..3a1005221d74 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java @@ -249,7 +249,6 @@ import org.apache.geode.internal.lang.ThrowableUtils; import org.apache.geode.internal.logging.InternalLogWriter; import org.apache.geode.internal.monitoring.ThreadsMonitoring; -import org.apache.geode.internal.net.SocketCreator; import org.apache.geode.internal.offheap.MemoryAllocator; import org.apache.geode.internal.security.SecurityService; import org.apache.geode.internal.security.SecurityServiceFactory; @@ -2651,7 +2650,8 @@ public Set getCurrentServers() { if (result == null) { result = new HashSet<>(); } - result.add(new InetSocketAddress(serverLocation.getHostName(), serverLocation.getPort())); + result.add(InetSocketAddress.createUnresolved(serverLocation.getHostName(), + serverLocation.getPort())); } } if (result == null) { @@ -2747,7 +2747,7 @@ public Region createVMRegion(String name, RegionAttributes aR private PoolFactory createDefaultPF() { PoolFactory defaultPoolFactory = PoolManager.createFactory(); try { - String localHostName = SocketCreator.getHostName(LocalHostUtil.getLocalHost()); + String localHostName = LocalHostUtil.getLocalHost().getHostName(); defaultPoolFactory.addServer(localHostName, CacheServer.DEFAULT_PORT); } catch (UnknownHostException ex) { throw new IllegalStateException("Could not determine local host name", ex); @@ -2772,7 +2772,7 @@ private void addLocalHostAsServer(PoolFactory poolFactory) { if (poolFactoryImpl.getPoolAttributes().locators.isEmpty() && poolFactoryImpl.getPoolAttributes().servers.isEmpty()) { try { - String localHostName = SocketCreator.getHostName(LocalHostUtil.getLocalHost()); + String localHostName = LocalHostUtil.getLocalHost().getHostName(); poolFactoryImpl.addServer(localHostName, CacheServer.DEFAULT_PORT); } catch (UnknownHostException ex) { throw new IllegalStateException("Could not determine local host name", ex); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PoolFactoryImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PoolFactoryImpl.java index 09be55672f6c..51f3e5679c93 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/PoolFactoryImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PoolFactoryImpl.java @@ -17,19 +17,19 @@ import java.io.DataInput; import java.io.DataOutput; +import java.io.Externalizable; import java.io.IOException; -import java.net.InetAddress; +import java.io.ObjectInput; +import java.io.ObjectOutput; import java.net.InetSocketAddress; -import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import org.apache.logging.log4j.Logger; -import org.apache.geode.DataSerializable; import org.apache.geode.DataSerializer; import org.apache.geode.annotations.VisibleForTesting; import org.apache.geode.cache.CacheException; @@ -40,7 +40,7 @@ import org.apache.geode.cache.query.QueryService; import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.tcpserver.LocatorAddress; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.monitoring.ThreadsMonitoring; import org.apache.geode.logging.internal.log4j.api.LogService; import org.apache.geode.pdx.internal.TypeRegistry; @@ -58,7 +58,7 @@ public class PoolFactoryImpl implements InternalPoolFactory { */ private PoolAttributes attributes = new PoolAttributes(); - private final List locatorAddresses = new ArrayList<>(); + private final List locatorAddresses = new ArrayList<>(); /** * The cache that created this factory @@ -248,28 +248,6 @@ public PoolFactory setSubscriptionTimeoutMultiplier(int multiplier) { return this; } - private InetSocketAddress getInetSocketAddress(String host, int port) { - if (port == 0) { - throw new IllegalArgumentException("port must be greater than 0 but was " + port); - // the rest of the port validation is done by InetSocketAddress - } - InetSocketAddress sockAddr; - try { - InetAddress hostAddr = InetAddress.getByName(host); - sockAddr = new InetSocketAddress(hostAddr, port); - } catch (UnknownHostException ignore) { - // IllegalArgumentException ex = new IllegalArgumentException("Unknown host " + host); - // ex.initCause(cause); - // throw ex; - // Fix for #45348 - logger.warn( - "Hostname is unknown: {}. Creating pool with unknown host in case the host becomes known later.", - host); - sockAddr = new InetSocketAddress(host, port); - } - return sockAddr; - } - @Override public PoolFactory setSubscriptionAckInterval(int ackInterval) { if (ackInterval <= 0) { @@ -286,9 +264,10 @@ public PoolFactory addLocator(String host, int port) { throw new IllegalStateException( "A server has already been added. You can only add locators or servers; not both."); } - InetSocketAddress isa = getInetSocketAddress(host, port); - attributes.locators.add(isa); - locatorAddresses.add(new LocatorAddress(isa, host)); + validatePort(port); + HostAndPort address = new HostAndPort(host, port); + attributes.locators.add(address); + locatorAddresses.add(address); return this; } @@ -298,10 +277,17 @@ public PoolFactory addServer(String host, int port) { throw new IllegalStateException( "A locator has already been added. You can only add locators or servers; not both."); } - attributes.servers.add(getInetSocketAddress(host, port)); + validatePort(port); + attributes.servers.add(new HostAndPort(host, port)); return this; } + private void validatePort(int port) { + if (port <= 0) { + throw new IllegalArgumentException("port must be greater than 0 but was " + port); + } + } + @Override public PoolFactory reset() { // preserve the startDisabled across resets @@ -332,10 +318,11 @@ public void init(Pool cp) { setSubscriptionAckInterval(cp.getSubscriptionAckInterval()); setServerGroup(cp.getServerGroup()); setMultiuserAuthentication(cp.getMultiuserAuthentication()); - for (InetSocketAddress inetSocketAddress : cp.getLocators()) { - addLocator(inetSocketAddress.getHostName(), inetSocketAddress.getPort()); + for (InetSocketAddress address : cp.getLocators()) { + addLocator(address.getHostName(), address.getPort()); } - attributes.servers.addAll(cp.getServers()); + attributes.servers.addAll(cp.getServers().stream() + .map(x -> new HostAndPort(x.getHostName(), x.getPort())).collect(Collectors.toList())); } public void init(GatewaySender sender) { @@ -405,7 +392,7 @@ public int hashCode() { /** * Not a true pool just the attributes. Serialization is used by unit tests */ - public static class PoolAttributes implements Pool, DataSerializable { + public static class PoolAttributes implements Pool, Externalizable { private static final long serialVersionUID = 1L; // for findbugs @@ -430,8 +417,8 @@ public static class PoolAttributes implements Pool, DataSerializable { int subscriptionTimeoutMultipler = DEFAULT_SUBSCRIPTION_TIMEOUT_MULTIPLIER; public String serverGroup = DEFAULT_SERVER_GROUP; boolean multiuserSecureModeEnabled = DEFAULT_MULTIUSER_AUTHENTICATION; - public ArrayList locators = new ArrayList<>(); - public ArrayList servers = new ArrayList<>(); + public ArrayList locators = new ArrayList<>(); + public ArrayList servers = new ArrayList<>(); public transient boolean startDisabled = false; // only used by junit tests public transient LocatorDiscoveryCallback locatorCallback = null; // only used by tests public GatewaySender gatewaySender = null; @@ -567,7 +554,7 @@ public List getLocators() { throw new IllegalStateException( "At least one locator or server must be added before a connection pool can be created."); } - return Collections.unmodifiableList(new ArrayList<>(locators)); + return locators.stream().map(x -> x.getSocketInetAddress()).collect(Collectors.toList()); } @Override @@ -582,7 +569,7 @@ public List getServers() { "At least one locator or server must be added before a connection pool can be created."); } // needs to return a copy. - return Collections.unmodifiableList(new ArrayList<>(servers)); + return servers.stream().map(x -> x.getSocketInetAddress()).collect(Collectors.toList()); } @Override @@ -616,7 +603,6 @@ public int getPendingEventCount() { } - @Override public void toData(DataOutput out) throws IOException { DataSerializer.writePrimitiveInt(connectionTimeout, out); DataSerializer.writePrimitiveInt(connectionLifetime, out); @@ -639,7 +625,6 @@ public void toData(DataOutput out) throws IOException { DataSerializer.writePrimitiveInt(socketConnectTimeout, out); } - @Override public void fromData(DataInput in) throws IOException, ClassNotFoundException { connectionTimeout = DataSerializer.readPrimitiveInt(in); connectionLifetime = DataSerializer.readPrimitiveInt(in); @@ -703,5 +688,15 @@ public boolean equals(Object o) { && Objects.equals(locatorCallback, that.locatorCallback) && Objects.equals(gatewaySender, that.gatewaySender); } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + toData(out); + } + + @Override + public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { + fromData(in); + } } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistentMemberPattern.java b/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistentMemberPattern.java index 1b9d56a28f99..db0726e48027 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistentMemberPattern.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistentMemberPattern.java @@ -22,7 +22,6 @@ import org.apache.geode.DataSerializer; import org.apache.geode.cache.persistence.PersistentID; -import org.apache.geode.internal.net.SocketCreator; /** * Implementation of the public PersistentID. It holds the region, host, directory, and timestamp. @@ -96,7 +95,7 @@ public String toString() { result.append(diskStoreID); if (host != null) { result.append(" ["); - result.append(SocketCreator.getHostName(host)); + result.append(host.getHostName()); result.append(":"); result.append(directory); result.append(",revoked@").append(revokedTime); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java index b4a475e4f939..fe3f206b7101 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/AcceptorImpl.java @@ -365,7 +365,6 @@ public class AcceptorImpl implements Acceptor, Runnable { * @param maxThreads the maximum number of threads allowed in the server pool * @param securityService the SecurityService to use for authentication and authorization * - * @see SocketCreator#createServerSocket(int, int, InetAddress) * @see ClientHealthMonitor * * @since GemFire 5.7 @@ -512,7 +511,7 @@ public class AcceptorImpl implements Acceptor, Runnable { final long tilt = System.currentTimeMillis() + timeLimitMillis; if (isSelector()) { - if (socketCreator.useSSL()) { + if (socketCreator.forCluster().useSSL()) { throw new IllegalArgumentException( "Selector thread pooling can not be used with client/server SSL. The selector can be disabled by setting max-threads=0."); } @@ -1545,7 +1544,7 @@ private boolean handOffQueueInitialization(Socket socket, CommunicationMode comm private CommunicationMode getCommunicationModeForNonSelector(Socket socket) throws IOException { socket.setSoTimeout(0); - socketCreator.handshakeIfSocketIsSSL(socket, acceptTimeout); + socketCreator.forCluster().handshakeIfSocketIsSSL(socket, acceptTimeout); byte communicationModeByte = (byte) socket.getInputStream().read(); if (communicationModeByte == -1) { throw new EOFException(); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java index 64eaa1c83217..7a196c7e268c 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdater.java @@ -59,6 +59,7 @@ import org.apache.geode.distributed.internal.InternalDistributedSystem.DisconnectListener; import org.apache.geode.distributed.internal.ServerLocation; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.Assert; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.InternalInstantiator; @@ -315,7 +316,8 @@ public CacheClientUpdater(String name, ServerLocation location, boolean primary, int socketBufferSize = Integer.getInteger("BridgeServer.SOCKET_BUFFER_SIZE", DEFAULT_SOCKET_BUFFER_SIZE); - mySock = socketCreator.connectForClient(location.getHostName(), location.getPort(), + mySock = socketCreator.forClient().connect( + new HostAndPort(location.getHostName(), location.getPort()), handshakeTimeout, socketBufferSize); mySock.setTcpNoDelay(true); mySock.setSendBufferSize(socketBufferSize); diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java index dfcc6dcab7a4..b22d05361a23 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/wan/AbstractGatewaySender.java @@ -791,7 +791,7 @@ protected void waitForRunningStatus() { synchronized (this.eventProcessor.getRunningStateLock()) { while (this.eventProcessor.getException() == null && this.eventProcessor.isStopped()) { try { - this.eventProcessor.getRunningStateLock().wait(); + this.eventProcessor.getRunningStateLock().wait(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SCAdvancedSocketCreator.java b/geode-core/src/main/java/org/apache/geode/internal/net/SCAdvancedSocketCreator.java new file mode 100644 index 000000000000..4879e60676fe --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/net/SCAdvancedSocketCreator.java @@ -0,0 +1,119 @@ +/* + * 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.internal.net; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; + +import javax.net.SocketFactory; + +import org.apache.geode.GemFireConfigException; +import org.apache.geode.SystemConnectException; +import org.apache.geode.distributed.internal.tcpserver.AdvancedSocketCreatorImpl; +import org.apache.geode.distributed.internal.tcpserver.ConnectionWatcher; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; + +class SCAdvancedSocketCreator extends AdvancedSocketCreatorImpl { + final SocketCreator coreSocketCreator; + + protected SCAdvancedSocketCreator(SocketCreator socketCreator) { + super(socketCreator); + coreSocketCreator = socketCreator; + } + + @Override + public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { + coreSocketCreator.handshakeIfSocketIsSSL(socket, timeout); + } + + @Override + public Socket connect(HostAndPort addr, int timeout, + ConnectionWatcher optionalWatcher, boolean allowClientSocketFactory, int socketBufferSize, + boolean useSSL) throws IOException { + + coreSocketCreator.printConfig(); + + if (!useSSL) { + return super.connect(addr, timeout, optionalWatcher, allowClientSocketFactory, + socketBufferSize, + useSSL); + } + + // create an SSL connection + + Socket socket; + InetSocketAddress sockaddr = addr.getSocketInetAddress(); + if (sockaddr.getAddress() == null) { + InetAddress address = InetAddress.getByName(sockaddr.getHostName()); + sockaddr = new InetSocketAddress(address, sockaddr.getPort()); + } + + if (coreSocketCreator.getSslContext() == null) { + throw new GemFireConfigException( + "SSL not configured correctly, Please look at previous error"); + } + SocketFactory sf = coreSocketCreator.getSslContext().getSocketFactory(); + socket = sf.createSocket(); + + // Optionally enable SO_KEEPALIVE in the OS network protocol. + socket.setKeepAlive(ENABLE_TCP_KEEP_ALIVE); + + // If necessary, set the receive buffer size before connecting the + // socket so that large buffers will be allocated on accepted sockets + // (see java.net.Socket.setReceiverBufferSize javadocs for details) + if (socketBufferSize != -1) { + socket.setReceiveBufferSize(socketBufferSize); + } + + try { + if (optionalWatcher != null) { + optionalWatcher.beforeConnect(socket); + } + socket.connect(sockaddr, Math.max(timeout, 0)); + coreSocketCreator.configureClientSSLSocket(socket, timeout); + return socket; + + } finally { + if (optionalWatcher != null) { + optionalWatcher.afterConnect(socket); + } + } + } + + @Override + protected RuntimeException problemCreatingSocketInPortRangeException(String s, IOException e) { + return new GemFireConfigException(s, e); + } + + @Override + protected RuntimeException noFreePortException(String reason) { + return new SystemConnectException(reason); + } + + @Override + protected Socket createCustomClientSocket(HostAndPort addr) throws IOException { + if (coreSocketCreator.getClientSocketFactory() != null) { + InetSocketAddress inetSocketAddress = addr.getSocketInetAddress(); + return coreSocketCreator.getClientSocketFactory().createSocket(inetSocketAddress.getAddress(), + inetSocketAddress.getPort()); + } + return null; + } + + + +} diff --git a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/HostAddress.java b/geode-core/src/main/java/org/apache/geode/internal/net/SCClientSocketCreator.java similarity index 58% rename from geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/HostAddress.java rename to geode-core/src/main/java/org/apache/geode/internal/net/SCClientSocketCreator.java index 3edde3b72088..01afdfb8425e 100644 --- a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/membership/HostAddress.java +++ b/geode-core/src/main/java/org/apache/geode/internal/net/SCClientSocketCreator.java @@ -12,16 +12,24 @@ * or implied. See the License for the specific language governing permissions and limitations under * the License. */ -package org.apache.geode.distributed.internal.membership.gms.membership; +package org.apache.geode.internal.net; -import java.net.InetSocketAddress; +import java.io.IOException; +import java.net.Socket; -import org.apache.geode.distributed.internal.tcpserver.LocatorAddress; +import org.apache.geode.distributed.internal.tcpserver.ClientSocketCreatorImpl; -public class HostAddress extends LocatorAddress { +class SCClientSocketCreator extends ClientSocketCreatorImpl { + private final SocketCreator coreSocketCreator; - public HostAddress(InetSocketAddress loc, String locStr) { - super(loc, locStr); + protected SCClientSocketCreator(SocketCreator socketCreator) { + super(socketCreator); + coreSocketCreator = socketCreator; + } + + @Override + public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { + coreSocketCreator.handshakeIfSocketIsSSL(socket, timeout); } } diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SCServerSocketCreator.java b/geode-core/src/main/java/org/apache/geode/internal/net/SCServerSocketCreator.java new file mode 100644 index 000000000000..572b3301b8cb --- /dev/null +++ b/geode-core/src/main/java/org/apache/geode/internal/net/SCServerSocketCreator.java @@ -0,0 +1,109 @@ +/* + * 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.internal.net; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; + +import javax.net.ServerSocketFactory; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLServerSocket; + +import org.apache.geode.GemFireConfigException; +import org.apache.geode.distributed.internal.tcpserver.ServerSocketCreatorImpl; +import org.apache.geode.internal.admin.SSLConfig; +import org.apache.geode.net.SSLParameterExtension; + +class SCServerSocketCreator extends ServerSocketCreatorImpl { + private final SocketCreator coreSocketCreator; + + protected SCServerSocketCreator(SocketCreator socketCreator) { + super(socketCreator); + coreSocketCreator = socketCreator; + } + + @Override + public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { + coreSocketCreator.handshakeIfSocketIsSSL(socket, timeout); + } + + public ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, + int socketBufferSize) throws IOException { + return createServerSocket(nport, backlog, bindAddr, socketBufferSize, + coreSocketCreator.useSSL()); + } + + @Override + protected ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, + int socketBufferSize, boolean sslConnection) throws IOException { + coreSocketCreator.printConfig(); + if (!sslConnection) { + return super.createServerSocket(nport, backlog, bindAddr, socketBufferSize, sslConnection); + } + if (coreSocketCreator.getSslContext() == null) { + throw new GemFireConfigException( + "SSL not configured correctly, Please look at previous error"); + } + ServerSocketFactory ssf = coreSocketCreator.getSslContext().getServerSocketFactory(); + SSLServerSocket serverSocket = (SSLServerSocket) ssf.createServerSocket(); + serverSocket.setReuseAddress(true); + // If necessary, set the receive buffer size before binding the socket so + // that large buffers will be allocated on accepted sockets (see + // java.net.ServerSocket.setReceiverBufferSize javadocs) + if (socketBufferSize != -1) { + serverSocket.setReceiveBufferSize(socketBufferSize); + } + serverSocket.bind(new InetSocketAddress(bindAddr, nport), backlog); + finishServerSocket(serverSocket); + return serverSocket; + } + + /** + * Configure the SSLServerSocket based on this SocketCreator's settings. + */ + private void finishServerSocket(SSLServerSocket serverSocket) { + SSLConfig sslConfig = coreSocketCreator.getSslConfig(); + serverSocket.setUseClientMode(false); + if (sslConfig.isRequireAuth()) { + // serverSocket.setWantClientAuth( true ); + serverSocket.setNeedClientAuth(true); + } + serverSocket.setEnableSessionCreation(true); + + // restrict protocols + String[] protocols = sslConfig.getProtocolsAsStringArray(); + if (!"any".equalsIgnoreCase(protocols[0])) { + serverSocket.setEnabledProtocols(protocols); + } + // restrict ciphers + String[] ciphers = sslConfig.getCiphersAsStringArray(); + if (!"any".equalsIgnoreCase(ciphers[0])) { + serverSocket.setEnabledCipherSuites(ciphers); + } + + SSLParameterExtension sslParameterExtension = sslConfig.getSSLParameterExtension(); + if (sslParameterExtension != null) { + SSLParameters modifiedParams = + sslParameterExtension.modifySSLServerSocketParameters(serverSocket.getSSLParameters()); + serverSocket.setSSLParameters(modifiedParams); + } + + } + + +} diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java index 427e7584986f..8027dfda6c74 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java +++ b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java @@ -23,7 +23,6 @@ import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; -import java.net.SocketAddress; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; @@ -41,10 +40,7 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.concurrent.ConcurrentHashMap; -import javax.net.ServerSocketFactory; -import javax.net.SocketFactory; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; @@ -54,7 +50,6 @@ import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLProtocolException; -import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; @@ -64,15 +59,15 @@ import org.apache.logging.log4j.Logger; import org.apache.geode.GemFireConfigException; -import org.apache.geode.SystemConnectException; import org.apache.geode.SystemFailure; +import org.apache.geode.annotations.VisibleForTesting; import org.apache.geode.annotations.internal.MakeNotStatic; import org.apache.geode.cache.wan.GatewaySender; import org.apache.geode.cache.wan.GatewayTransportFilter; import org.apache.geode.distributed.ClientSocketFactory; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionConfigImpl; -import org.apache.geode.distributed.internal.tcpserver.ConnectionWatcher; +import org.apache.geode.distributed.internal.tcpserver.AdvancedSocketCreatorImpl; import org.apache.geode.distributed.internal.tcpserver.TcpSocketCreatorImpl; import org.apache.geode.internal.ClassPathLoader; import org.apache.geode.internal.admin.SSLConfig; @@ -88,31 +83,18 @@ /** - * Analyze configuration data (gemfire.properties) and configure sockets accordingly for SSL. + * SocketCreators are built using a SocketCreatorFactory using Geode distributed-system properties. + * They know how to properly configure sockets for TLS (SSL) communications and perform + * handshakes. Connection-initiation uses a HostAndPort instance that is similar to an + * InetSocketAddress. *

- * gemfire.useSSL = (true|false) default false.
- * gemfire.ssl.debug = (true|false) default false.
- * gemfire.ssl.needClientAuth = (true|false) default true.
- * gemfire.ssl.protocols = list of protocols
- * gemfire.ssl.ciphers = list of cipher suites
- *

- * The following may be included to configure the certificates used by the Sun Provider. - *

- * javax.net.ssl.trustStore = pathname
- * javax.net.ssl.trustStorePassword = password
- * javax.net.ssl.keyStore = pathname
- * javax.net.ssl.keyStorePassword = password
- *

- * Additional properties will be set as System properties to be available as needed by other - * provider implementations. + * SocketCreator also supports a client-socket-factory that is designated with the property + * gemfire.clientSocketFactory for use in creating client->server connections. */ public class SocketCreator extends TcpSocketCreatorImpl { private static final Logger logger = LogService.getLogger(); - @MakeNotStatic - private static final ConcurrentHashMap hostNames = new ConcurrentHashMap<>(); - /** * flag to force always using DNS (regardless of the fact that these lookups can hang) */ @@ -141,17 +123,11 @@ public class SocketCreator extends TcpSocketCreatorImpl { private boolean hostnameValidationDisabledLogShown = false; - /** - * context for SSL socket factories - */ private SSLContext sslContext; private final SSLConfig sslConfig; - /** - * A factory used to create client Sockets. - */ private ClientSocketFactory clientSocketFactory; /** @@ -159,20 +135,8 @@ public class SocketCreator extends TcpSocketCreatorImpl { * gemfire.setTcpKeepAlive java system property. If not set then GemFire will enable keep-alive on * server->client and p2p connections. */ - public static final boolean ENABLE_TCP_KEEP_ALIVE = TcpSocketCreatorImpl.ENABLE_TCP_KEEP_ALIVE; - - // ------------------------------------------------------------------------- - // Constructor - // ------------------------------------------------------------------------- - - /** - * Constructs new SocketCreator instance. - */ - public SocketCreator(final SSLConfig sslConfig) { - this.sslConfig = sslConfig; - initialize(); - } - + public static final boolean ENABLE_TCP_KEEP_ALIVE = + AdvancedSocketCreatorImpl.ENABLE_TCP_KEEP_ALIVE; // ------------------------------------------------------------------------- // Static instance accessors @@ -185,43 +149,29 @@ public static InetAddress getLocalHost() throws UnknownHostException { return LocalHostUtil.getLocalHost(); } - /** - * returns the host name for the given inet address, using a local cache of names to avoid dns - * hits and duplicate strings - */ - public static String getHostName(InetAddress addr) { - String result = hostNames.get(addr); - if (result == null) { - result = addr.getHostName(); - hostNames.put(addr, result); - } - return result; - } + // ------------------------------------------------------------------------- + // Constructor + // ------------------------------------------------------------------------- /** - * returns the host name for the given inet address, using a local cache of names to avoid dns - * hits and duplicate strings + * Constructs new SocketCreator instance. */ - public static String getCanonicalHostName(InetAddress addr, String hostName) { - String result = hostNames.get(addr); - if (result == null) { - hostNames.put(addr, hostName); - return hostName; - } - return result; + public SocketCreator(final SSLConfig sslConfig) { + this.sslConfig = sslConfig; + initialize(); } - /** - * Reset the hostNames caches - */ - public static void resetHostNameCache() { - hostNames.clear(); - } // ------------------------------------------------------------------------- // Initializers (change SocketCreator state) // ------------------------------------------------------------------------- + protected void initializeCreators() { + serverSocketCreator = new SCServerSocketCreator(this); + clientSocketCreator = new SCClientSocketCreator(this); + advancedSocketCreator = new SCAdvancedSocketCreator(this); + } + /** * Initialize this SocketCreator. *

@@ -230,7 +180,7 @@ public static void resetHostNameCache() { private void initialize() { try { try { - if (this.sslConfig.isEnabled() && sslContext == null) { + if (this.sslConfig.isEnabled() && getSslContext() == null) { sslContext = createAndConfigureSSLContext(); } } catch (Exception e) { @@ -425,10 +375,29 @@ private KeyManager[] getKeyManagers() throws KeyStoreException, IOException, return extendedKeyManagers; } + /** + * context for SSL socket factories + */ + @VisibleForTesting public SSLContext getSslContext() { return sslContext; } + /** + * A factory used to create client Sockets. + */ + public ClientSocketFactory getClientSocketFactory() { + return clientSocketFactory; + } + + public SSLConfig getSslConfig() { + return sslConfig; + } + + /** + * ExtendedAliasKeyManager supports use of certificate aliases in distributed system + * properties. + */ private static class ExtendedAliasKeyManager extends X509ExtendedKeyManager { private final X509ExtendedKeyManager delegate; @@ -519,197 +488,23 @@ private String getKeyAlias(final String keyType, final PrivateKey key) { } } - // ------------------------------------------------------------------------- - // Public methods - // ------------------------------------------------------------------------- - /** * Returns true if this SocketCreator is configured to use SSL. */ @Override - public boolean useSSL() { + protected boolean useSSL() { return this.sslConfig.isEnabled(); } - public ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, - List transportFilters, int socketBufferSize) throws IOException { - if (transportFilters.isEmpty()) { - return createServerSocket(nport, backlog, bindAddr, socketBufferSize); - } else { - printConfig(); - ServerSocket result = new TransportFilterServerSocket(transportFilters); - result.setReuseAddress(true); - // Set the receive buffer size before binding the socket so - // that large buffers will be allocated on accepted sockets (see - // java.net.ServerSocket.setReceiverBufferSize javadocs) - result.setReceiveBufferSize(socketBufferSize); - try { - result.bind(new InetSocketAddress(bindAddr, nport), backlog); - } catch (BindException e) { - BindException throwMe = new BindException( - String.format("Failed to create server socket on %s[%s]", bindAddr, nport)); - throwMe.initCause(e); - throw throwMe; - } - return result; - } - } - - public ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, - int socketBufferSize) throws IOException { - return createServerSocket(nport, backlog, bindAddr, socketBufferSize, sslConfig.isEnabled()); - } - - @Override - protected ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, - int socketBufferSize, boolean sslConnection) throws IOException { - printConfig(); - if (!sslConnection) { - return super.createServerSocket(nport, backlog, bindAddr, socketBufferSize, sslConnection); - } - if (this.sslContext == null) { - throw new GemFireConfigException( - "SSL not configured correctly, Please look at previous error"); - } - ServerSocketFactory ssf = this.sslContext.getServerSocketFactory(); - SSLServerSocket serverSocket = (SSLServerSocket) ssf.createServerSocket(); - serverSocket.setReuseAddress(true); - // If necessary, set the receive buffer size before binding the socket so - // that large buffers will be allocated on accepted sockets (see - // java.net.ServerSocket.setReceiverBufferSize javadocs) - if (socketBufferSize != -1) { - serverSocket.setReceiveBufferSize(socketBufferSize); - } - serverSocket.bind(new InetSocketAddress(bindAddr, nport), backlog); - finishServerSocket(serverSocket); - return serverSocket; - } - - /** - * Creates or bind server socket to a random port selected from tcp-port-range which is same as - * membership-port-range. - * - * - * @return Returns the new server socket. - * - */ - public ServerSocket createServerSocketUsingPortRange(InetAddress ba, int backlog, - boolean isBindAddress, boolean useNIO, int tcpBufferSize, int[] tcpPortRange) - throws IOException { - return createServerSocketUsingPortRange(ba, backlog, isBindAddress, useNIO, tcpBufferSize, - tcpPortRange, sslConfig.isEnabled()); - } - - @Override - protected RuntimeException problemCreatingSocketInPortRangeException(String s, IOException e) { - return new GemFireConfigException(s, e); - } - - @Override - protected RuntimeException noFreePortException(String reason) { - return new SystemConnectException(reason); - } - - /** - * Return a client socket. This method is used by client/server clients. - */ - public Socket connectForClient(String host, int port, int timeout) throws IOException { - return connect(InetAddress.getByName(host), port, timeout, null, true, -1); - } - - /** - * Return a client socket. This method is used by client/server clients. - */ - public Socket connectForClient(String host, int port, int timeout, int socketBufferSize) - throws IOException { - return connect(InetAddress.getByName(host), port, timeout, null, true, socketBufferSize); - } - - /** - * Return a client socket. This method is used by peers. - */ - public Socket connectForServer(InetAddress inetadd, int port) throws IOException { - return connect(inetadd, port, 0, null, false, -1); - } - - /** - * Return a client socket, timing out if unable to connect and timeout > 0 (millis). The parameter - * timeout is ignored if SSL is being used, as there is no timeout argument in the ssl - * socket factory - */ - public Socket connect(InetAddress inetadd, int port, int timeout, - ConnectionWatcher optionalWatcher, boolean clientSide, int socketBufferSize) - throws IOException { - return connect(inetadd, port, timeout, optionalWatcher, clientSide, socketBufferSize, - sslConfig.isEnabled()); - } - - /** - * Return a client socket, timing out if unable to connect and timeout > 0 (millis). The parameter - * timeout is ignored if SSL is being used, as there is no timeout argument in the ssl - * socket factory - */ - @Override - public Socket connect(InetAddress inetadd, int port, int timeout, - ConnectionWatcher optionalWatcher, boolean clientSide, int socketBufferSize, - boolean sslConnection) throws IOException { - - printConfig(); - - if (!sslConnection) { - return super.connect(inetadd, port, timeout, optionalWatcher, clientSide, socketBufferSize, - sslConnection); - } - - // create an SSL connection - - Socket socket; - SocketAddress sockaddr = new InetSocketAddress(inetadd, port); - if (this.sslContext == null) { - throw new GemFireConfigException( - "SSL not configured correctly, Please look at previous error"); - } - SocketFactory sf = this.sslContext.getSocketFactory(); - socket = sf.createSocket(); - - // Optionally enable SO_KEEPALIVE in the OS network protocol. - socket.setKeepAlive(ENABLE_TCP_KEEP_ALIVE); - - // If necessary, set the receive buffer size before connecting the - // socket so that large buffers will be allocated on accepted sockets - // (see java.net.Socket.setReceiverBufferSize javadocs for details) - if (socketBufferSize != -1) { - socket.setReceiveBufferSize(socketBufferSize); - } - - try { - if (optionalWatcher != null) { - optionalWatcher.beforeConnect(socket); - } - socket.connect(sockaddr, Math.max(timeout, 0)); - configureClientSSLSocket(socket, timeout); - return socket; - - } finally { - if (optionalWatcher != null) { - optionalWatcher.afterConnect(socket); - } - } - } - - @Override - protected Socket createCustomClientSocket(InetAddress inetadd, int port) throws IOException { - if (this.clientSocketFactory != null) { - return this.clientSocketFactory.createSocket(inetadd, port); - } - return null; - } + // ------------------------------------------------------------------------- + // Public methods + // ------------------------------------------------------------------------- /** * Returns an SSLEngine that can be used to perform TLS handshakes and communication */ public SSLEngine createSSLEngine(String hostName, int port) { - return sslContext.createSSLEngine(hostName, port); + return getSslContext().createSSLEngine(hostName, port); } /** @@ -803,7 +598,7 @@ private SSLParameters checkAndEnableHostnameValidation(SSLParameters sslParamete * * @param timeout the number of milliseconds allowed for the handshake to complete */ - public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { + void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { if (!(socket instanceof SSLSocket)) { return; } @@ -836,46 +631,48 @@ public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOExceptio } } - // ------------------------------------------------------------------------- - // Private implementation methods - // ------------------------------------------------------------------------- - /** - * Configure the SSLServerSocket based on this SocketCreator's settings. + * Create a server socket with the given transport filters.
+ * Note: This method is outside of the + * client/server/advanced interfaces because it references WAN classes that aren't + * available to them. */ - private void finishServerSocket(SSLServerSocket serverSocket) { - serverSocket.setUseClientMode(false); - if (this.sslConfig.isRequireAuth()) { - // serverSocket.setWantClientAuth( true ); - serverSocket.setNeedClientAuth(true); + public ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, + List transportFilters, int socketBufferSize) throws IOException { + if (transportFilters.isEmpty()) { + return ((SCServerSocketCreator) forCluster()) + .createServerSocket(nport, backlog, bindAddr, socketBufferSize, useSSL()); + } else { + printConfig(); + ServerSocket result = new TransportFilterServerSocket(transportFilters); + result.setReuseAddress(true); + // Set the receive buffer size before binding the socket so + // that large buffers will be allocated on accepted sockets (see + // java.net.ServerSocket.setReceiverBufferSize javadocs) + result.setReceiveBufferSize(socketBufferSize); + try { + result.bind(new InetSocketAddress(bindAddr, nport), backlog); + } catch (BindException e) { + BindException throwMe = new BindException( + String.format("Failed to create server socket on %s[%s]", bindAddr, nport)); + throwMe.initCause(e); + throw throwMe; + } + return result; } - serverSocket.setEnableSessionCreation(true); + } - // restrict protocols - String[] protocols = this.sslConfig.getProtocolsAsStringArray(); - if (!"any".equalsIgnoreCase(protocols[0])) { - serverSocket.setEnabledProtocols(protocols); - } - // restrict ciphers - String[] ciphers = this.sslConfig.getCiphersAsStringArray(); - if (!"any".equalsIgnoreCase(ciphers[0])) { - serverSocket.setEnabledCipherSuites(ciphers); - } - SSLParameterExtension sslParameterExtension = this.sslConfig.getSSLParameterExtension(); - if (sslParameterExtension != null) { - SSLParameters modifiedParams = - sslParameterExtension.modifySSLServerSocketParameters(serverSocket.getSSLParameters()); - serverSocket.setSSLParameters(modifiedParams); - } + // ------------------------------------------------------------------------- + // Private implementation methods + // ------------------------------------------------------------------------- - } /** * When a socket is accepted from a server socket, it should be passed to this method for SSL * configuration. */ - private void configureClientSSLSocket(Socket socket, int timeout) throws IOException { + void configureClientSSLSocket(Socket socket, int timeout) throws IOException { if (socket instanceof SSLSocket) { SSLSocket sslSocket = (SSLSocket) socket; @@ -934,7 +731,7 @@ private void configureClientSSLSocket(Socket socket, int timeout) throws IOExcep /** * Print current configured state to log. */ - private void printConfig() { + void printConfig() { if (!configShown && logger.isDebugEnabled()) { configShown = true; StringBuilder sb = new StringBuilder(); @@ -952,7 +749,6 @@ private void printConfig() { } } - protected void initializeClientSocketFactory() { this.clientSocketFactory = null; String className = @@ -980,5 +776,4 @@ public void initializeTransportFilterClientSocketFactory(GatewaySender sender) { this.clientSocketFactory = new TransportFilterSocketFactory() .setGatewayTransportFilters(sender.getGatewayTransportFilters()); } - } diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java index 8b0d91dce7c7..2e162648eead 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java +++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/HostStatSampler.java @@ -30,7 +30,6 @@ import org.apache.geode.internal.inet.LocalHostUtil; import org.apache.geode.internal.io.MainWithChildrenRollingFileHandler; import org.apache.geode.internal.logging.log4j.LogMarker; -import org.apache.geode.internal.net.SocketCreator; import org.apache.geode.internal.process.UncheckedPidUnavailableException; import org.apache.geode.internal.statistics.platform.OsStatisticsFactory; import org.apache.geode.internal.util.concurrent.StoppableCountDownLatch; @@ -153,7 +152,7 @@ public long getSystemStartTime() { @Override public String getSystemDirectoryPath() { try { - return SocketCreator.getHostName(LocalHostUtil.getLocalHost()); + return LocalHostUtil.getLocalHost().getHostName(); } catch (UnknownHostException ignore) { return ""; } diff --git a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java index d84c829e00ab..074da0223fdb 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java +++ b/geode-core/src/main/java/org/apache/geode/internal/statistics/StatArchiveWriter.java @@ -41,7 +41,6 @@ import org.apache.geode.internal.NanoTimer; import org.apache.geode.internal.inet.LocalHostUtil; import org.apache.geode.internal.logging.log4j.LogMarker; -import org.apache.geode.internal.net.SocketCreator; import org.apache.geode.logging.internal.log4j.api.LogService; import org.apache.geode.util.internal.GeodeGlossary; @@ -204,7 +203,7 @@ protected String getOSInfo() { protected String getMachineInfo() { String machineInfo = System.getProperty("os.arch"); try { - String hostName = SocketCreator.getHostName(LocalHostUtil.getLocalHost()); + String hostName = LocalHostUtil.getLocalHost().getHostName(); machineInfo += " " + hostName; } catch (UnknownHostException ignore) { } diff --git a/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java b/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java index a816895ae02c..6130420a98e3 100644 --- a/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java +++ b/geode-core/src/main/java/org/apache/geode/internal/tcp/TCPConduit.java @@ -255,7 +255,7 @@ public TCPConduit(Membership mgr, int port, InetAddress address, boolean isBindA conTable = connectionTableFactory.apply(this); this.socketCreator = socketCreator; - useSSL = socketCreator.useSSL(); + useSSL = socketCreator.forAdvancedUse().useSSL(); if (address == null) { localHostValidation.run(); @@ -366,8 +366,9 @@ private void createServerSocket() { try { if (serverPort <= 0) { - socket = socketCreator.createServerSocketUsingPortRange(bindAddress, - connectionRequestBacklog, isBindAddress, true, 0, tcpPortRange); + socket = socketCreator.forAdvancedUse().createServerSocketUsingPortRange(bindAddress, + connectionRequestBacklog, isBindAddress, true, 0, tcpPortRange, + socketCreator.forAdvancedUse().useSSL()); } else { ServerSocketChannel channel = ServerSocketChannel.open(); diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ContextAwareSSLRMIClientSocketFactory.java b/geode-core/src/main/java/org/apache/geode/management/internal/ContextAwareSSLRMIClientSocketFactory.java index cadb2b231548..55eeb6a031ea 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/ContextAwareSSLRMIClientSocketFactory.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/ContextAwareSSLRMIClientSocketFactory.java @@ -27,6 +27,7 @@ import javax.rmi.ssl.SslRMIClientSocketFactory; import org.apache.geode.annotations.Immutable; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.net.SSLConfigurationFactory; import org.apache.geode.internal.net.SocketCreator; @@ -54,7 +55,7 @@ public Socket createSocket(String host, int port) throws IOException { try { socketCreator = SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.JMX); - return socketCreator.connectForClient(host, port, 0); + return socketCreator.forClient().connect(new HostAndPort(host, port), 0); } catch (Exception exception) { try { // In gfsh the ssl config is stored within the GEODE_SSL_CONFIG_PROPERTIES system property. @@ -64,7 +65,7 @@ public Socket createSocket(String host, int port) throws IOException { SSLConfig sslConfig = SSLConfigurationFactory .getSSLConfigForComponent(gfProperties, SecurableCommunicationChannel.JMX); socketCreator = new SocketCreator(sslConfig); - return socketCreator.connectForClient(host, port, 0); + return socketCreator.forClient().connect(new HostAndPort(host, port), 0); } catch (Exception finalException) { // Back off and use the default factory (javax.net.ssl properties are used to configure // SSL). diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java b/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java index 2ce9a8010afe..cd87917ef0d3 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/JmxManagerLocatorRequest.java @@ -17,11 +17,10 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.util.Properties; import org.apache.geode.annotations.Immutable; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.admin.SSLConfig; @@ -77,8 +76,6 @@ public String toString() { */ public static JmxManagerLocatorResponse send(String locatorHost, int locatorPort, int msTimeout, Properties sslConfigProps) throws IOException, ClassNotFoundException { - InetAddress networkAddress = InetAddress.getByName(locatorHost); - InetSocketAddress inetSockAddr = new InetSocketAddress(networkAddress, locatorPort); // simply need to turn sslConfigProps into sslConfig for locator SSLConfig sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(sslConfigProps, @@ -87,7 +84,8 @@ public static JmxManagerLocatorResponse send(String locatorHost, int locatorPort TcpClient client = new TcpClient(socketCreator, InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()); - Object responseFromServer = client.requestToServer(inetSockAddr, SINGLETON, msTimeout, true); + Object responseFromServer = client.requestToServer(new HostAndPort(locatorHost, locatorPort), + SINGLETON, msTimeout, true); if (responseFromServer instanceof JmxManagerLocatorResponse) return (JmxManagerLocatorResponse) responseFromServer; diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java index f8d5319d57a8..247c5e536a6e 100755 --- a/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/ManagementAgent.java @@ -227,8 +227,8 @@ private void loadWebApplications() { SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.JMX); final SocketCreator locatorSocketCreator = SocketCreatorFactory .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR); - System.setProperty(PULSE_USESSL_MANAGER, jmxSocketCreator.useSSL() + ""); - System.setProperty(PULSE_USESSL_LOCATOR, locatorSocketCreator.useSSL() + ""); + System.setProperty(PULSE_USESSL_MANAGER, jmxSocketCreator.forClient().useSSL() + ""); + System.setProperty(PULSE_USESSL_LOCATOR, locatorSocketCreator.forClient().useSSL() + ""); serviceAttributes.put(HttpService.GEODE_SSLCONFIG_SERVLET_CONTEXT_PARAM, createSslProps()); @@ -326,7 +326,7 @@ private void configureAndStart() throws IOException { final SocketCreator socketCreator = SocketCreatorFactory.getSocketCreatorForComponent(SecurableCommunicationChannel.JMX); - final boolean ssl = socketCreator.useSSL(); + final boolean ssl = socketCreator.forClient().useSSL(); if (logger.isDebugEnabled()) { logger.debug("Starting jmx manager agent on port {}{}", port, @@ -513,7 +513,7 @@ public GemFireRMIServerSocketFactory(SocketCreator sc, InetAddress bindAddr) { @Override public ServerSocket createServerSocket(int port) throws IOException { - return this.sc.createServerSocket(port, TCPConduit.getBackLog(), this.bindAddr); + return this.sc.forCluster().createServerSocket(port, TCPConduit.getBackLog(), this.bindAddr); } } } diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeConnectionConfig.java b/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeConnectionConfig.java index 8cfbeb250873..183c91379d86 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeConnectionConfig.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/api/GeodeConnectionConfig.java @@ -34,6 +34,7 @@ import org.apache.geode.cache.execute.ResultCollector; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.admin.SSLConfig; @@ -107,7 +108,8 @@ private void setClientCache(ClientCache clientCache) { cmsInfo = null; for (InetSocketAddress locator : locators) { try { - cmsInfo = (ClusterManagementServiceInfo) client.requestToServer(locator, + cmsInfo = (ClusterManagementServiceInfo) client.requestToServer( + new HostAndPort(locator.getHostName(), locator.getPort()), new ClusterManagementServiceInfoRequest(), 1000, true); // do not try anymore if we found one that has cms running diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ClusterConfigurationStatusRetriever.java b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ClusterConfigurationStatusRetriever.java index 5e72d0d10758..bceb0fec0b74 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ClusterConfigurationStatusRetriever.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/configuration/utils/ClusterConfigurationStatusRetriever.java @@ -16,11 +16,11 @@ import java.io.IOException; -import java.net.InetAddress; import java.util.Properties; import java.util.Set; import org.apache.geode.distributed.LocatorLauncher; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.cache.persistence.PersistentMemberPattern; @@ -37,15 +37,14 @@ public static String fromLocator(String locatorHostName, int locatorPort, Proper throws ClassNotFoundException, IOException { final StringBuilder buffer = new StringBuilder(); - final InetAddress networkAddress = InetAddress.getByName(locatorHostName); - TcpClient client = new TcpClient( new SocketCreator(SSLConfigurationFactory.getSSLConfigForComponent(configProps, SecurableCommunicationChannel.LOCATOR)), InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()); + HostAndPort locatorAddress = new HostAndPort(locatorHostName, locatorPort); SharedConfigurationStatusResponse statusResponse = - (SharedConfigurationStatusResponse) client.requestToServer(networkAddress, locatorPort, + (SharedConfigurationStatusResponse) client.requestToServer(locatorAddress, new SharedConfigurationStatusRequest(), 10000, true); for (int i = 0; i < NUM_ATTEMPTS_FOR_SHARED_CONFIGURATION_STATUS; i++) { @@ -54,8 +53,8 @@ public static String fromLocator(String locatorHostName, int locatorPort, Proper || statusResponse.getStatus().equals( org.apache.geode.management.internal.configuration.domain.SharedConfigurationStatus.NOT_STARTED)) { statusResponse = - (SharedConfigurationStatusResponse) client.requestToServer(networkAddress, - locatorPort, new SharedConfigurationStatusRequest(), 10000, true); + (SharedConfigurationStatusResponse) client.requestToServer(locatorAddress, + new SharedConfigurationStatusRequest(), 10000, true); try { Thread.sleep(5000); } catch (InterruptedException e) { diff --git a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt index 3b2ed1737d1f..7b572ced7ccd 100644 --- a/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt +++ b/geode-core/src/main/resources/org/apache/geode/internal/sanctioned-geode-core-serializables.txt @@ -259,13 +259,6 @@ org/apache/geode/distributed/internal/deadlock/MessageDependencyMonitor$MessageK org/apache/geode/distributed/internal/direct/ShunnedMemberException,true,-6455664684151074915 org/apache/geode/distributed/internal/locks/DistributedMemberLock$LockReentryPolicy,false org/apache/geode/distributed/internal/locks/LockGrantorDestroyedException,true,-3540124531032570817 -org/apache/geode/distributed/internal/membership/api/MemberDisconnectedException,true,-3649273301807236514 -org/apache/geode/distributed/internal/membership/api/MemberShunnedException,true,-8453126202477831557 -org/apache/geode/distributed/internal/membership/api/MemberStartupException,true,6610743861046044144 -org/apache/geode/distributed/internal/membership/api/MembershipClosedException,true,6112938405434046127 -org/apache/geode/distributed/internal/membership/api/MembershipConfigurationException,true,5633602142465129621 -org/apache/geode/distributed/internal/membership/gms/membership/GMSJoinLeave$ViewAbandonedException,false -org/apache/geode/distributed/internal/membership/gms/messages/InstallViewMessage$messageType,false org/apache/geode/internal/ConfigSource,true,-4097017272431018553,description:java/lang/String,type:org/apache/geode/internal/ConfigSource$Type org/apache/geode/internal/ConfigSource$Type,false org/apache/geode/internal/CopyOnWriteHashSet,true,8591978652141659932 @@ -312,6 +305,7 @@ org/apache/geode/internal/cache/PartitionedRegionDataStore$CreateBucketResult,fa org/apache/geode/internal/cache/PartitionedRegionException,true,5113786059279106007 org/apache/geode/internal/cache/PartitionedRegionQueryEvaluator$MemberResultsList,false,isLastChunkReceived:boolean org/apache/geode/internal/cache/PartitionedRegionStatus,true,-6755318987122602065,numberOfLocalEntries:int +org/apache/geode/internal/cache/PoolFactoryImpl$PoolAttributes,true,1,connectionLifetime:int,connectionTimeout:int,gateway:boolean,gatewaySender:org/apache/geode/cache/wan/GatewaySender,idleTimeout:long,locators:java/util/ArrayList,maxConnections:int,minConnections:int,multiuserSecureModeEnabled:boolean,pingInterval:long,prSingleHopEnabled:boolean,queueAckInterval:int,queueEnabled:boolean,queueMessageTrackingTimeout:int,queueRedundancyLevel:int,readTimeout:int,retryAttempts:int,serverGroup:java/lang/String,servers:java/util/ArrayList,socketBufferSize:int,socketConnectTimeout:int,statisticInterval:int,subscriptionTimeoutMultipler:int,threadLocalConnections:boolean org/apache/geode/internal/cache/PrimaryBucketException,true,1 org/apache/geode/internal/cache/PutAllPartialResultException,true,2411654400733621071,result:org/apache/geode/internal/cache/PutAllPartialResultException$PutAllPartialResult org/apache/geode/internal/cache/PutAllPartialResultException$PutAllPartialResult,true,-2168767259323206954,firstCauseOfFailure:java/lang/Exception,firstFailedKey:java/lang/Object,succeededKeys:org/apache/geode/internal/cache/tier/sockets/VersionedObjectList,totalMapSize:int diff --git a/geode-core/src/test/java/org/apache/geode/cache/client/internal/PoolImplTest.java b/geode-core/src/test/java/org/apache/geode/cache/client/internal/PoolImplTest.java index 5487f427ec7b..80cade152897 100644 --- a/geode-core/src/test/java/org/apache/geode/cache/client/internal/PoolImplTest.java +++ b/geode-core/src/test/java/org/apache/geode/cache/client/internal/PoolImplTest.java @@ -37,7 +37,7 @@ import org.apache.geode.cache.client.internal.pooling.ConnectionManagerImpl; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.InternalDistributedSystem; -import org.apache.geode.distributed.internal.tcpserver.LocatorAddress; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.cache.PoolFactoryImpl; import org.apache.geode.internal.cache.PoolManagerImpl; @@ -154,7 +154,7 @@ private PoolImpl getPool(int retryAttemptsAttribute) { final ThreadsMonitoring tMonitoring = mock(ThreadsMonitoring.class); - return PoolImpl.create(poolManager, "pool", poolAttributes, new LinkedList(), + return PoolImpl.create(poolManager, "pool", poolAttributes, new LinkedList(), internalDistributedSystem, internalCache, tMonitoring); } diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/CacheServerImplTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/CacheServerImplTest.java index 4662276bc53a..361e68871cda 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/CacheServerImplTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/CacheServerImplTest.java @@ -36,6 +36,7 @@ import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.InternalDistributedSystem; import org.apache.geode.distributed.internal.ResourceEvent; +import org.apache.geode.distributed.internal.tcpserver.ClusterSocketCreator; import org.apache.geode.internal.cache.tier.Acceptor; import org.apache.geode.internal.cache.tier.OverflowAttributes; import org.apache.geode.internal.cache.tier.sockets.AcceptorBuilder; @@ -67,6 +68,8 @@ public void setUp() throws IOException { config = mock(DistributionConfig.class); securityService = mock(SecurityService.class); socketCreator = mock(SocketCreator.class); + ClusterSocketCreator ssc = mock(ClusterSocketCreator.class); + when(socketCreator.forCluster()).thenReturn(ssc); system = mock(InternalDistributedSystem.class); advisor = mock(CacheServerAdvisor.class); @@ -79,6 +82,8 @@ public void setUp() throws IOException { when(serverSocket.getLocalSocketAddress()).thenReturn(mock(SocketAddress.class)); when(socketCreator.createServerSocket(anyInt(), anyInt(), any(), any(), anyInt())) .thenReturn(serverSocket); + when(ssc.createServerSocket(anyInt(), anyInt(), any())) + .thenReturn(serverSocket); when(statisticsManager.createAtomicStatistics(any(), any())).thenReturn(mock(Statistics.class)); when(statisticsManager.createType(any(), any(), any())).thenReturn(mock(StatisticsType.class)); when(system.getConfig()).thenReturn(config); diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdaterJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdaterJUnitTest.java index d2572e9994d3..3cb9c6281d6e 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdaterJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/tier/sockets/CacheClientUpdaterJUnitTest.java @@ -31,6 +31,8 @@ import org.apache.geode.cache.client.internal.QueueManager; import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.distributed.internal.ServerLocation; +import org.apache.geode.distributed.internal.tcpserver.ClientSocketCreator; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.cache.tier.ClientSideHandshake; import org.apache.geode.internal.net.SocketCreator; import org.apache.geode.test.junit.categories.ClientSubscriptionTest; @@ -57,7 +59,9 @@ public void failureToConnectClosesStatistics() throws Exception { // engineer a failure to connect via SocketCreator SocketCreator socketCreator = mock(SocketCreator.class); - when(socketCreator.connectForClient(any(String.class), any(Integer.class), + ClientSocketCreator csc = mock(ClientSocketCreator.class); + when(socketCreator.forClient()).thenReturn(csc); + when(csc.connect(any(HostAndPort.class), any(Integer.class), any(Integer.class))).thenThrow(new SocketException("ouch")); // mock some stats that we can then use to ensure that they're closed when the problem occurs diff --git a/geode-core/src/test/java/org/apache/geode/internal/net/SocketCreatorJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/net/SocketCreatorJUnitTest.java index d37e043c46ab..9b8b99ade3c1 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/net/SocketCreatorJUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/net/SocketCreatorJUnitTest.java @@ -55,7 +55,7 @@ public void testConfigureServerSSLSocketSetsSoTimeout() throws Exception { final SSLSocket socket = mock(SSLSocket.class); final int timeout = 1938236; - socketCreator.handshakeIfSocketIsSSL(socket, timeout); + socketCreator.forCluster().handshakeIfSocketIsSSL(socket, timeout); verify(socket).setSoTimeout(timeout); } @@ -65,7 +65,7 @@ public void testConfigureServerPlainSocketDoesntSetSoTimeout() throws Exception final Socket socket = mock(Socket.class); final int timeout = 1938236; - socketCreator.handshakeIfSocketIsSSL(socket, timeout); + socketCreator.forCluster().handshakeIfSocketIsSSL(socket, timeout); verify(socket, never()).setSoTimeout(timeout); } @@ -85,10 +85,10 @@ private void testBindExceptionMessageFormatting(InetAddress inetAddress) throws ServerSocket serverSocket = null; try { - serverSocket = socketCreator.createServerSocket(11234, 10, inetAddress); + serverSocket = socketCreator.forCluster().createServerSocket(11234, 10, inetAddress); assertThatExceptionOfType(BindException.class).isThrownBy(() -> { // call twice on the same port to trigger exception - socketCreator.createServerSocket(11234, 10, inetAddress); + socketCreator.forCluster().createServerSocket(11234, 10, inetAddress); }).withMessageContaining("11234") .withMessageContaining(InetAddress.getLocalHost().getHostAddress()); } finally { diff --git a/geode-core/src/test/java/org/apache/geode/internal/tcp/TCPConduitTest.java b/geode-core/src/test/java/org/apache/geode/internal/tcp/TCPConduitTest.java index 33c6ea1a159a..edd081d98d1d 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/tcp/TCPConduitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/tcp/TCPConduitTest.java @@ -45,6 +45,7 @@ import org.apache.geode.distributed.internal.direct.DirectChannel; import org.apache.geode.distributed.internal.membership.InternalDistributedMember; import org.apache.geode.distributed.internal.membership.api.Membership; +import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.inet.LocalHostUtil; import org.apache.geode.internal.net.SocketCreator; @@ -64,7 +65,7 @@ public void setUp() throws Exception { membership = cast(mock(Membership.class)); directChannel = mock(DirectChannel.class); connectionTable = mock(ConnectionTable.class); - socketCreator = mock(SocketCreator.class); + socketCreator = new SocketCreator(new SSLConfig.Builder().build()); localHost = LocalHostUtil.getLocalHost(); when(directChannel.getDM()) diff --git a/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestBase.java b/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestBase.java index 3c4b627b15f5..529ac8703dea 100644 --- a/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestBase.java +++ b/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestBase.java @@ -199,7 +199,8 @@ public void closeDurableClient() { public void disconnectDurableClient(boolean keepAlive) { printClientProxyState("Before"); - this.durableClientVM.invoke(() -> CacheServerTestUtil.closeCache(keepAlive)); + this.durableClientVM.invoke("close durable client cache", + () -> CacheServerTestUtil.closeCache(keepAlive)); await() .until(CacheServerTestUtil::getCache, nullValue()); printClientProxyState("after"); diff --git a/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestCase.java b/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestCase.java index 24073d6e809d..b4ce7c7c247e 100755 --- a/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestCase.java +++ b/geode-cq/src/distributedTest/java/org/apache/geode/internal/cache/tier/sockets/DurableClientTestCase.java @@ -311,6 +311,13 @@ public void testStartStopStartDurableClientUpdate() { // Verify the durable client received the updates this.checkListenerEvents(1, 1, -1, this.durableClientVM); + server1VM.invoke("wait for client acknowledgement", () -> { + CacheClientProxy proxy = getClientProxy(); + await().untilAsserted( + () -> assertThat(proxy._messageDispatcher._messageQueue.stats.getEventsRemoved()) + .isGreaterThan(0)); + }); + // Stop the durable client this.disconnectDurableClient(true); @@ -324,12 +331,10 @@ public void testStartStopStartDurableClientUpdate() { this.server1VM.invoke(new CacheSerializableRunnable("Verify durable client") { @Override public void run2() throws CacheException { - // Find the proxy CacheClientProxy proxy = getClientProxy(); assertThat(proxy).isNotNull(); - // Verify the queue size - assertThat(1).isEqualTo(proxy.getQueueSize()); + assertThat(proxy.getQueueSize()).isEqualTo(1); } }); diff --git a/geode-dunit/src/main/java/org/apache/geode/cache/client/internal/LocatorTestBase.java b/geode-dunit/src/main/java/org/apache/geode/cache/client/internal/LocatorTestBase.java index 340fd3e61804..3de2162b699a 100644 --- a/geode-dunit/src/main/java/org/apache/geode/cache/client/internal/LocatorTestBase.java +++ b/geode-dunit/src/main/java/org/apache/geode/cache/client/internal/LocatorTestBase.java @@ -237,10 +237,12 @@ protected void startBridgeClientInVM(VM vm, final String group, final String hos protected void startBridgeClientInVM(VM vm, final String group, final String host, final int port, final String... regions) throws Exception { - PoolFactoryImpl pf = new PoolFactoryImpl(null); - pf.addLocator(host, port).setServerGroup(group).setPingInterval(200) - .setSubscriptionEnabled(true).setSubscriptionRedundancy(-1); - startBridgeClientInVM(vm, pf.getPoolAttributes(), regions); + vm.invoke(() -> { + PoolFactoryImpl pf = new PoolFactoryImpl(null); + pf.addLocator(host, port).setServerGroup(group).setPingInterval(200) + .setSubscriptionEnabled(true).setSubscriptionRedundancy(-1); + startBridgeClientInVM(null, pf.getPoolAttributes(), regions); + }); } protected void startBridgeClientInVM(VM vm, final Pool pool, final String... regions) diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java index 7799697721a6..992dd0f2ee5a 100644 --- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java +++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/rules/DistributedRule.java @@ -241,7 +241,6 @@ public static void tearDownInVM() { QueryObserverHolder.reset(); QueryTestUtils.setCache(null); RegionTestCase.preSnapshotRegion = null; - SocketCreator.resetHostNameCache(); SocketCreator.resolve_dns = true; TcpClient.clearStaticData(); 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/GMSUtilTest.java index f448aae38c34..4a1ed002f68c 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/GMSUtilTest.java @@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.net.InetAddress; -import java.net.InetSocketAddress; import java.util.List; import junitparams.JUnitParamsRunner; @@ -29,7 +28,7 @@ import org.junit.runner.RunWith; import org.apache.geode.distributed.internal.membership.api.MembershipConfigurationException; -import org.apache.geode.distributed.internal.membership.gms.membership.HostAddress; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; @RunWith(JUnitParamsRunner.class) public class GMSUtilTest { @@ -49,8 +48,7 @@ public void resolveableLoopBackAddress() throws MembershipConfigurationException parseLocators(RESOLVEABLE_LOOPBACK_HOST + "[" + PORT + "]", InetAddress.getLoopbackAddress())) .contains( - new HostAddress(new InetSocketAddress(RESOLVEABLE_LOOPBACK_HOST, PORT), - RESOLVEABLE_LOOPBACK_HOST)); + new HostAndPort(RESOLVEABLE_LOOPBACK_HOST, PORT)); } @Test @@ -73,11 +71,10 @@ public void unresolveableAddress() { @Test public void unresolveableAddressNotChecked() throws MembershipConfigurationException { - final List hostAddresses = + final List HostAndPortes = parseLocators(UNRESOLVEABLE_HOST + "[" + PORT + "]", (InetAddress) null); - assertThat(hostAddresses) - .contains(new HostAddress(new InetSocketAddress(UNRESOLVEABLE_HOST, PORT), - UNRESOLVEABLE_HOST)); + assertThat(HostAndPortes) + .contains(new HostAndPort(UNRESOLVEABLE_HOST, PORT)); } @Test @@ -86,8 +83,7 @@ public void validPortSpecified(final int validPort) throws MembershipConfigurati final String locatorsString = RESOLVEABLE_LOOPBACK_HOST + "[" + validPort + "]"; assertThat(parseLocators(locatorsString, InetAddress.getLoopbackAddress())) .contains( - new HostAddress(new InetSocketAddress(RESOLVEABLE_LOOPBACK_HOST, validPort), - RESOLVEABLE_LOOPBACK_HOST)); + new HostAndPort(RESOLVEABLE_LOOPBACK_HOST, validPort)); } @Test @@ -106,7 +102,7 @@ public void validHostSpecified(final String locatorsString) throws MembershipConfigurationException { assertThat(parseLocators(locatorsString, (InetAddress) null)) .contains( - new HostAddress(new InetSocketAddress("127.0.0.1", 1234), "127.0.0.1")); + new HostAndPort("127.0.0.1", 1234)); } @Test @@ -115,23 +111,20 @@ public void validIPV6AddySpecified(final String locatorsString) throws MembershipConfigurationException { assertThat(parseLocators(locatorsString, (InetAddress) null)) .contains( - new HostAddress(new InetSocketAddress("fdf0:76cf:a0ed:9449::5", 12233), - "fdf0:76cf:a0ed:9449::5")); + new HostAndPort("fdf0:76cf:a0ed:9449::5", 12233)); } @Test public void multipleHosts() throws MembershipConfigurationException { - final List addys = + final List addys = parseLocators( "geodecluster-sample-locator-0.geodecluster-sample-locator[10334]," + "geodecluster-sample-locator-1.geodecluster-sample-locator[10334]," + "geodecluster-sample-locator-2.geodecluster-sample-locator[10334]", (InetAddress) null); assertThat(addys).contains( - new HostAddress( - new InetSocketAddress("geodecluster-sample-locator-2.geodecluster-sample-locator", - 10334), - "geodecluster-sample-locator-2.geodecluster-sample-locator")); + new HostAndPort("geodecluster-sample-locator-2.geodecluster-sample-locator", + 10334)); assertThat(addys).hasSize(3); } @@ -149,12 +142,11 @@ public void multipleHostsWithBindAddress() throws MembershipConfigurationExcepti @Test public void nonLoopbackBindAddressDoesNotResolveLocatorAddress() throws MembershipConfigurationException { - final List hostAddresses = + final List hostAndPorts = parseLocators(UNRESOLVEABLE_HOST + "[" + PORT + "]", RESOLVEABLE_NON_LOOPBACK_HOST); - assertThat(hostAddresses) - .contains(new HostAddress(new InetSocketAddress(UNRESOLVEABLE_HOST, PORT), - UNRESOLVEABLE_HOST)); + assertThat(hostAndPorts) + .contains(new HostAndPort(UNRESOLVEABLE_HOST, PORT)); } } 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 e98dfdeb2c5c..c65f8efca19f 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 @@ -35,7 +35,6 @@ import java.io.IOException; import java.net.InetAddress; -import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -82,6 +81,7 @@ import org.apache.geode.distributed.internal.membership.gms.messages.RemoveMemberMessage; import org.apache.geode.distributed.internal.membership.gms.messages.ViewAckMessage; import org.apache.geode.distributed.internal.membership.gms.util.MemberIdentifierUtil; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.serialization.Version; import org.apache.geode.test.junit.categories.MembershipTest; @@ -211,7 +211,7 @@ public void testFindCoordinatorPausesWhenLocatorWaitTimeIsSet() throws Exception initMocks(false); when(mockConfig.getLocatorWaitTime()).thenReturn(15000); - when(locatorClient.requestToServer(isA(InetSocketAddress.class), + when(locatorClient.requestToServer(isA(HostAndPort.class), isA(FindCoordinatorRequest.class), anyInt(), anyBoolean())) .thenThrow(new IOException("Connection refused")); @@ -222,7 +222,7 @@ public void testFindCoordinatorPausesWhenLocatorWaitTimeIsSet() throws Exception .isInstanceOf(MemberStartupException.class) .hasMessageContaining("Interrupted while trying to contact locators"); assertThat(Thread.currentThread().interrupted()).isTrue(); - verify(locatorClient, times(1)).requestToServer(isA(InetSocketAddress.class), + verify(locatorClient, times(1)).requestToServer(isA(HostAndPort.class), isA(FindCoordinatorRequest.class), anyInt(), anyBoolean()); } @@ -429,7 +429,7 @@ public void testRemoveAndLeaveIsNotACrash() throws Exception { @Test public void multipleLocatorsWithSameAddressAreCanonicalized() throws Exception { - List locators = GMSUtil.parseLocators( + List locators = GMSUtil.parseLocators( "localhost[1234],localhost[1234],localhost[1234]", (InetAddress) null); assertThat(locators.size()).isEqualTo(1); } @@ -1428,7 +1428,7 @@ public void testCoordinatorFindRequestSuccess() throws Exception { FindCoordinatorResponse fcr = new FindCoordinatorResponse(mockMembers[0], mockMembers[0], false, null, registrants, false, true, null); - when(locatorClient.requestToServer(isA(InetSocketAddress.class), + when(locatorClient.requestToServer(isA(HostAndPort.class), isA(FindCoordinatorRequest.class), anyInt(), anyBoolean())) .thenReturn(fcr); @@ -1449,7 +1449,7 @@ public void testCoordinatorFindRequestFailure() throws Exception { JoinResponseMessage jrm = new JoinResponseMessage(mockMembers[0], view, 0); gmsJoinLeave.setJoinResponseMessage(jrm); - when(locatorClient.requestToServer(eq(new InetSocketAddress("localhost", 12346)), + when(locatorClient.requestToServer(eq(new HostAndPort("localhost", 12346)), isA(FindCoordinatorRequest.class), anyInt(), anyBoolean())) .thenReturn(fcr); 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 bba8f76a7970..b09cb4e81225 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 @@ -28,7 +28,7 @@ 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.gms.membership.HostAddress; +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; @@ -46,7 +46,7 @@ public class GMSUtil { * @param bindAddress optional address to check for loopback compatibility * @return addresses of locators */ - public static List parseLocators(String locatorsString, String bindAddress) + public static List parseLocators(String locatorsString, String bindAddress) throws MembershipConfigurationException { InetAddress addr = null; @@ -82,12 +82,10 @@ public static Set readHashSetOfMemberIDs(DataI * @param locatorsString a DistributionConfig "locators" string * @param bindAddress optional address to check for loopback compatibility * @return addresses of locators - * - * @see org.apache.geode.distributed.ConfigurationProperties#LOCATORS for format */ - public static List parseLocators(String locatorsString, InetAddress bindAddress) + public static List parseLocators(String locatorsString, InetAddress bindAddress) throws MembershipConfigurationException { - List result = new ArrayList<>(2); + List result = new ArrayList<>(2); Set inetAddresses = new HashSet<>(); String host; final boolean isLoopback = ((bindAddress != null) && bindAddress.isLoopbackAddress()); @@ -149,10 +147,10 @@ public static List parseLocators(String locatorsString, InetAddress } } - HostAddress la = new HostAddress(isa, host); + HostAndPort hostAndPort = new HostAndPort(host, port); if (!inetAddresses.contains(isa)) { inetAddresses.add(isa); - result.add(la); + result.add(hostAndPort); } } diff --git a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberDataBuilderImpl.java b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberDataBuilderImpl.java index b0eca8f666d4..377617530cc3 100644 --- a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberDataBuilderImpl.java +++ b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberDataBuilderImpl.java @@ -76,13 +76,13 @@ private MemberDataBuilderImpl(InetAddress hostAddress, String hostName) { this.hostName = hostName; } - private MemberDataBuilderImpl(String fakeHostName) { + private MemberDataBuilderImpl(String hostName) { try { inetAddress = LocalHostUtil.getLocalHost(); } catch (UnknownHostException e2) { throw new RuntimeException("Unable to resolve local host address", e2); } - hostName = fakeHostName; + this.hostName = hostName; } public MemberDataBuilderImpl setMembershipPort(int membershipPort) { diff --git a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberIdentifierImpl.java b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberIdentifierImpl.java index 2268b5a522be..d9553f6ce819 100644 --- a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberIdentifierImpl.java +++ b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/MemberIdentifierImpl.java @@ -436,9 +436,9 @@ public void addFixedToString(StringBuilder sb, boolean useIpAddress) { String host; InetAddress add = getInetAddress(); - if (add.isMulticastAddress() || useIpAddress) + if ((add != null) && (add.isMulticastAddress() || useIpAddress)) { host = add.getHostAddress(); - else { + } else { String hostName = memberData.getHostName(); InetAddressValidator inetAddressValidator = InetAddressValidator.getInstance(); boolean isIpAddress = inetAddressValidator.isValid(hostName); diff --git a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java index 803f4dedbfc3..bd95e5740410 100644 --- a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java +++ b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/fd/GMSHealthMonitor.java @@ -68,6 +68,7 @@ import org.apache.geode.distributed.internal.membership.gms.messages.SuspectMembersMessage; import org.apache.geode.distributed.internal.membership.gms.messages.SuspectRequest; import org.apache.geode.distributed.internal.tcpserver.ConnectionWatcher; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpSocketCreator; import org.apache.geode.internal.lang.JavaWorkarounds; import org.apache.geode.internal.serialization.Version; @@ -573,8 +574,8 @@ boolean doTCPCheckMember(ID suspectMember, int port, logger.debug("Checking member {} with TCP socket connection {}:{}.", suspectMember, suspectMember.getInetAddress(), port); clientSocket = - socketCreator - .connect(suspectMember.getInetAddress(), port, (int) memberTimeout, + socketCreator.forAdvancedUse() + .connect(new HostAndPort(suspectMember.getHostName(), port), (int) memberTimeout, new ConnectTimeoutTask(services.getTimer(), memberTimeout), false, -1, false); clientSocket.setTcpNoDelay(true); passed = doTCPCheckMember(suspectMember, clientSocket); @@ -680,7 +681,7 @@ public void start() throws MemberStartupException { } ServerSocket createServerSocket(InetAddress socketAddress, int[] portRange) throws IOException { - ServerSocket newSocket = socketCreator + ServerSocket newSocket = socketCreator.forAdvancedUse() .createServerSocketUsingPortRange(socketAddress, 50/* backlog */, true/* isBindAddress */, false/* useNIO */, 65536/* tcpBufferSize */, portRange, false); socketPort = newSocket.getLocalPort(); 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 eb2939bfc359..adf866069415 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 @@ -23,7 +23,6 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.InetAddress; -import java.net.InetSocketAddress; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; @@ -45,8 +44,8 @@ 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.membership.HostAddress; import org.apache.geode.distributed.internal.membership.gms.messenger.GMSMemberWrapper; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.distributed.internal.tcpserver.TcpHandler; import org.apache.geode.distributed.internal.tcpserver.TcpServer; @@ -73,7 +72,7 @@ public class GMSLocator implements Locator, Tcp private final boolean networkPartitionDetectionEnabled; private final String securityUDPDHAlgo; private final String locatorString; - private final List locators; + private final List locators; private final MembershipLocatorStatistics locatorStats; private final Set registrants = new HashSet<>(); private final Map publicKeys = @@ -412,8 +411,8 @@ private void recover() { } private boolean recoverFromOtherLocators() { - for (HostAddress other : locators) { - if (recover(other.getSocketInetAddress())) { + for (HostAndPort other : locators) { + if (recover(other)) { logger.info("Peer locator recovered state from {}", other); return true; } @@ -421,10 +420,10 @@ private boolean recoverFromOtherLocators() { return false; } - private boolean recover(InetSocketAddress other) { + private boolean recover(HostAndPort other) { try { logger.info("Peer locator attempting to recover from {}", other); - Object response = locatorClient.requestToServer(other.getAddress(), other.getPort(), + Object response = locatorClient.requestToServer(other, new GetViewRequest(), 20000, true); if (response instanceof GetViewResponse) { view = ((GetViewResponse) response).getView(); diff --git a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/MembershipLocatorImpl.java b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/MembershipLocatorImpl.java index 999e6cbff224..81f3e80d844c 100644 --- a/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/MembershipLocatorImpl.java +++ b/geode-membership/src/main/java/org/apache/geode/distributed/internal/membership/gms/locator/MembershipLocatorImpl.java @@ -37,6 +37,7 @@ import org.apache.geode.distributed.internal.membership.api.MembershipLocatorStatistics; import org.apache.geode.distributed.internal.membership.gms.GMSMembership; import org.apache.geode.distributed.internal.membership.gms.Services; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.ProtocolChecker; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.distributed.internal.tcpserver.TcpHandler; @@ -176,7 +177,8 @@ public void stop() { if (isAlive()) { logger.info("Stopping {}", this); try { - locatorClient.stop(((InetSocketAddress) getBindAddress()).getAddress(), getPort()); + locatorClient + .stop(new HostAndPort(((InetSocketAddress) getBindAddress()).getHostName(), getPort())); } catch (ConnectException ignore) { // must not be running } 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 35c8f2cef041..95b3e3a64157 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 @@ -20,7 +20,6 @@ import static org.apache.geode.internal.serialization.DataSerializableFixedID.REMOVE_MEMBER_REQUEST; import java.io.IOException; -import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -62,6 +61,7 @@ import org.apache.geode.distributed.internal.membership.gms.messages.NetworkPartitionMessage; import org.apache.geode.distributed.internal.membership.gms.messages.RemoveMemberMessage; import org.apache.geode.distributed.internal.membership.gms.messages.ViewAckMessage; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.serialization.Version; import org.apache.geode.logging.internal.executors.LoggingExecutors; @@ -179,7 +179,7 @@ public class GMSJoinLeave implements JoinLeave */ private GMSMembershipView lastConflictingView; - private List locators; + private List locators; /** * a list of join/leave/crashes @@ -1140,10 +1140,9 @@ boolean findCoordinator() throws MemberStartupException { state.locatorsContacted = 0; do { - for (HostAddress laddr : locators) { + for (HostAndPort laddr : locators) { try { - InetSocketAddress addr = laddr.getSocketInetAddress(); - Object o = locatorClient.requestToServer(addr, request, connectTimeout, true); + Object o = locatorClient.requestToServer(laddr, request, connectTimeout, true); FindCoordinatorResponse response = (o instanceof FindCoordinatorResponse) ? (FindCoordinatorResponse) o : null; if (response != null) { diff --git a/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheConnectionIntegrationTest.java b/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheConnectionIntegrationTest.java index 2a2d2b50e1ff..5917829f16c5 100644 --- a/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheConnectionIntegrationTest.java +++ b/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheConnectionIntegrationTest.java @@ -60,6 +60,7 @@ import org.apache.geode.cache.server.CacheServer; import org.apache.geode.distributed.ConfigurationProperties; import org.apache.geode.distributed.internal.InternalDistributedSystem; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.AvailablePortHelper; import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.cache.InternalCacheServer; @@ -272,6 +273,7 @@ private Socket getSSLSocket() throws IOException { sslConfigBuilder.setEndpointIdentificationEnabled(false); SocketCreator socketCreator = new SocketCreator(sslConfigBuilder.build()); - return socketCreator.connectForClient("localhost", cacheServerPort, 5000); + return socketCreator.forClient().connect(new HostAndPort("localhost", cacheServerPort), + 5000); } } diff --git a/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java b/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java index b40cabd9b044..f4d2e70fc8cd 100644 --- a/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java +++ b/geode-protobuf/src/integrationTest/java/org/apache/geode/internal/protocol/protobuf/v1/acceptance/CacheOperationsJUnitTest.java @@ -53,6 +53,7 @@ import org.apache.geode.cache.RegionFactory; import org.apache.geode.cache.server.CacheServer; import org.apache.geode.distributed.ConfigurationProperties; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.internal.AvailablePortHelper; import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.net.SocketCreator; @@ -401,6 +402,7 @@ private Socket getSSLSocket() throws IOException { sslConfigBuilder.setKeystorePassword("password"); SocketCreator socketCreator = new SocketCreator(sslConfigBuilder.build()); - return socketCreator.connectForClient("localhost", cacheServerPort, 5000); + return socketCreator.forClient().connect(new HostAndPort("localhost", cacheServerPort), + 5000); } } diff --git a/geode-serialization/src/main/java/org/apache/geode/internal/serialization/DataSerializableFixedID.java b/geode-serialization/src/main/java/org/apache/geode/internal/serialization/DataSerializableFixedID.java index 50b52bff4308..e00dd6448993 100644 --- a/geode-serialization/src/main/java/org/apache/geode/internal/serialization/DataSerializableFixedID.java +++ b/geode-serialization/src/main/java/org/apache/geode/internal/serialization/DataSerializableFixedID.java @@ -673,6 +673,7 @@ public interface DataSerializableFixedID extends SerializationVersions, BasicSer short GATEWAY_SENDER_QUEUE_ENTRY_SYNCHRONIZATION_ENTRY = 2182; short ABORT_BACKUP_REQUEST = 2183; short MEMBER_IDENTIFIER = 2184; + short HOST_AND_PORT = 2185; // NOTE, codes > 65535 will take 4 bytes to serialize diff --git a/geode-serialization/src/main/java/org/apache/geode/internal/serialization/StaticSerialization.java b/geode-serialization/src/main/java/org/apache/geode/internal/serialization/StaticSerialization.java index aa4e46a20fe7..09f62a83a361 100644 --- a/geode-serialization/src/main/java/org/apache/geode/internal/serialization/StaticSerialization.java +++ b/geode-serialization/src/main/java/org/apache/geode/internal/serialization/StaticSerialization.java @@ -266,6 +266,7 @@ public static InetAddress readInetAddress(DataInput in) throws IOException { } try { + // note: this does not throw UnknownHostException at this time InetAddress addr = InetAddress.getByAddress(address); return addr; } catch (UnknownHostException ex) { diff --git a/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerGossipVersionDUnitTest.java b/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerGossipVersionDUnitTest.java index b283358a447f..f321a9aa6bdd 100644 --- a/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerGossipVersionDUnitTest.java +++ b/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerGossipVersionDUnitTest.java @@ -149,7 +149,8 @@ private void restartLocator(int port0, File logFile0, Properties props) { .getSocketCreatorForComponent(SecurableCommunicationChannel.LOCATOR), InternalDataSerializer.getDSFIDSerializer().getObjectSerializer(), InternalDataSerializer.getDSFIDSerializer().getObjectDeserializer()) - .requestToServer(LocalHostUtil.getLocalHost(), port0, req, 5000); + .requestToServer(new HostAndPort(LocalHostUtil.getLocalHost().getHostName(), port0), + req, 5000); assertThat(response).isNotNull(); } catch (IllegalStateException e) { diff --git a/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java b/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java index a0947e570d51..991c10b4f0c3 100644 --- a/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java +++ b/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerJUnitTest.java @@ -32,6 +32,7 @@ import java.net.ConnectException; import java.net.InetAddress; import java.net.SocketException; +import java.net.UnknownHostException; import java.util.HashSet; import java.util.Properties; import java.util.Set; @@ -124,6 +125,14 @@ private static int getNeverUsedPort() { return port; } + @Test + public void testConnectToUnknownHost() throws Exception { + final TcpClient tcpClient = createTcpClient(); + InfoRequest testInfoRequest = new InfoRequest(); + assertThatThrownBy(() -> tcpClient.requestToServer(new HostAndPort("unknown host name", port), + testInfoRequest, TIMEOUT)).isInstanceOf(UnknownHostException.class); + } + @Test public void testClientGetInfo() throws Exception { TcpHandler handler = new InfoRequestHandler(); @@ -133,10 +142,11 @@ public void testClientGetInfo() throws Exception { InfoRequest testInfoRequest = new InfoRequest(); InfoResponse testInfoResponse = - (InfoResponse) tcpClient.requestToServer(localhost, port, testInfoRequest, TIMEOUT); + (InfoResponse) tcpClient.requestToServer(new HostAndPort(localhost.getHostAddress(), port), + testInfoRequest, TIMEOUT); assertThat(testInfoResponse.getInfo()[0]).contains("geode-tcp-server"); - String[] requestedInfo = tcpClient.getInfo(localhost, port); + String[] requestedInfo = tcpClient.getInfo(new HostAndPort(localhost.getHostAddress(), port)); assertNotNull(requestedInfo); assertTrue(requestedInfo.length > 1); @@ -167,7 +177,8 @@ public void testConcurrency() throws Exception { public void run() { Boolean delay = Boolean.valueOf(true); try { - tcpClient.requestToServer(localhost, port, delay, TIMEOUT); + tcpClient.requestToServer(new HostAndPort(localhost.getHostAddress(), port), delay, + TIMEOUT); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { @@ -180,7 +191,8 @@ public void run() { try { Thread.sleep(500); assertFalse(done.get()); - tcpClient.requestToServer(localhost, port, Boolean.valueOf(false), TIMEOUT); + tcpClient.requestToServer(new HostAndPort(localhost.getHostAddress(), port), + Boolean.valueOf(false), TIMEOUT); assertFalse(done.get()); latch.countDown(); @@ -206,8 +218,9 @@ public void testNewConnectionsAcceptedAfterSocketException() throws IOException, // Due to the mocked handler, an EOFException will be thrown on the client. This is expected. assertThatThrownBy( - () -> tcpClient.requestToServer(localhost, port, new TestObject(), TIMEOUT)) - .isInstanceOf(EOFException.class); + () -> tcpClient.requestToServer(new HostAndPort(localhost.getHostAddress(), port), + new TestObject(), TIMEOUT)) + .isInstanceOf(EOFException.class); // Change the mock handler behavior to echo the request back doAnswer(new Answer() { @@ -221,7 +234,8 @@ public Object answer(InvocationOnMock invocation) throws Throwable { TestObject test = new TestObject(); test.id = 5; TestObject result = - (TestObject) tcpClient.requestToServer(localhost, port, test, TIMEOUT); + (TestObject) tcpClient.requestToServer(new HostAndPort(localhost.getHostAddress(), port), + test, TIMEOUT); assertEquals(test.id, result.id); @@ -233,7 +247,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable { private void stopServer(final TcpClient tcpClient) throws InterruptedException { try { - tcpClient.stop(localhost, port); + tcpClient.stop(new HostAndPort(localhost.getHostAddress(), port)); } catch (ConnectException ignore) { // must not be running } diff --git a/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerProductVersionDUnitTest.java b/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerProductVersionDUnitTest.java index e98cbf82e0cd..9bc0f317e15c 100644 --- a/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerProductVersionDUnitTest.java +++ b/geode-tcp-server/src/distributedTest/java/org/apache/geode/distributed/internal/tcpserver/TcpServerProductVersionDUnitTest.java @@ -23,6 +23,8 @@ import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetAddress; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -168,8 +170,19 @@ private SerializableRunnableIF createRequestResponseFunction( tcpClient = getLegacyTcpClient(); } - final Object response = tcpClient - .requestToServer(SocketCreator.getLocalHost(), locatorPort, requestMessage, 1000); + Object response; + try { + Method requestToServer = + TcpClient.class.getMethod("requestToServer", InetAddress.class, int.class, Object.class, + int.class); + response = requestToServer.invoke(tcpClient, SocketCreator.getLocalHost(), locatorPort, + requestMessage, 1000); + } catch (NoSuchMethodException e) { + response = tcpClient + .requestToServer( + new HostAndPort(SocketCreator.getLocalHost().getHostAddress(), locatorPort), + requestMessage, 1000); + } final Class responseClass = Class.forName(responseClassName); diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreator.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreator.java new file mode 100644 index 000000000000..a93df50dc123 --- /dev/null +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreator.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.tcpserver; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + + +/** + * AdvancedSocketCreator provides a couple of methods for either client/server + * or cluster communications that don't fit neatly into either of the ClientSocketCreator + * or ClusterSocketCreator interfaces. + */ +public interface AdvancedSocketCreator { + /** + * Returns true if this socket creator is configured to use SSL by default + */ + boolean useSSL(); + + /** + * After creating a socket connection use this method to initiate the SSL + * handshake. If SSL is not enabled for the socket this method does nothing. + */ + void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException; + + /** + * This method is used to create a ServerSocket that uses a port in a specific + * range of values. You can also specify whether SSL is or is not used. + */ + ServerSocket createServerSocketUsingPortRange(InetAddress ba, int backlog, + boolean isBindAddress, boolean useNIO, + int tcpBufferSize, int[] tcpPortRange, + boolean sslConnection) throws IOException; + + /** + * This method gives you pretty much full control over creating a connection + * to the given host/port. Use it with care. + *

+ * Return a client socket, timing out if unable to connect and timeout > 0 (millis). The parameter + * timeout is ignored if SSL is being used, as there is no timeout argument in the ssl + * socket factory + */ + Socket connect(HostAndPort addr, int timeout, + ConnectionWatcher optionalWatcher, boolean allowClientSocketFactory, + int socketBufferSize, + boolean useSSL) throws IOException; +} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreatorImpl.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreatorImpl.java new file mode 100644 index 000000000000..16104eccad30 --- /dev/null +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/AdvancedSocketCreatorImpl.java @@ -0,0 +1,180 @@ +/* + * 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.tcpserver; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.nio.channels.ServerSocketChannel; +import java.util.concurrent.ThreadLocalRandom; + +import org.apache.geode.util.internal.GeodeGlossary; + +public class AdvancedSocketCreatorImpl implements AdvancedSocketCreator { + + public static final boolean ENABLE_TCP_KEEP_ALIVE; + + static { + // bug #49484 - customers want tcp/ip keep-alive turned on by default + // to avoid dropped connections. It can be turned off by setting this + // property to false + String str = System.getProperty(GeodeGlossary.GEMFIRE_PREFIX + "setTcpKeepAlive"); + if (str != null) { + ENABLE_TCP_KEEP_ALIVE = Boolean.valueOf(str); + } else { + ENABLE_TCP_KEEP_ALIVE = true; + } + } + + protected final TcpSocketCreatorImpl socketCreator; + + protected AdvancedSocketCreatorImpl(TcpSocketCreatorImpl socketCreator) { + this.socketCreator = socketCreator; + } + + @Override + public boolean useSSL() { + return socketCreator.useSSL(); + } + + @Override + public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { + if (useSSL()) { + throw new IllegalStateException("Handshake on SSL connections is not supported"); + } + } + + @Override + public Socket connect(HostAndPort addr, int timeout, + ConnectionWatcher optionalWatcher, boolean allowClientSocketFactory, + int socketBufferSize, boolean useSSL) throws IOException { + if (useSSL) { + throw new IllegalArgumentException(); + } + Socket socket = null; + if (allowClientSocketFactory) { + socket = createCustomClientSocket(addr); + } + if (socket == null) { + socket = new Socket(); + + // Optionally enable SO_KEEPALIVE in the OS network protocol. + socket.setKeepAlive(ENABLE_TCP_KEEP_ALIVE); + + if (socketBufferSize != -1) { + socket.setReceiveBufferSize(socketBufferSize); + } + if (optionalWatcher != null) { + optionalWatcher.beforeConnect(socket); + } + InetSocketAddress inetSocketAddress = addr.getSocketInetAddress(); + try { + InetAddress serverAddress = inetSocketAddress.getAddress(); + if (serverAddress == null) { + serverAddress = InetAddress.getByName(inetSocketAddress.getHostName()); + } + socket.connect( + new InetSocketAddress(serverAddress, inetSocketAddress.getPort()), + Math.max(timeout, 0)); + } finally { + if (optionalWatcher != null) { + optionalWatcher.afterConnect(socket); + } + } + } + return socket; + } + + @Override + public final ServerSocket createServerSocketUsingPortRange(InetAddress ba, int backlog, + boolean isBindAddress, boolean useNIO, + int tcpBufferSize, int[] tcpPortRange, + boolean sslConnection) throws IOException { + try { + // Get a random port from range. + int startingPort = tcpPortRange[0] + + ThreadLocalRandom.current().nextInt(tcpPortRange[1] - tcpPortRange[0] + 1); + int localPort = startingPort; + int portLimit = tcpPortRange[1]; + + while (true) { + if (localPort > portLimit) { + if (startingPort != 0) { + localPort = tcpPortRange[0]; + portLimit = startingPort - 1; + startingPort = 0; + } else { + throw noFreePortException( + String.format("Unable to find a free port in the membership-port-range: [%d,%d]", + tcpPortRange[0], tcpPortRange[1])); + } + } + ServerSocket socket = null; + try { + if (useNIO) { + ServerSocketChannel channel = ServerSocketChannel.open(); + socket = channel.socket(); + + InetSocketAddress address = + new InetSocketAddress(isBindAddress ? ba : null, localPort); + socket.bind(address, backlog); + } else { + socket = socketCreator.serverSocketCreator.createServerSocket(localPort, + backlog, isBindAddress ? ba : null, + tcpBufferSize, sslConnection); + } + return socket; + } catch (java.net.SocketException ex) { + if (socket != null && !socket.isClosed()) { + socket.close(); + } + localPort++; + } + } + } catch (IOException e) { + throw problemCreatingSocketInPortRangeException( + "unable to create a socket in the membership-port range", e); + } + } + + /** + * Overridable method for creating an exception during search of port-range + */ + protected RuntimeException problemCreatingSocketInPortRangeException(String s, IOException e) { + return new RuntimeException(s, e); + } + + /** + * Overridable method for creating an exception during search of port-range + */ + protected RuntimeException noFreePortException(String reason) { + return new RuntimeException(reason); + } + + /** + * reimplement this method to use a custom socket factory to create and configure a new + * client-side socket + * + * @return the socket, or null if no custom client socket factory is available + */ + protected Socket createCustomClientSocket(HostAndPort addr) throws IOException { + throw new UnsupportedOperationException( + "custom client socket factory is not supported by this socket creator"); + } + + +} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreator.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreator.java new file mode 100644 index 000000000000..dd360d0cb90b --- /dev/null +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreator.java @@ -0,0 +1,48 @@ +/* + * 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.tcpserver; + +import java.io.IOException; +import java.net.Socket; + +/** + * ClientSocketCreator should be used, in most cases, in client caches and for WAN + * connections. It allows the use of a socket factory in creating connections to servers. + */ +public interface ClientSocketCreator { + + /** + * Returns true if this socket creator is configured to use SSL by default + */ + boolean useSSL(); + + /** + * After creating a socket connection use this method to initiate the SSL + * handshake. If SSL is not enabled for the socket this method does nothing. + */ + void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException; + + /** + * Create a connection to the given host/port using client-cache defaults for things + * like socket buffer size + */ + Socket connect(HostAndPort addr, int connectTimeout) throws IOException; + + /** + * Creates a connection to the given host/port + */ + Socket connect(HostAndPort addr, int connectTimeout, int socketBufferSize) + throws IOException; +} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreatorImpl.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreatorImpl.java new file mode 100644 index 000000000000..2479f829312f --- /dev/null +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClientSocketCreatorImpl.java @@ -0,0 +1,54 @@ +/* + * 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.tcpserver; + +import java.io.IOException; +import java.net.Socket; + +public class ClientSocketCreatorImpl implements ClientSocketCreator { + protected final TcpSocketCreatorImpl socketCreator; + + protected ClientSocketCreatorImpl(TcpSocketCreatorImpl socketCreator) { + this.socketCreator = socketCreator; + } + + @Override + public boolean useSSL() { + return socketCreator.useSSL(); + } + + @Override + public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { + if (useSSL()) { + throw new IllegalStateException("Handshake on SSL connections is not supported"); + } + } + + /** + * Return a client socket. This method is used by client/server clients. + */ + public Socket connect(HostAndPort addr, int timeout) throws IOException { + return socketCreator.connect(addr, timeout, null, true, -1); + } + + /** + * Return a client socket. This method is used by client/server clients. + */ + public Socket connect(HostAndPort addr, int timeout, int socketBufferSize) + throws IOException { + return socketCreator.connect(addr, timeout, null, true, socketBufferSize); + } + +} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClusterSocketCreator.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClusterSocketCreator.java new file mode 100644 index 000000000000..ccf4c69d3459 --- /dev/null +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ClusterSocketCreator.java @@ -0,0 +1,66 @@ +/* + * 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.tcpserver; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * ServerSocketCreator should be used to create connections between peers in + * a cluster. + */ +public interface ClusterSocketCreator { + + /** + * Returns true if this socket creator is configured to use SSL by default + */ + boolean useSSL(); + + /** + * After creating a socket connection use this method to initiate the SSL + * handshake. If SSL is not enabled for the socket this method does nothing. + */ + void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException; + + /** + * Create a server socket that listens on all interfaces + */ + ServerSocket createServerSocket(int nport, int backlog) throws IOException; + + /** + * Create a server socket that is bound to the given address + */ + ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr) + throws IOException; + + /** + * Creates a connection to the given host/port. This method ignores any + * custom client-side socket factory that may be installed. + */ + Socket connect(HostAndPort addr) throws IOException; + + /** + * Creates a connection to the given host/port. The ConnectionWatcher may be null. + * If it is not null the watcher is notified before and after the connection is created. + * This is typically used by a timer task in order to take action should connection-formation + * take too long. + *

+ * This method ignores any custom client-side socket factory that may be installed. + */ + Socket connect(HostAndPort addr, int timeout, + ConnectionWatcher optionalWatcher) throws IOException; +} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/HostAndPort.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/HostAndPort.java new file mode 100644 index 000000000000..860eae50dea0 --- /dev/null +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/HostAndPort.java @@ -0,0 +1,154 @@ +/* + * 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.tcpserver; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.util.Objects; + +import org.apache.commons.validator.routines.InetAddressValidator; + +import org.apache.geode.internal.serialization.DataSerializableFixedID; +import org.apache.geode.internal.serialization.DeserializationContext; +import org.apache.geode.internal.serialization.SerializationContext; +import org.apache.geode.internal.serialization.StaticSerialization; +import org.apache.geode.internal.serialization.Version; + +/** + * This class is serializable for testing. A number of client/server and WAN tests + * transmit PoolAttributes between unit test JVMs using RMI. PoolAttributes are + * Externalizable for this purpose and use Geode serialization to transmit HostAndPort + * objects along with other attributes. + */ +public class HostAndPort implements DataSerializableFixedID { + + private InetSocketAddress socketInetAddress; + + public HostAndPort() { + // serialization constructor + } + + public HostAndPort(String hostName, int port) { + if (hostName == null) { + socketInetAddress = new InetSocketAddress(port); + } else if (InetAddressValidator.getInstance().isValid(hostName)) { + // numeric address - use as-is + socketInetAddress = new InetSocketAddress(hostName, port); + } else { + // non-numeric address - resolve hostname when needed + socketInetAddress = InetSocketAddress.createUnresolved(hostName, port); + } + } + + /** + * If location is not litteral IP address a new resolved {@link InetSocketAddress} is returned. + * + * @return resolved {@link InetSocketAddress}, otherwise stored {@link InetSocketAddress} if + * literal IP address is used. + */ + public InetSocketAddress getSocketInetAddress() { + if (socketInetAddress.isUnresolved()) { + // note that this leaves the InetAddress null if the hostname isn't resolvable + return new InetSocketAddress(socketInetAddress.getHostString(), socketInetAddress.getPort()); + } else { + return this.socketInetAddress; + } + } + + public String getHostName() { + return socketInetAddress.getHostString(); + } + + public int getPort() { + return socketInetAddress.getPort(); + } + + @Override + public int hashCode() { + return socketInetAddress.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + HostAndPort that = (HostAndPort) o; + return Objects.equals(socketInetAddress, that.socketInetAddress); + } + + @Override + public String toString() { + return getClass().getSimpleName() + " [socketInetAddress=" + socketInetAddress + "]"; + } + + private InetSocketAddress cloneUnresolved(final InetSocketAddress inetSocketAddress) { + return InetSocketAddress.createUnresolved(inetSocketAddress.getHostString(), + inetSocketAddress.getPort()); + } + + public InetAddress getAddress() { + return getSocketInetAddress().getAddress(); + } + + @Override + public int getDSFID() { + return HOST_AND_PORT; + } + + @Override + public void toData(DataOutput out, SerializationContext context) throws IOException { + if (socketInetAddress.isUnresolved()) { + out.writeByte(0); + StaticSerialization.writeString(getHostName(), out); + out.writeInt(getPort()); + } else { + out.writeByte(1); + StaticSerialization.writeInetAddress(socketInetAddress.getAddress(), out); + out.writeInt(getPort()); + } + } + + @Override + public void fromData(DataInput in, DeserializationContext context) + throws IOException, ClassNotFoundException { + InetAddress address = null; + byte flags = in.readByte(); + if ((flags & 1) == 0) { + String hostName = StaticSerialization.readString(in); + int port = in.readInt(); + if (hostName == null || hostName.isEmpty()) { + socketInetAddress = new InetSocketAddress(port); + } else { + socketInetAddress = InetSocketAddress.createUnresolved(hostName, port); + } + } else { + address = StaticSerialization.readInetAddress(in); + int port = in.readInt(); + socketInetAddress = new InetSocketAddress(address, port); + } + } + + @Override + public Version[] getSerializationVersions() { + return new Version[0]; + } +} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/LocatorAddress.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/LocatorAddress.java deleted file mode 100644 index 0097b50d4ad3..000000000000 --- a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/LocatorAddress.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.tcpserver; - -import java.net.InetSocketAddress; -import java.util.Objects; - -import org.apache.commons.validator.routines.InetAddressValidator; - -public class LocatorAddress { - - private final InetSocketAddress socketInetAddress; - - public LocatorAddress(InetSocketAddress loc, String locStr) { - if (InetAddressValidator.getInstance().isValid(locStr)) { - socketInetAddress = new InetSocketAddress(locStr, loc.getPort()); - } else { - socketInetAddress = cloneUnresolved(loc); - } - } - - /** - * @deprecated Users should not care if literal IP or hostname is used. - */ - @Deprecated - public boolean isIpString() { - return !socketInetAddress.isUnresolved(); - } - - /** - * If location is not litteral IP address a new resolved {@link InetSocketAddress} is returned. - * - * @return resolved {@link InetSocketAddress}, otherwise stored {@link InetSocketAddress} if - * literal IP address is used. - */ - public InetSocketAddress getSocketInetAddress() { - if (socketInetAddress.isUnresolved()) { - return new InetSocketAddress(socketInetAddress.getHostString(), socketInetAddress.getPort()); - } else { - return this.socketInetAddress; - } - } - - public String getHostName() { - return socketInetAddress.getHostString(); - } - - public int getPort() { - return socketInetAddress.getPort(); - } - - @Override - public int hashCode() { - return socketInetAddress.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LocatorAddress that = (LocatorAddress) o; - return Objects.equals(socketInetAddress, that.socketInetAddress); - } - - @Override - public String toString() { - return getClass().getSimpleName() + " [socketInetAddress=" + socketInetAddress + "]"; - } - - private InetSocketAddress cloneUnresolved(final InetSocketAddress inetSocketAddress) { - return InetSocketAddress.createUnresolved(inetSocketAddress.getHostString(), - inetSocketAddress.getPort()); - } - -} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ServerSocketCreatorImpl.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ServerSocketCreatorImpl.java new file mode 100644 index 000000000000..ad637adf2516 --- /dev/null +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/ServerSocketCreatorImpl.java @@ -0,0 +1,96 @@ +/* + * 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.tcpserver; + +import java.io.IOException; +import java.net.BindException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; + +public class ServerSocketCreatorImpl implements ClusterSocketCreator { + private final TcpSocketCreatorImpl socketCreator; + + protected ServerSocketCreatorImpl(TcpSocketCreatorImpl socketCreator) { + + this.socketCreator = socketCreator; + } + + public boolean useSSL() { + return socketCreator.useSSL(); + } + + public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { + if (useSSL()) { + throw new IllegalStateException("Handshake on SSL connections is not supported"); + } + } + + @Override + public final ServerSocket createServerSocket(int nport, int backlog) throws IOException { + return createServerSocket(nport, backlog, null, -1, useSSL()); + } + + @Override + public final ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr) + throws IOException { + return createServerSocket(nport, backlog, bindAddr, -1, useSSL()); + } + + /** + * Overridable method for creating a server socket. Override this if you are implementing + * SSL communications or otherwise need to customize server socket creation. + */ + protected ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, + int socketBufferSize, boolean sslConnection) throws IOException { + if (sslConnection) { + throw new UnsupportedOperationException(); + } + ServerSocket result = new ServerSocket(); + result.setReuseAddress(true); + if (socketBufferSize != -1) { + result.setReceiveBufferSize(socketBufferSize); + } + try { + result.bind(new InetSocketAddress(bindAddr, nport), backlog); + } catch (BindException e) { + BindException throwMe = + new BindException(String.format("Failed to create server socket on %s[%s]", + bindAddr == null ? InetAddress.getLocalHost().getHostAddress() : bindAddr, + nport)); + throwMe.initCause(e); + throw throwMe; + } + return result; + } + + /** + * Return a client socket. This method is used by peers. + */ + public Socket connect(HostAndPort addr) throws IOException { + return socketCreator.connect(addr, 0, null, false, -1); + } + + @Override + public final Socket connect(HostAndPort addr, int timeout, + ConnectionWatcher optionalWatcher) + throws IOException { + return socketCreator.advancedSocketCreator.connect(addr, timeout, optionalWatcher, false, -1, + useSSL()); + } + + +} diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java index fcae472409b1..d1089d05137f 100644 --- a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpClient.java @@ -21,8 +21,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.Socket; import java.util.HashMap; import java.util.Map; @@ -54,7 +52,7 @@ public class TcpClient { private static final int DEFAULT_REQUEST_TIMEOUT = 60 * 2 * 1000; @MakeNotStatic - private static final Map serverVersions = + private static final Map serverVersions = new HashMap<>(); private final TcpSocketCreator socketCreator; @@ -76,17 +74,17 @@ public TcpClient(TcpSocketCreator socketCreator, final ObjectSerializer objectSe /** * Stops the Locator running on a given host and port */ - public void stop(InetAddress addr, int port) throws java.net.ConnectException { + public void stop(HostAndPort addr) throws java.net.ConnectException { try { ShutdownRequest request = new ShutdownRequest(); - requestToServer(addr, port, request, DEFAULT_REQUEST_TIMEOUT); + requestToServer(addr, request, DEFAULT_REQUEST_TIMEOUT); } catch (java.net.ConnectException ce) { // must not be running, rethrow so the caller can handle. // In most cases this Exception should be ignored. throw ce; } catch (Exception ex) { logger.error( - "TcpClient.stop(): exception connecting to locator " + addr + ":" + port + ": " + ex); + "TcpClient.stop(): exception connecting to locator " + addr + ex); } } @@ -95,17 +93,17 @@ public void stop(InetAddress addr, int port) throws java.net.ConnectException { * Strings are returned: the first string is the working directory of the locator * and the second string is the product directory of the locator. */ - public String[] getInfo(InetAddress addr, int port) { + public String[] getInfo(HostAndPort addr) { try { InfoRequest request = new InfoRequest(); InfoResponse response = - (InfoResponse) requestToServer(addr, port, request, DEFAULT_REQUEST_TIMEOUT); + (InfoResponse) requestToServer(addr, request, DEFAULT_REQUEST_TIMEOUT); return response.getInfo(); } catch (java.net.ConnectException ignore) { return null; } catch (Exception ex) { logger.error( - "TcpClient.getInfo(): exception connecting to locator " + addr + ":" + port + ": " + ex); + "TcpClient.getInfo(): exception connecting to locator " + addr + ": " + ex); return null; } @@ -115,53 +113,31 @@ public String[] getInfo(InetAddress addr, int port) { * Send a request to a Locator and expect a reply * * @param addr The locator's address - * @param port The locator's tcp/ip port * @param request The request message * @param timeout Timeout for sending the message and receiving a reply * @return the reply */ - public Object requestToServer(InetAddress addr, int port, Object request, int timeout) + public Object requestToServer(HostAndPort addr, Object request, int timeout) throws IOException, ClassNotFoundException { - return requestToServer(addr, port, request, timeout, true); + return requestToServer(addr, request, timeout, true); } /** * Send a request to a Locator * * @param addr The locator's address - * @param port The locator's tcp/ip port - * @param request The request message - * @param timeout Timeout for sending the message and receiving a reply - * @param replyExpected Whether to wait for a reply - * @return the reply - */ - public Object requestToServer(InetAddress addr, int port, Object request, int timeout, - boolean replyExpected) throws IOException, ClassNotFoundException { - InetSocketAddress ipAddr; - if (addr == null) { - ipAddr = new InetSocketAddress(port); - } else { - ipAddr = new InetSocketAddress(addr, port); // fix for bug 30810 - } - return requestToServer(ipAddr, request, timeout, replyExpected); - } - - /** - * Send a request to a Locator - * - * @param ipAddr The locator's inet socket address * @param request The request message * @param timeout Timeout for sending the message and receiving a reply * @param replyExpected Whether to wait for a reply * @return The reply, or null if no reply is expected */ - public Object requestToServer(InetSocketAddress ipAddr, Object request, int timeout, + public Object requestToServer(HostAndPort addr, Object request, int timeout, boolean replyExpected) throws IOException, ClassNotFoundException { long giveupTime = System.currentTimeMillis() + timeout; // Get the GemFire version of the TcpServer first, before sending any other request. - short serverVersion = getServerVersion(ipAddr, timeout); + short serverVersion = getServerVersion(addr, timeout); if (serverVersion > Version.CURRENT_ORDINAL) { serverVersion = Version.CURRENT_ORDINAL; @@ -179,10 +155,10 @@ public Object requestToServer(InetSocketAddress ipAddr, Object request, int time return null; } - logger.debug("TcpClient sending {} to {}", request, ipAddr); + logger.debug("TcpClient sending {} to {}", request, addr); Socket sock = - socketCreator.connect(ipAddr.getAddress(), ipAddr.getPort(), (int) newTimeout, null, false); + socketCreator.forCluster().connect(addr, (int) newTimeout, null); sock.setSoTimeout((int) newTimeout); DataOutputStream out = null; try { @@ -210,7 +186,7 @@ public Object requestToServer(InetSocketAddress ipAddr, Object request, int time return response; } catch (EOFException ex) { logger.debug("requestToServer EOFException ", ex); - EOFException eof = new EOFException("Locator at " + ipAddr + EOFException eof = new EOFException("Locator at " + addr + " did not respond. This is normal if the locator was shutdown. If it wasn't check its log for exceptions."); eof.initCause(ex); throw eof; @@ -232,7 +208,7 @@ public Object requestToServer(InetSocketAddress ipAddr, Object request, int time // with the socket and is closing it. Aborting the connection by // setting SO_LINGER to zero will clean up the TIME_WAIT socket on // the locator's machine. - if (!sock.isClosed() && !socketCreator.useSSL()) { + if (!sock.isClosed() && !socketCreator.forCluster().useSSL()) { sock.setSoLinger(true, 0); } } @@ -246,7 +222,7 @@ public Object requestToServer(InetSocketAddress ipAddr, Object request, int time } } - private Short getServerVersion(InetSocketAddress ipAddr, int timeout) + private Short getServerVersion(HostAndPort addr, int timeout) throws IOException, ClassNotFoundException { int gossipVersion; @@ -255,7 +231,7 @@ private Short getServerVersion(InetSocketAddress ipAddr, int timeout) // Get GemFire version of TcpServer first, before sending any other request. synchronized (serverVersions) { - serverVersion = serverVersions.get(ipAddr); + serverVersion = serverVersions.get(addr); } if (serverVersion != null) { @@ -265,7 +241,7 @@ private Short getServerVersion(InetSocketAddress ipAddr, int timeout) gossipVersion = TcpServer.getOldGossipVersion(); try { - sock = socketCreator.connect(ipAddr.getAddress(), ipAddr.getPort(), timeout, null, false); + sock = socketCreator.forCluster().connect(addr, timeout, null); sock.setSoTimeout(timeout); } catch (SSLException e) { throw new IllegalStateException("Unable to form SSL connection", e); @@ -296,7 +272,7 @@ private Short getServerVersion(InetSocketAddress ipAddr, int timeout) VersionResponse response = (VersionResponse) readObject; serverVersion = response.getVersionOrdinal(); synchronized (serverVersions) { - serverVersions.put(ipAddr, serverVersion); + serverVersions.put(addr, serverVersion); } return serverVersion; @@ -318,7 +294,7 @@ private Short getServerVersion(InetSocketAddress ipAddr, int timeout) } synchronized (serverVersions) { - serverVersions.put(ipAddr, Version.GFE_57.ordinal()); + serverVersions.put(addr, Version.GFE_57.ordinal()); } return Short.valueOf(Version.GFE_57.ordinal()); } diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java index 5c25ac868116..7f2d828b86af 100755 --- a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpServer.java @@ -189,10 +189,10 @@ private void startServerThread() throws IOException { private void initializeServerSocket() throws IOException { if (srv_sock == null || srv_sock.isClosed()) { if (bind_address == null) { - srv_sock = socketCreator.createServerSocket(port, backlogLimit); + srv_sock = socketCreator.forCluster().createServerSocket(port, backlogLimit); bind_address = srv_sock.getInetAddress(); } else { - srv_sock = socketCreator.createServerSocket(port, backlogLimit, bind_address); + srv_sock = socketCreator.forCluster().createServerSocket(port, backlogLimit, bind_address); } // GEODE-4176 - set the port from a wild-card bind so that handlers know the correct value @@ -304,7 +304,7 @@ private void processRequest(final Socket socket) { DataInputStream input = null; try { socket.setSoTimeout(readTimeout); - socketCreator.handshakeIfSocketIsSSL(socket, readTimeout); + socketCreator.forCluster().handshakeIfSocketIsSSL(socket, readTimeout); try { input = new DataInputStream(socket.getInputStream()); diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreator.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreator.java index 11b787619ddb..a16b1cb61910 100644 --- a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreator.java +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreator.java @@ -15,34 +15,24 @@ package org.apache.geode.distributed.internal.tcpserver; -import java.io.IOException; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; /** * Create sockets for TcpServer (and TcpClient). */ public interface TcpSocketCreator { - boolean useSSL(); - - ServerSocket createServerSocket(int nport, int backlog) throws IOException; - - ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr) - throws IOException; - - ServerSocket createServerSocketUsingPortRange(InetAddress ba, int backlog, - boolean isBindAddress, boolean useNIO, int tcpBufferSize, int[] tcpPortRange, - boolean sslConnection) throws IOException; - - Socket connect(InetAddress inetadd, int port, int timeout, - ConnectionWatcher optionalWatcher, boolean clientSide) throws IOException; - - Socket connect(InetAddress inetadd, int port, int timeout, - ConnectionWatcher optionalWatcher, boolean clientSide, int socketBufferSize, - boolean sslConnection) throws IOException; - - void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException; - + /** + * Returns a socket creator for server and peer-to-peer sockets + */ + ClusterSocketCreator forCluster(); + + /** + * Returns a socket creator for client caches and WAN senders + */ + ClientSocketCreator forClient(); + + /** + * Returns a socket creator for advanced use + */ + AdvancedSocketCreator forAdvancedUse(); } diff --git a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreatorImpl.java b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreatorImpl.java index 8dc4d9e2396e..8cb33e6a3ca9 100644 --- a/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreatorImpl.java +++ b/geode-tcp-server/src/main/java/org/apache/geode/distributed/internal/tcpserver/TcpSocketCreatorImpl.java @@ -15,15 +15,8 @@ package org.apache.geode.distributed.internal.tcpserver; import java.io.IOException; -import java.net.BindException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.ServerSocket; import java.net.Socket; -import java.nio.channels.ServerSocketChannel; -import java.util.concurrent.ThreadLocalRandom; -import org.apache.geode.util.internal.GeodeGlossary; /** * TcpSocketCreatorImpl is a simple implementation of TcpSocketCreator for use in the @@ -33,188 +26,46 @@ public class TcpSocketCreatorImpl implements TcpSocketCreator { - public static final boolean ENABLE_TCP_KEEP_ALIVE; + protected ServerSocketCreatorImpl serverSocketCreator; + protected ClientSocketCreatorImpl clientSocketCreator; + protected AdvancedSocketCreatorImpl advancedSocketCreator; - static { - // bug #49484 - customers want tcp/ip keep-alive turned on by default - // to avoid dropped connections. It can be turned off by setting this - // property to false - String str = System.getProperty(GeodeGlossary.GEMFIRE_PREFIX + "setTcpKeepAlive"); - if (str != null) { - ENABLE_TCP_KEEP_ALIVE = Boolean.valueOf(str); - } else { - ENABLE_TCP_KEEP_ALIVE = true; - } + public TcpSocketCreatorImpl() { + initializeCreators(); } - public TcpSocketCreatorImpl() {} + protected void initializeCreators() { + serverSocketCreator = new ServerSocketCreatorImpl(this); + clientSocketCreator = new ClientSocketCreatorImpl(this); + advancedSocketCreator = new AdvancedSocketCreatorImpl(this); + } - @Override - public boolean useSSL() { + protected boolean useSSL() { return false; } - @Override - public final ServerSocket createServerSocket(int nport, int backlog) throws IOException { - return createServerSocket(nport, backlog, null, -1, useSSL()); - } - - @Override - public final ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr) + Socket connect(HostAndPort addr, int timeout, + ConnectionWatcher optionalWatcher, boolean clientSide, int socketBufferSize) throws IOException { - return createServerSocket(nport, backlog, bindAddr, -1, useSSL()); - } - - @Override - public final ServerSocket createServerSocketUsingPortRange(InetAddress ba, int backlog, - boolean isBindAddress, boolean useNIO, - int tcpBufferSize, int[] tcpPortRange, - boolean sslConnection) throws IOException { - try { - // Get a random port from range. - int startingPort = tcpPortRange[0] - + ThreadLocalRandom.current().nextInt(tcpPortRange[1] - tcpPortRange[0] + 1); - int localPort = startingPort; - int portLimit = tcpPortRange[1]; - - while (true) { - if (localPort > portLimit) { - if (startingPort != 0) { - localPort = tcpPortRange[0]; - portLimit = startingPort - 1; - startingPort = 0; - } else { - throw noFreePortException( - String.format("Unable to find a free port in the membership-port-range: [%d,%d]", - tcpPortRange[0], tcpPortRange[1])); - } - } - ServerSocket socket = null; - try { - if (useNIO) { - ServerSocketChannel channel = ServerSocketChannel.open(); - socket = channel.socket(); - - InetSocketAddress address = new InetSocketAddress(isBindAddress ? ba : null, localPort); - socket.bind(address, backlog); - } else { - socket = this.createServerSocket(localPort, backlog, isBindAddress ? ba : null, - tcpBufferSize, sslConnection); - } - return socket; - } catch (java.net.SocketException ex) { - if (socket != null && !socket.isClosed()) { - socket.close(); - } - localPort++; - } - } - } catch (IOException e) { - throw problemCreatingSocketInPortRangeException( - "unable to create a socket in the membership-port range", e); - } - } - - /** - * Overridable method for creating an exception during search of port-range - */ - protected RuntimeException problemCreatingSocketInPortRangeException(String s, IOException e) { - return new RuntimeException(s, e); - } - - /** - * Overridable method for creating an exception during search of port-range - */ - protected RuntimeException noFreePortException(String reason) { - return new RuntimeException(reason); - } - - /** - * Overridable method for creating a server socket. Override this if you are implementing - * SSL communications or otherwise need to customize server socket creation. - */ - protected ServerSocket createServerSocket(int nport, int backlog, InetAddress bindAddr, - int socketBufferSize, boolean sslConnection) throws IOException { - if (sslConnection) { - throw new UnsupportedOperationException(); - } - ServerSocket result = new ServerSocket(); - result.setReuseAddress(true); - if (socketBufferSize != -1) { - result.setReceiveBufferSize(socketBufferSize); - } - try { - result.bind(new InetSocketAddress(bindAddr, nport), backlog); - } catch (BindException e) { - BindException throwMe = - new BindException(String.format("Failed to create server socket on %s[%s]", - bindAddr == null ? InetAddress.getLocalHost().getHostAddress() : bindAddr, - String.valueOf(nport))); - throwMe.initCause(e); - throw throwMe; - } - return result; + return forAdvancedUse().connect(addr, timeout, optionalWatcher, clientSide, socketBufferSize, + useSSL()); } @Override - public final Socket connect(InetAddress inetadd, int port, int timeout, - ConnectionWatcher optionalWatcher, boolean clientSide) - throws IOException { - return connect(inetadd, port, timeout, optionalWatcher, clientSide, -1, useSSL()); + public ClusterSocketCreator forCluster() { + return serverSocketCreator; } @Override - public Socket connect(InetAddress inetadd, int port, int timeout, - ConnectionWatcher optionalWatcher, boolean clientSide, - int socketBufferSize, boolean sslConnection) throws IOException { - if (sslConnection) { - throw new IllegalArgumentException(); - } - Socket socket = null; - if (clientSide) { - socket = createCustomClientSocket(inetadd, port); - } - if (socket == null) { - socket = new Socket(); - - // Optionally enable SO_KEEPALIVE in the OS network protocol. - socket.setKeepAlive(ENABLE_TCP_KEEP_ALIVE); - - if (socketBufferSize != -1) { - socket.setReceiveBufferSize(socketBufferSize); - } - if (optionalWatcher != null) { - optionalWatcher.beforeConnect(socket); - } - try { - socket.connect(new InetSocketAddress(inetadd, port), Math.max(timeout, 0)); - } finally { - if (optionalWatcher != null) { - optionalWatcher.afterConnect(socket); - } - } - } - return socket; - } - - /** - * reimplement this method to use a custom socket factory to create and configure a new - * client-side socket - * - * @return the socket, or null if no custom client socket factory is available - */ - protected Socket createCustomClientSocket(InetAddress inetaddr, int port) throws IOException { - throw new UnsupportedOperationException( - "custom client socket factory is not supported by this socket creator"); + public ClientSocketCreator forClient() { + return clientSocketCreator; } @Override - public void handshakeIfSocketIsSSL(Socket socket, int timeout) throws IOException { - if (useSSL()) { - throw new IllegalStateException("Handshake on SSL connections is not supported"); - } + public AdvancedSocketCreator forAdvancedUse() { + return advancedSocketCreator; } } diff --git a/geode-tcp-server/src/test/java/org/apache/geode/distributed/internal/tcpserver/LocatorAddressTest.java b/geode-tcp-server/src/test/java/org/apache/geode/distributed/internal/tcpserver/HostAndPortTest.java similarity index 56% rename from geode-tcp-server/src/test/java/org/apache/geode/distributed/internal/tcpserver/LocatorAddressTest.java rename to geode-tcp-server/src/test/java/org/apache/geode/distributed/internal/tcpserver/HostAndPortTest.java index ad2ed0e192ad..1381721d72e6 100644 --- a/geode-tcp-server/src/test/java/org/apache/geode/distributed/internal/tcpserver/LocatorAddressTest.java +++ b/geode-tcp-server/src/test/java/org/apache/geode/distributed/internal/tcpserver/HostAndPortTest.java @@ -20,15 +20,14 @@ import org.junit.Test; -public class LocatorAddressTest { +public class HostAndPortTest { /** * Test that getSocketInentAddress returns resolved InetSocketAddress */ @Test public void Test_getSocketInentAddress_returns_resolved_SocketAddress() { - InetSocketAddress host1address = new InetSocketAddress(8080); - LocatorAddress locator1 = new LocatorAddress(host1address, "localhost"); + HostAndPort locator1 = new HostAndPort("localhost", 8080); InetSocketAddress actual = locator1.getSocketInetAddress(); @@ -40,8 +39,7 @@ public void Test_getSocketInentAddress_returns_resolved_SocketAddress() { */ @Test public void Test_getSocketInentAddress_returns_unresolved_SocketAddress() { - InetSocketAddress host1address = InetSocketAddress.createUnresolved("fakelocalhost", 8090); - LocatorAddress locator1 = new LocatorAddress(host1address, "fakelocalhost"); + HostAndPort locator1 = new HostAndPort("fakelocalhost", 8090); InetSocketAddress actual = locator1.getSocketInetAddress(); @@ -49,61 +47,43 @@ public void Test_getSocketInentAddress_returns_unresolved_SocketAddress() { } /** - * Test whether LocatorAddress are equal, when created from resolved and unresolved + * Test whether HostAndPort are equal, when created from resolved and unresolved * InetSocketAddress */ @Test public void Test_equals_LocatorAddress_from_resolved_and_unresolved_SocketAddress() { - InetSocketAddress host1address = InetSocketAddress.createUnresolved("localhost", 8090); - LocatorAddress locator1 = new LocatorAddress(host1address, "localhost"); + HostAndPort locator1 = new HostAndPort("localhost", 8080); InetSocketAddress host2address = locator1.getSocketInetAddress(); - LocatorAddress locator2 = new LocatorAddress(host2address, "localhost"); + HostAndPort locator2 = new HostAndPort("localhost", host2address.getPort()); - assertThat(host1address.isUnresolved()).isTrue(); assertThat(host2address.isUnresolved()).isFalse(); assertThat(locator1.equals(locator2)).isTrue(); } @Test public void Test_getPort_returns_port() { - InetSocketAddress host1address = InetSocketAddress.createUnresolved("localhost", 8090); - LocatorAddress locator1 = new LocatorAddress(host1address, "localhost"); + HostAndPort locator1 = new HostAndPort("localhost", 8090); assertThat(locator1.getPort()).isEqualTo(8090); } @Test public void Test_getHostName_returns_hostname() { - InetSocketAddress host1address = InetSocketAddress.createUnresolved("fakelocalhost", 8091); - LocatorAddress locator1 = new LocatorAddress(host1address, "fakelocalhost"); + HostAndPort locator1 = new HostAndPort("fakelocalhost", 8091); assertThat(locator1.getHostName()).isEqualTo("fakelocalhost"); } @Test public void Test_hashCode_of_SocketAddress() { InetSocketAddress host1address = InetSocketAddress.createUnresolved("fakelocalhost", 8091); - LocatorAddress locator1 = new LocatorAddress(host1address, "fakelocalhost"); + HostAndPort locator1 = new HostAndPort("fakelocalhost", 8091); assertThat(locator1.hashCode()).isEqualTo(host1address.hashCode()); } @Test public void Test_toString_LocatorAddress() { - InetSocketAddress host1address = InetSocketAddress.createUnresolved("fakelocalhost", 8091); - LocatorAddress locator1 = new LocatorAddress(host1address, "fakelocalhost"); + HostAndPort locator1 = new HostAndPort("fakelocalhost", 8091); assertThat(locator1.toString()).contains("socketInetAddress"); } - @Test - public void Test_isIpString_for_LocatorAddress_constructed_from_IPstring() { - InetSocketAddress host1address = new InetSocketAddress(8080); - LocatorAddress locator1 = new LocatorAddress(host1address, "127.0.0.1"); - assertThat(locator1.isIpString()).isTrue(); - } - - @Test - public void Test_isIpString_for_LocatorAddress_constructed_from_hostname() { - InetSocketAddress host1address = new InetSocketAddress(8080); - LocatorAddress locator1 = new LocatorAddress(host1address, "localhost"); - assertThat(locator1.isIpString()).isFalse(); - } } diff --git a/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java b/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java index 329e8007ee4e..27ce3ffb1955 100644 --- a/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java +++ b/geode-wan/src/distributedTest/java/org/apache/geode/internal/cache/wan/serial/WANHostNameVerificationDistributedTest.java @@ -43,6 +43,8 @@ import org.apache.geode.internal.AvailablePortHelper; import org.apache.geode.internal.cache.wan.AbstractGatewaySender; import org.apache.geode.internal.cache.wan.GatewaySenderEventRemoteDispatcher; +import org.apache.geode.internal.inet.LocalHostUtil; +import org.apache.geode.test.awaitility.GeodeAwaitility; import org.apache.geode.test.dunit.IgnoredException; import org.apache.geode.test.dunit.rules.ClusterStartupRule; import org.apache.geode.test.dunit.rules.MemberVM; @@ -111,7 +113,12 @@ private int setupWanSite1(CertStores locator_ln_store, CertStores server_ln_stor locator_ln.waitUntilRegionIsReadyOnExactlyThisManyServers("/region", 1); // create gateway sender - server_ln.invoke(WANHostNameVerificationDistributedTest::createGatewaySender); + server_ln.invoke(() -> { + GeodeAwaitility.await().until(() -> { + WANHostNameVerificationDistributedTest.createGatewaySender(); + return true; + }); + }); return locator_ln.getPort(); } @@ -140,7 +147,12 @@ private void setupWanSite2(int site1Port, CertStores locator_ny_store, locator_ny.waitUntilRegionIsReadyOnExactlyThisManyServers("/region", 1); // create gateway sender - server_ny.invoke(WANHostNameVerificationDistributedTest::createGatewayReceiver); + server_ny.invoke(() -> { + GeodeAwaitility.await().until(() -> { + WANHostNameVerificationDistributedTest.createGatewayReceiver(); + return true; + }); + }); } private static void createGatewayReceiver() { @@ -202,15 +214,22 @@ public void enableHostNameValidationAcrossAllComponents() throws Exception { // ClusterStartupRule uses 'localhost' as locator host .sanDnsName(InetAddress.getLoopbackAddress().getHostName()) .sanDnsName(InetAddress.getLocalHost().getHostName()) + .sanDnsName(InetAddress.getLocalHost().getHostAddress()) + .sanDnsName(LocalHostUtil.getLocalHost().getCanonicalHostName()) .sanIpAddress(InetAddress.getLocalHost()) .sanIpAddress(InetAddress.getByName("0.0.0.0")) // to pass on windows + .sanIpAddress(LocalHostUtil.getLocalHost()) .generate(); CertificateMaterial server_ln_cert = new CertificateBuilder() .commonName("server_ln") .issuedBy(ca) .sanDnsName(InetAddress.getLocalHost().getHostName()) + .sanDnsName(LocalHostUtil.getLocalHost().getHostName()) + .sanDnsName(LocalHostUtil.getLocalHost().getCanonicalHostName()) + .sanDnsName(InetAddress.getLocalHost().getHostAddress()) .sanIpAddress(InetAddress.getLocalHost()) + .sanIpAddress(LocalHostUtil.getLocalHost()) .generate(); CertificateMaterial locator_ny_cert = new CertificateBuilder() @@ -220,8 +239,12 @@ public void enableHostNameValidationAcrossAllComponents() throws Exception { .sanDnsName(InetAddress.getLoopbackAddress().getHostName()) .sanDnsName(InetAddress.getLocalHost().getHostName()) .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName()) + .sanDnsName(LocalHostUtil.getLocalHost().getCanonicalHostName()) + .sanDnsName(LocalHostUtil.getLocalHost().getHostName()) + .sanDnsName(InetAddress.getLocalHost().getHostAddress()) .sanIpAddress(InetAddress.getLocalHost()) .sanIpAddress(InetAddress.getByName("0.0.0.0")) // to pass on windows + .sanIpAddress(LocalHostUtil.getLocalHost()) .generate(); CertificateMaterial server_ny_cert = new CertificateBuilder() @@ -229,7 +252,11 @@ public void enableHostNameValidationAcrossAllComponents() throws Exception { .issuedBy(ca) .sanDnsName(InetAddress.getLocalHost().getHostName()) .sanDnsName(InetAddress.getLocalHost().getCanonicalHostName()) + .sanDnsName(LocalHostUtil.getLocalHost().getHostName()) + .sanDnsName(LocalHostUtil.getLocalHost().getCanonicalHostName()) + .sanDnsName(InetAddress.getLocalHost().getHostAddress()) .sanIpAddress(InetAddress.getLocalHost()) + .sanIpAddress(LocalHostUtil.getLocalHost()) .generate(); setupWanSites(ca, locator_ln_cert, server_ln_cert, locator_ny_cert, server_ny_cert); diff --git a/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorDiscovery.java b/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorDiscovery.java index ce1c7e207801..62b2fabae27a 100644 --- a/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorDiscovery.java +++ b/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorDiscovery.java @@ -21,6 +21,7 @@ import org.apache.logging.log4j.Logger; import org.apache.geode.distributed.internal.WanLocatorDiscoverer; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.InternalDataSerializer; import org.apache.geode.internal.admin.remote.DistributionLocatorId; @@ -138,8 +139,8 @@ private void exchangeLocalLocators() { while (!getDiscoverer().isStopped()) { try { RemoteLocatorJoinResponse response = - (RemoteLocatorJoinResponse) locatorClient.requestToServer(locatorId.getHost(), request, - WanLocatorDiscoverer.WAN_LOCATOR_CONNECTION_TIMEOUT, true); + (RemoteLocatorJoinResponse) locatorClient.requestToServer(locatorId.getHost(), + request, WanLocatorDiscoverer.WAN_LOCATOR_CONNECTION_TIMEOUT, true); if (response != null) { LocatorHelper.addExchangedLocators(response.getLocators(), this.locatorListener); logger.info("Locator discovery task exchanged locator information {} with {}: {}.", @@ -185,7 +186,8 @@ public void exchangeRemoteLocators() { RemoteLocatorJoinResponse response; try { response = - (RemoteLocatorJoinResponse) locatorClient.requestToServer(remoteLocator.getHost(), + (RemoteLocatorJoinResponse) locatorClient.requestToServer( + remoteLocator.getHost(), request, WanLocatorDiscoverer.WAN_LOCATOR_CONNECTION_TIMEOUT, true); if (response != null) { LocatorHelper.addExchangedLocators(response.getLocators(), this.locatorListener); @@ -195,7 +197,8 @@ public void exchangeRemoteLocators() { while (true) { Thread.sleep(WAN_LOCATOR_PING_INTERVAL); RemoteLocatorPingResponse pingResponse = - (RemoteLocatorPingResponse) locatorClient.requestToServer(remoteLocator.getHost(), + (RemoteLocatorPingResponse) locatorClient.requestToServer( + new HostAndPort(remoteLocator.getHostName(), remoteLocator.getPort()), pingRequest, WanLocatorDiscoverer.WAN_LOCATOR_CONNECTION_TIMEOUT, true); if (pingResponse != null) { continue; diff --git a/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerImpl.java b/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerImpl.java index 31315edda439..112feb6752a2 100644 --- a/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerImpl.java +++ b/geode-wan/src/main/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerImpl.java @@ -244,7 +244,8 @@ void sendMessage(DistributionLocatorId targetLocator, LocatorJoinMessage locator DistributionLocatorId advertisedLocator = locatorJoinMessage.getLocator(); try { - tcpClient.requestToServer(targetLocator.getHost(), locatorJoinMessage, memberTimeout, + tcpClient.requestToServer(targetLocator.getHost(), + locatorJoinMessage, memberTimeout, false); } catch (Exception exception) { if (logger.isDebugEnabled()) { @@ -266,7 +267,8 @@ boolean retryMessage(DistributionLocatorId targetLocator, LocatorJoinMessage loc DistributionLocatorId advertisedLocator = locatorJoinMessage.getLocator(); try { - tcpClient.requestToServer(targetLocator.getHost(), locatorJoinMessage, memberTimeout, + tcpClient.requestToServer(targetLocator.getHost(), + locatorJoinMessage, memberTimeout, false); return true; diff --git a/geode-wan/src/test/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerTest.java b/geode-wan/src/test/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerTest.java index f3770a6a8ee5..d282128618d4 100644 --- a/geode-wan/src/test/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerTest.java +++ b/geode-wan/src/test/java/org/apache/geode/cache/client/internal/locator/wan/LocatorMembershipListenerTest.java @@ -30,7 +30,6 @@ import java.io.EOFException; import java.io.IOException; -import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -50,6 +49,7 @@ import org.junit.Test; import org.apache.geode.distributed.internal.DistributionConfig; +import org.apache.geode.distributed.internal.tcpserver.HostAndPort; import org.apache.geode.distributed.internal.tcpserver.TcpClient; import org.apache.geode.internal.admin.remote.DistributionLocatorId; import org.apache.geode.test.junit.ResultCaptor; @@ -211,7 +211,7 @@ public void locatorJoinedShouldNotifyNobodyIfThereAreNoKnownLocators() any(DistributionLocatorId.class), anyMap(), any(DistributionLocatorId.class), anyInt()); locatorMembershipListener.locatorJoined(2, joiningLocator, locator1Site1); joinLocatorsDistributorThread(resultCaptor); - verify(tcpClient, times(0)).requestToServer(any(InetSocketAddress.class), + verify(tcpClient, times(0)).requestToServer(any(HostAndPort.class), any(LocatorJoinMessage.class), anyInt(), anyBoolean()); } diff --git a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewaySenderEventRemoteDispatcherIntegrationTest.java b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewaySenderEventRemoteDispatcherIntegrationTest.java index f564b0814bff..1b17e6dc6f63 100644 --- a/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewaySenderEventRemoteDispatcherIntegrationTest.java +++ b/geode-wan/src/test/java/org/apache/geode/internal/cache/wan/GatewaySenderEventRemoteDispatcherIntegrationTest.java @@ -22,8 +22,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.util.LinkedList; import java.util.Properties; @@ -82,14 +80,6 @@ public void canProcessesEventAfterHostnameLookupFailsInNotifyServerCrashed() thr final GatewaySenderEventRemoteDispatcher dispatcher = new GatewaySenderEventRemoteDispatcher(eventProcessor, connection); - /* - * Set a HostnameResolver which simulates a failed - * hostname lookup resulting in an UnknownHostException - */ - InternalDistributedMember.setHostnameResolver(ignored -> { - throw new UnknownHostException("a.b.c"); - }); - /* * We have mocked our connection to throw a RuntimeException when readAcknowledgement() is * called, then in the exception handling for that RuntimeException, the UnknownHostException @@ -97,13 +87,6 @@ public void canProcessesEventAfterHostnameLookupFailsInNotifyServerCrashed() thr */ dispatcher.readAcknowledgement(); - /* - * Need to reset the hostname resolver to a real InetAddress resolver as it is static state and - * we do not want it to throw an UnknownHostException in subsequent test runs. - */ - InternalDistributedMember - .setHostnameResolver((location) -> InetAddress.getByName(location.getHostName())); - /* * The handling of the UnknownHostException should not result in the event processor being * stopped, so assert that setIsStopped(true) was never called.