diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/client/sni/ClientSNIAcceptanceTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/client/sni/ClientSNIAcceptanceTest.java index 69aa5d8e9e21..8c8f39792e53 100644 --- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/client/sni/ClientSNIAcceptanceTest.java +++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/client/sni/ClientSNIAcceptanceTest.java @@ -91,11 +91,17 @@ public void connectToSNIProxyDocker() { .setPoolSocketFactory(ProxySocketFactories.sni("localhost", proxyPort)) .create(); + // the geode-starter.gfsh script has created a Region named "jellyfish" on the + // server sitting behind the haproxy gateway. Show that an empty client cache can + // put something in that region and then retrieve it. Region region = cache.createClientRegionFactory(ClientRegionShortcut.PROXY) .create("jellyfish"); region.destroy("hello"); region.put("hello", "world"); assertThat(region.get("hello")).isEqualTo("world"); + // the geode-starter.gfsh script put an entry named "foo" into the region with the + // value "bar" + assertThat(region.get("foo")).isEqualTo("bar"); } } diff --git a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest.java b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest.java index 90744734ff1f..0ca9a0c8d703 100644 --- a/geode-core/src/integrationTest/java/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest.java +++ b/geode-core/src/integrationTest/java/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest.java @@ -52,6 +52,7 @@ import org.apache.geode.cache.RegionService; import org.apache.geode.cache.client.internal.ProxyCache; import org.apache.geode.cache.client.internal.UserAttributes; +import org.apache.geode.cache.client.proxy.SniSocketFactory; import org.apache.geode.cache.server.CacheServer; import org.apache.geode.distributed.DistributedSystem; import org.apache.geode.distributed.internal.InternalDistributedSystem; @@ -127,7 +128,7 @@ public void test000Defaults() throws Exception { } @Test - public void test001FindDefaultFromXML() throws Exception { + public void test001FindDefaultPoolFromXML() throws Exception { File cacheXmlFile = temporaryFolder.newFile("ClientCacheFactoryJUnitTest.xml"); URL url = ClientCacheFactoryJUnitTest.class .getResource("ClientCacheFactoryJUnitTest_single_pool.xml"); @@ -149,6 +150,13 @@ public void test001FindDefaultFromXML() throws Exception { .isEqualTo(PoolFactory.DEFAULT_SOCKET_CONNECT_TIMEOUT); assertThat(defPool.getServers()).isEqualTo( Collections.singletonList(new InetSocketAddress("localhost", CacheServer.DEFAULT_PORT))); + + // verify that the SocketCreator settings were correctly picked up from the xml file + SocketFactory factory = defPool.getSocketFactory(); + assertThat(factory).isInstanceOf(SniSocketFactory.class); + SniSocketFactory sniSocketFactory = (SniSocketFactory) factory; + assertThat(sniSocketFactory.getPort()).isEqualTo(40404); + assertThat(sniSocketFactory.getHostname()).isEqualTo("localhost"); } /** diff --git a/geode-core/src/test/resources/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest_single_pool.xml b/geode-core/src/integrationTest/resources/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest_single_pool.xml similarity index 82% rename from geode-core/src/test/resources/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest_single_pool.xml rename to geode-core/src/integrationTest/resources/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest_single_pool.xml index f139459626d6..82666d93727e 100644 --- a/geode-core/src/test/resources/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest_single_pool.xml +++ b/geode-core/src/integrationTest/resources/org/apache/geode/cache/client/ClientCacheFactoryJUnitTest_single_pool.xml @@ -27,5 +27,14 @@ version="1.0"> + + org.apache.geode.cache.client.proxy.SniSocketFactory + + localhost + + + 40404 + + diff --git a/geode-core/src/main/java/org/apache/geode/cache/client/proxy/SniSocketFactory.java b/geode-core/src/main/java/org/apache/geode/cache/client/proxy/SniSocketFactory.java index 584a4055e795..f8059a312fba 100644 --- a/geode-core/src/main/java/org/apache/geode/cache/client/proxy/SniSocketFactory.java +++ b/geode-core/src/main/java/org/apache/geode/cache/client/proxy/SniSocketFactory.java @@ -18,26 +18,50 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; +import java.util.Properties; +import org.apache.geode.cache.Cache; +import org.apache.geode.cache.Declarable; import org.apache.geode.cache.client.SocketFactory; +import org.apache.geode.internal.DistributionLocator; /** * A {@link SocketFactory} that connects a client to locators and servers * through a SNI proxy. */ -public class SniSocketFactory implements SocketFactory { +public class SniSocketFactory implements SocketFactory, Declarable { - private final String hostname; - private final int port; + private String hostname; + private int port; + + public SniSocketFactory() {} // required by Declarable public SniSocketFactory(String hostname, int port) { this.hostname = hostname; this.port = port; } + @Override // Declarable + public void initialize(Cache cache, Properties properties) { + System.out.println("BRUCE: sni properties are " + properties); + this.hostname = properties.getProperty("hostname"); + String portString = + properties.getProperty("port", "" + DistributionLocator.DEFAULT_LOCATOR_PORT); + this.port = Integer.parseInt(portString); + } + @Override public Socket createSocket() throws IOException { + System.out.println("BRUCE: creating a socket with " + hostname + ":" + port); return new SniProxySocket(new InetSocketAddress(hostname, port)); } + + public String getHostname() { + return hostname; + } + + public int getPort() { + return port; + } } diff --git a/geode-docs/reference/topics/client-cache-elements-list.html.md.erb b/geode-docs/reference/topics/client-cache-elements-list.html.md.erb index 0d26303c427b..edb6f6d4d8de 100644 --- a/geode-docs/reference/topics/client-cache-elements-list.html.md.erb +++ b/geode-docs/reference/topics/client-cache-elements-list.html.md.erb @@ -31,6 +31,7 @@ For details, see [<client-cache> Element Reference.](client-cache.html) + diff --git a/geode-docs/reference/topics/client-cache.html.md.erb b/geode-docs/reference/topics/client-cache.html.md.erb index 0db531bc8689..ab3c0e8634b1 100644 --- a/geode-docs/reference/topics/client-cache.html.md.erb +++ b/geode-docs/reference/topics/client-cache.html.md.erb @@ -338,6 +338,32 @@ Provide a server list or `locator` list, but not both. port="123456"/> ``` +## <socket-factory> + +Defines a factory to create socket connections to locators and servers. A typical use of this element is to redirect connections to an ingress gateway such as Istio or HAProxy in a cluster where the TLS (SSL) Server Name Indication (SNI) field is set to indicate the actual locator or server the client is trying to reach. This allows you to expose only the gateway hostname:port without the client needing to be able to resolve the names of the locator and server machines. + +**Note:** +This setting may be used with either a Server list or a Locator list. It will be used to form connections to either. + +**Default:** + +**API:** `org.apache.geode.cache.client.proxy.ProxySocketFactories` + +**Example:** + +``` pre + + + org.apache.geode.cache.client.proxy.SniSocketFactory + + my-gateway-address + + + 12345 + + + +``` ## <disk-store> diff --git a/geode-docs/topologies_and_comm/cs_configuration/setting_up_a_client_server_system.html.md.erb b/geode-docs/topologies_and_comm/cs_configuration/setting_up_a_client_server_system.html.md.erb index 7bdeaa55349f..a9c82c10c282 100644 --- a/geode-docs/topologies_and_comm/cs_configuration/setting_up_a_client_server_system.html.md.erb +++ b/geode-docs/topologies_and_comm/cs_configuration/setting_up_a_client_server_system.html.md.erb @@ -53,8 +53,8 @@ Configure your server and client processes and data regions to run your client/s - - + + ... + + org.apache.geode.cache.client.proxy.SniSocketFactory + + my-gateway-address + + + 12345 + + + + 3. Configure the server data regions for client/server work, following these guidelines. These do not need to be performed in this order. diff --git a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java index bee2551a70e0..209c822c43a7 100755 --- a/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java +++ b/geode-dunit/src/main/java/org/apache/geode/test/dunit/internal/ProcessManager.java @@ -257,9 +257,10 @@ private String[] buildJavaCommand(int vmNum, int namingPort, String version) { } else { // remove current-version product classes and resources from the classpath dunitClasspath = - removeModulesFromPath(dunitClasspath, "geode-common", "geode-core", "geode-cq", - "geode-http-service", "geode-json", "geode-log4j", "geode-lucene", - "geode-serialization", "geode-wan", "geode-gfsh"); + dunitClasspath = + removeModulesFromPath(dunitClasspath, "geode-common", "geode-core", "geode-cq", + "geode-http-service", "geode-json", "geode-log4j", "geode-lucene", + "geode-serialization", "geode-wan", "geode-gfsh"); classPath = versionManager.getClasspath(version) + File.pathSeparator + dunitClasspath; }