diff --git a/src/main/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplate.java b/src/main/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplate.java index fd301522..32a4088f 100644 --- a/src/main/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplate.java +++ b/src/main/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplate.java @@ -23,7 +23,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; import org.apache.geode.cache.client.ClientCache; import org.apache.geode.cache.execute.Function; @@ -32,6 +31,7 @@ import org.springframework.data.gemfire.config.schema.definitions.IndexDefinitio import org.springframework.data.gemfire.config.schema.definitions.RegionDefinition; import org.springframework.data.gemfire.util.ArrayUtils; import org.springframework.data.gemfire.util.CollectionUtils; +import org.springframework.data.gemfire.util.NetworkUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -80,13 +80,16 @@ public class RestHttpGemfireAdminTemplate extends FunctionGemfireAdminTemplate { protected static final boolean DEFAULT_CREATE_REGION_SKIP_IF_EXISTS = true; protected static final boolean DEFAULT_HTTP_FOLLOW_REDIRECTS = true; - protected static final int DEFAULT_PORT = 7070; + // Default port to -1 to let HTTP clients determine the port from the protocol/scheme. + // By default, Apache Geode / Pivotal GemFire's (embedded) HTTP service listens on port 7070. + protected static final int DEFAULT_PORT = -1; protected static final String DEFAULT_HOST = "localhost"; protected static final String DEFAULT_SCHEME = "https"; protected static final String HTTP_SCHEME = "http"; protected static final String HTTPS_SCHEME = "https"; protected static final String MANAGEMENT_REST_API_URL_TEMPLATE = "%1$s://%2$s:%3$d/gemfire/v1"; + protected static final String MANAGEMENT_REST_API_NO_PORT_URL_TEMPLATE = "%1$s://%2$s/gemfire/v1"; protected static final List VALID_SCHEMES = Arrays.asList(HTTP_SCHEME, HTTPS_SCHEME); @@ -105,6 +108,7 @@ public class RestHttpGemfireAdminTemplate extends FunctionGemfireAdminTemplate { * @see org.apache.geode.cache.client.ClientCache */ public RestHttpGemfireAdminTemplate(ClientCache clientCache) { + this(clientCache, DEFAULT_SCHEME, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_HTTP_FOLLOW_REDIRECTS, Collections.emptyList()); } @@ -188,7 +192,10 @@ public class RestHttpGemfireAdminTemplate extends FunctionGemfireAdminTemplate { * @return the resolved URL. */ String resolveManagementRestApiUrl(String scheme, String host, int port) { - return String.format(MANAGEMENT_REST_API_URL_TEMPLATE, scheme, host, port); + + return NetworkUtils.isValidNonEphemeralPort(port) + ? String.format(MANAGEMENT_REST_API_URL_TEMPLATE, scheme, host, port) + : String.format(MANAGEMENT_REST_API_NO_PORT_URL_TEMPLATE, scheme, host); } /** @@ -286,8 +293,8 @@ public class RestHttpGemfireAdminTemplate extends FunctionGemfireAdminTemplate { public Builder listenOn(int port) { - Assert.isTrue(port > 0 && port < 65536, - String.format("Port [%d] must be greater than 0 and less than 65536", port)); + Assert.isTrue(NetworkUtils.isValidNonEphemeralPort(port), + String.format(NetworkUtils.INVALID_NO_EPHEMERAL_PORT_MESSAGE, port)); this.port = port; @@ -321,11 +328,13 @@ public class RestHttpGemfireAdminTemplate extends FunctionGemfireAdminTemplate { clientHttpRequestInterceptors = ArrayUtils.nullSafeArray(clientHttpRequestInterceptors, ClientHttpRequestInterceptor.class); - return with(Arrays.stream(clientHttpRequestInterceptors).collect(Collectors.toList())); + return with(Arrays.asList(clientHttpRequestInterceptors)); } public Builder with(List clientHttpRequestInterceptors) { + this.clientHttpRequestInterceptors.addAll(CollectionUtils.nullSafeList(clientHttpRequestInterceptors)); + return this; } diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationConfiguration.java index 31fd3f65..813d6549 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationConfiguration.java @@ -57,6 +57,7 @@ import org.springframework.data.gemfire.config.schema.support.IndexDefiner; import org.springframework.data.gemfire.config.schema.support.RegionDefiner; import org.springframework.data.gemfire.config.support.AbstractSmartLifecycle; import org.springframework.data.gemfire.util.CacheUtils; +import org.springframework.data.gemfire.util.NetworkUtils; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -97,8 +98,7 @@ public class ClusterConfigurationConfiguration extends AbstractAnnotationConfigS protected static final int DEFAULT_MANAGEMENT_HTTP_PORT = HttpServiceConfiguration.DEFAULT_HTTP_SERVICE_PORT; protected static final String DEFAULT_MANAGEMENT_HTTP_HOST = "localhost"; - protected static final String HTTP_FOLLOW_REDIRECTS_PROPERTY = - "spring.data.gemfire.management.http.follow-redirects"; + protected static final String HTTP_FOLLOW_REDIRECTS_PROPERTY = "spring.data.gemfire.management.http.follow-redirects"; protected static final String HTTP_SCHEME = "http"; protected static final String HTTPS_SCHEME = "https"; @@ -306,13 +306,12 @@ public class ClusterConfigurationConfiguration extends AbstractAnnotationConfigS String host = resolveManagementHttpHost(); String scheme = requireHttps ? HTTPS_SCHEME : HTTP_SCHEME; - return new RestHttpGemfireAdminTemplate.Builder() + return configurePort(new RestHttpGemfireAdminTemplate.Builder() .with(resolveClientHttpRequestInterceptors()) .with(clientCache) .using(scheme) .on(host) - .listenOn(port) - .followRedirects(followRedirects) + .followRedirects(followRedirects), port) .build(); } else { @@ -320,6 +319,13 @@ public class ClusterConfigurationConfiguration extends AbstractAnnotationConfigS } } + private RestHttpGemfireAdminTemplate.Builder configurePort(RestHttpGemfireAdminTemplate.Builder builder, int port) { + + return NetworkUtils.isValidNonEphemeralPort(port) + ? builder.listenOn(port) + : builder; + } + /** * Constructs a new instance of {@link SchemaObjectCollector} to inspect the application's context * and find all the GemFire schema objects declared of a particular type or types. diff --git a/src/main/java/org/springframework/data/gemfire/util/NetworkUtils.java b/src/main/java/org/springframework/data/gemfire/util/NetworkUtils.java new file mode 100644 index 00000000..ce743bf6 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/util/NetworkUtils.java @@ -0,0 +1,47 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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.springframework.data.gemfire.util; + +/** + * Abstract utility class providing functions for networking. + * + * @author John Blum + * @since 2.2.0 + */ +public abstract class NetworkUtils { + + public static final String INVALID_PORT_MESSAGE = + "Port [%d] must be greater than equal to 0 and less than 65536"; + + public static final String INVALID_NO_EPHEMERAL_PORT_MESSAGE = + "Port [%d] must be greater than 0 and less than 65536"; + + /** + * Determines whether the given {@link Integer#TYPE port} is valid. + * + * Technically, port 0 is valid too but no client would use port 0 (the ephemeral port) to connect to a service. + * + * @param port port to evaluate. + * @return a boolean value indicating whether the {@link Integer#TYPE port} is valid or not. + */ + public static boolean isValidPort(int port) { + return port > -1 && port < 65536; + } + + public static boolean isValidNonEphemeralPort(int port) { + return isValidPort(port) && port > 0; + } +} diff --git a/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateBuilderUnitTests.java b/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateBuilderUnitTests.java index 86881aab..cd56df60 100644 --- a/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateBuilderUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateBuilderUnitTests.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.data.gemfire.util.NetworkUtils; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.InterceptingClientHttpRequestFactory; @@ -55,7 +56,7 @@ public class RestHttpGemfireAdminTemplateBuilderUnitTests { private ClientCache mockClientCache; @SuppressWarnings("unchecked") - private T resolveFieldValue(Object target, String fieldName) throws NoSuchFieldException { + private T getFieldValue(Object target, String fieldName) throws NoSuchFieldException { Field field = ReflectionUtils.findField(target.getClass(), fieldName, ClientHttpRequestFactory.class); @@ -100,7 +101,7 @@ public class RestHttpGemfireAdminTemplateBuilderUnitTests { .isInstanceOf(InterceptingClientHttpRequestFactory.class); ClientHttpRequestFactory clientHttpRequestFactory = - resolveFieldValue(template.getRestOperations().getRequestFactory(), "requestFactory"); + getFieldValue(template.getRestOperations().getRequestFactory(), "requestFactory"); assertThat(clientHttpRequestFactory).isInstanceOf(FollowRedirectsSimpleClientHttpRequestFactory.class); assertThat(((FollowRedirectsSimpleClientHttpRequestFactory) clientHttpRequestFactory).isFollowRedirects()) @@ -114,7 +115,7 @@ public class RestHttpGemfireAdminTemplateBuilderUnitTests { } catch (IllegalArgumentException expected) { - assertThat(expected).hasMessage("Port [%d] must be greater than 0 and less than 65536", port); + assertThat(expected).hasMessage(NetworkUtils.INVALID_NO_EPHEMERAL_PORT_MESSAGE, port); assertThat(expected).hasNoCause(); throw expected; @@ -139,7 +140,7 @@ public class RestHttpGemfireAdminTemplateBuilderUnitTests { .build(); assertThat(template).isNotNull(); - assertThat(template.getManagementRestApiUrl()).isEqualTo("https://localhost:7070/gemfire/v1"); + assertThat(template.getManagementRestApiUrl()).isEqualTo("https://localhost/gemfire/v1"); } @Test diff --git a/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateUnitTests.java b/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateUnitTests.java index ffb8c349..3ceb2280 100644 --- a/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/admin/remote/RestHttpGemfireAdminTemplateUnitTests.java @@ -65,9 +65,14 @@ import org.springframework.web.client.RestTemplate; * @see org.junit.Test * @see org.mockito.Mock * @see org.mockito.Mockito + * @see org.apache.geode.cache.Region + * @see org.apache.geode.cache.client.ClientCache + * @see org.apache.geode.cache.query.Index * @see org.springframework.data.gemfire.config.admin.remote.RestHttpGemfireAdminTemplate + * @see org.springframework.http.HttpHeaders * @see org.springframework.http.client.ClientHttpRequestFactory * @see org.springframework.http.client.ClientHttpRequestInterceptor + * @see org.springframework.http.client.InterceptingClientHttpRequestFactory * @see org.springframework.web.client.RestOperations * @see org.springframework.web.client.RestTemplate * @since 2.0.0 @@ -111,7 +116,7 @@ public class RestHttpGemfireAdminTemplateUnitTests { } @SuppressWarnings("unchecked") - private T resolveFieldValue(Object target, String fieldName) throws NoSuchFieldException { + private T getFieldValue(Object target, String fieldName) throws NoSuchFieldException { Field field = ReflectionUtils.findField(target.getClass(), fieldName, ClientHttpRequestFactory.class); @@ -134,12 +139,11 @@ public class RestHttpGemfireAdminTemplateUnitTests { assertThat(template).isNotNull(); assertThat(template.getClientCache()).isSameAs(this.mockClientCache); assertThat(template.getManagementRestApiUrl()) - .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_URL_TEMPLATE, - RestHttpGemfireAdminTemplate.DEFAULT_SCHEME, RestHttpGemfireAdminTemplate.DEFAULT_HOST, - RestHttpGemfireAdminTemplate.DEFAULT_PORT)); + .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_NO_PORT_URL_TEMPLATE, + RestHttpGemfireAdminTemplate.DEFAULT_SCHEME, RestHttpGemfireAdminTemplate.DEFAULT_HOST)); assertThat(template.getRestOperations()).isInstanceOf(RestTemplate.class); - RestTemplate restTemplate = (RestTemplate) template.getRestOperations(); + RestTemplate restTemplate = template.getRestOperations(); ClientHttpRequestFactory clientHttpRequestFactory = restTemplate.getRequestFactory(); @@ -176,7 +180,7 @@ public class RestHttpGemfireAdminTemplateUnitTests { assertThat(clientHttpRequestFactory).isInstanceOf(InterceptingClientHttpRequestFactory.class); - clientHttpRequestFactory = this.resolveFieldValue(clientHttpRequestFactory, "requestFactory"); + clientHttpRequestFactory = this.getFieldValue(clientHttpRequestFactory, "requestFactory"); assertThat(clientHttpRequestFactory).isInstanceOf(FollowRedirectsSimpleClientHttpRequestFactory.class); assertThat(((FollowRedirectsSimpleClientHttpRequestFactory) clientHttpRequestFactory).isFollowRedirects()) @@ -251,9 +255,9 @@ public class RestHttpGemfireAdminTemplateUnitTests { .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_URL_TEMPLATE, "https", "cardboardbox", 443)); - assertThat(this.template.resolveManagementRestApiUrl("ftp", "jambox", 21)) + assertThat(this.template.resolveManagementRestApiUrl("ftp", "lunchbox", 21)) .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_URL_TEMPLATE, - "ftp", "jambox", 21)); + "ftp", "lunchbox", 21)); assertThat(this.template.resolveManagementRestApiUrl("sftp", "mailbox", 22)) .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_URL_TEMPLATE, @@ -264,6 +268,26 @@ public class RestHttpGemfireAdminTemplateUnitTests { "smtp", "skullbox", 25)); } + @Test + public void resolvesManagementRestApiUrlCorrectlyWhenInvalidPortIsGiven() { + + assertThat(this.template.resolveManagementRestApiUrl("https", "box", -1)) + .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_NO_PORT_URL_TEMPLATE, + "https", "box")); + + assertThat(this.template.resolveManagementRestApiUrl("http", "dropbox", 0)) + .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_NO_PORT_URL_TEMPLATE, + "http", "dropbox")); + + assertThat(this.template.resolveManagementRestApiUrl("https", "jambox", 65536)) + .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_NO_PORT_URL_TEMPLATE, + "https", "jambox")); + + assertThat(this.template.resolveManagementRestApiUrl("http", "shoebox", 101123)) + .isEqualTo(String.format(RestHttpGemfireAdminTemplate.MANAGEMENT_REST_API_NO_PORT_URL_TEMPLATE, + "http", "shoebox")); + } + @Test @SuppressWarnings("unchecked") public void createIndexCallsGemFireManagementRestApi() { @@ -276,7 +300,7 @@ public class RestHttpGemfireAdminTemplateUnitTests { assertThat(requestEntity).isNotNull(); assertThat(requestEntity.getMethod()).isEqualTo(HttpMethod.POST); - assertThat(requestEntity.getUrl()).isEqualTo(URI.create("https://localhost:7070/gemfire/v1/indexes")); + assertThat(requestEntity.getUrl()).isEqualTo(URI.create("https://localhost/gemfire/v1/indexes")); HttpHeaders headers = requestEntity.getHeaders(); @@ -316,7 +340,7 @@ public class RestHttpGemfireAdminTemplateUnitTests { assertThat(requestEntity).isNotNull(); assertThat(requestEntity.getMethod()).isEqualTo(HttpMethod.POST); - assertThat(requestEntity.getUrl()).isEqualTo(URI.create("https://localhost:7070/gemfire/v1/regions")); + assertThat(requestEntity.getUrl()).isEqualTo(URI.create("https://localhost/gemfire/v1/regions")); HttpHeaders headers = requestEntity.getHeaders(); diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationWithClientHttpRequestInterceptorsIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationWithClientHttpRequestInterceptorsIntegrationTests.java index e36ef0d2..315d0e5d 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationWithClientHttpRequestInterceptorsIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/ClusterConfigurationWithClientHttpRequestInterceptorsIntegrationTests.java @@ -90,7 +90,7 @@ public class ClusterConfigurationWithClientHttpRequestInterceptorsIntegrationTes private List clientHttpRequestInterceptors; @SuppressWarnings("unchecked") - private T resolveFieldValue(Object target, String fieldName) throws NoSuchFieldException { + private T getFieldValue(Object target, String fieldName) throws NoSuchFieldException { Field field = ReflectionUtils.findField(target.getClass(), fieldName); @@ -138,7 +138,7 @@ public class ClusterConfigurationWithClientHttpRequestInterceptorsIntegrationTes RestHttpGemfireAdminTemplate template = schemaObjectContext.getGemfireAdminOperations(); - RestTemplate restTemplate = resolveFieldValue(template, "restTemplate"); + RestTemplate restTemplate = getFieldValue(template, "restTemplate"); assertThat(restTemplate).isNotNull(); assertThat(restTemplate.getInterceptors()) diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationUnitTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationUnitTests.java index 4f1478c4..63cd0897 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationUnitTests.java @@ -68,10 +68,15 @@ import org.springframework.web.client.RestTemplate; * @see org.junit.Test * @see org.mockito.Mock * @see org.mockito.Mockito + * @see org.apache.geode.cache.Cache + * @see org.apache.geode.cache.client.ClientCache + * @see org.springframework.beans.factory.BeanFactory * @see org.springframework.core.env.Environment * @see org.springframework.core.type.AnnotationMetadata + * @see org.springframework.data.gemfire.config.admin.GemfireAdminOperations * @see org.springframework.data.gemfire.config.annotation.ClusterConfigurationConfiguration * @see org.springframework.data.gemfire.config.annotation.EnableClusterConfiguration + * @see org.springframework.web.client.RestTemplate * @since 2.0.1 */ public class EnableClusterConfigurationUnitTests { @@ -99,7 +104,7 @@ public class EnableClusterConfigurationUnitTests { } @SuppressWarnings("unchecked") - private T resolveFieldValue(Object target, String fieldName) throws NoSuchFieldException { + private T getFieldValue(Object target, String fieldName) throws NoSuchFieldException { Field field = ReflectionUtils.findField(target.getClass(), fieldName); @@ -509,7 +514,7 @@ public class EnableClusterConfigurationUnitTests { RestHttpGemfireAdminTemplate template = (RestHttpGemfireAdminTemplate) operations; - RestTemplate restTemplate = resolveFieldValue(template, "restTemplate"); + RestTemplate restTemplate = getFieldValue(template, "restTemplate"); assertThat(restTemplate).isNotNull(); assertThat(restTemplate.getInterceptors()).isEmpty(); @@ -547,14 +552,13 @@ public class EnableClusterConfigurationUnitTests { assertThat(configuration.resolveManagementRequireHttps()).isTrue(); assertThat(configuration.resolveManagementUseHttp()).isTrue(); - GemfireAdminOperations operations = - configuration.resolveGemfireAdminOperations(environment, mockClientCache); + GemfireAdminOperations operations = configuration.resolveGemfireAdminOperations(environment, mockClientCache); assertThat(operations).isInstanceOf(RestHttpGemfireAdminTemplate.class); RestHttpGemfireAdminTemplate template = (RestHttpGemfireAdminTemplate) operations; - RestTemplate restTemplate = resolveFieldValue(template, "restTemplate"); + RestTemplate restTemplate = getFieldValue(template, "restTemplate"); assertThat(restTemplate).isNotNull(); assertThat(restTemplate.getInterceptors()).isEmpty(); @@ -598,21 +602,20 @@ public class EnableClusterConfigurationUnitTests { assertThat(configuration.resolveManagementRequireHttps()).isFalse(); assertThat(configuration.resolveManagementUseHttp()).isTrue(); - GemfireAdminOperations operations = - configuration.resolveGemfireAdminOperations(environment, mockClientCache); + GemfireAdminOperations operations = configuration.resolveGemfireAdminOperations(environment, mockClientCache); assertThat(operations).isInstanceOf(RestHttpGemfireAdminTemplate.class); RestHttpGemfireAdminTemplate template = (RestHttpGemfireAdminTemplate) operations; - RestTemplate restTemplate = resolveFieldValue(template, "restTemplate"); + RestTemplate restTemplate = getFieldValue(template, "restTemplate"); assertThat(restTemplate).isNotNull(); assertThat(restTemplate.getInterceptors()).containsExactly(mockInterceptorOne, mockInterceptorTwo); assertThat(restTemplate.getRequestFactory()).isInstanceOf(InterceptingClientHttpRequestFactory.class); FollowRedirectsSimpleClientHttpRequestFactory clientHttpRequestFactory = - resolveFieldValue(restTemplate.getRequestFactory(), "requestFactory"); + getFieldValue(restTemplate.getRequestFactory(), "requestFactory"); assertThat(clientHttpRequestFactory.isFollowRedirects()).isTrue(); @@ -624,4 +627,43 @@ public class EnableClusterConfigurationUnitTests { .getProperty(eq(ClusterConfigurationConfiguration.HTTP_FOLLOW_REDIRECTS_PROPERTY), eq(Boolean.class), eq(ClusterConfigurationConfiguration.DEFAULT_HTTP_FOLLOW_REDIRECTS)); } + + @Test + public void resolvesNewRestHttpGemfireAdminOperationsAvoidsSettingInvalidPort() throws Exception { + + ClientCache mockClientCache = mock(ClientCache.class); + + Environment environment = mock(Environment.class); + + when(environment.getProperty(anyString(), eq(Boolean.class), anyBoolean())).thenReturn(false); + + ClusterConfigurationConfiguration configuration = spy(new ClusterConfigurationConfiguration()); + + doReturn(Collections.emptyList()).when(configuration).resolveClientHttpRequestInterceptors(); + + configuration.setManagementHttpHost("skullbox"); + configuration.setManagementHttpPort(-1); + configuration.setManagementUseHttp(true); + + assertThat(configuration.resolveManagementHttpHost()).isEqualTo("skullbox"); + assertThat(configuration.resolveManagementHttpPort()).isEqualTo(-1); + assertThat(configuration.resolveManagementUseHttp()).isTrue(); + + GemfireAdminOperations operations = configuration.resolveGemfireAdminOperations(environment, mockClientCache); + + assertThat(operations).isInstanceOf(RestHttpGemfireAdminTemplate.class); + + RestHttpGemfireAdminTemplate template = (RestHttpGemfireAdminTemplate) operations; + + assertThat(this.getFieldValue(template, "managementRestApiUrl")) + .isEqualTo("https://skullbox/gemfire/v1"); + + verifyZeroInteractions(mockClientCache); + + verify(configuration, times(1)).resolveClientHttpRequestInterceptors(); + + verify(environment, times(1)) + .getProperty(eq(ClusterConfigurationConfiguration.HTTP_FOLLOW_REDIRECTS_PROPERTY), eq(Boolean.class), + eq(ClusterConfigurationConfiguration.DEFAULT_HTTP_FOLLOW_REDIRECTS)); + } } diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationWithSecurityIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationWithSecurityIntegrationTests.java index 86a1d66b..09021702 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationWithSecurityIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/EnableClusterConfigurationWithSecurityIntegrationTests.java @@ -104,7 +104,7 @@ public class EnableClusterConfigurationWithSecurityIntegrationTests { private ClusterSchemaObjectInitializer initializer; @SuppressWarnings("unchecked") - private T resolveFieldValue(Object target, String fieldName) throws NoSuchFieldException { + private T getFieldValue(Object target, String fieldName) throws NoSuchFieldException { Field field = ReflectionUtils.findField(target.getClass(), fieldName); @@ -151,7 +151,7 @@ public class EnableClusterConfigurationWithSecurityIntegrationTests { RestHttpGemfireAdminTemplate template = schemaObjectContext.getGemfireAdminOperations(); - RestTemplate restTemplate = resolveFieldValue(template, "restTemplate"); + RestTemplate restTemplate = getFieldValue(template, "restTemplate"); assertThat(restTemplate).isNotNull(); assertThat(restTemplate.getInterceptors()).containsExactly(this.securityAwareClientHttpRequestInterceptor, diff --git a/src/test/java/org/springframework/data/gemfire/util/NetworkUtilsUnitTests.java b/src/test/java/org/springframework/data/gemfire/util/NetworkUtilsUnitTests.java new file mode 100644 index 00000000..b455dc0b --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/util/NetworkUtilsUnitTests.java @@ -0,0 +1,78 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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.springframework.data.gemfire.util; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +/** + * Unit Tests for {@link NetworkUtils}. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.data.gemfire.util.NetworkUtils + * @since 2.2.0 + */ +public class NetworkUtilsUnitTests { + + @Test + public void invalidPortMessageIsCorrect() { + assertThat(String.format(NetworkUtils.INVALID_PORT_MESSAGE, -1)) + .isEqualTo("Port [-1] must be greater than equal to 0 and less than 65536"); + } + + @Test + public void invalidNonEphemeralPortMessageIsCorrect() { + assertThat(String.format(NetworkUtils.INVALID_NO_EPHEMERAL_PORT_MESSAGE, -1)) + .isEqualTo("Port [-1] must be greater than 0 and less than 65536"); + } + + @Test + public void withValidPortsReturnsTrue() { + + for (int port = 0; port < 65536; port++) { + assertThat(NetworkUtils.isValidPort(port)).isTrue(); + } + } + + @Test + public void withInvalidPortsReturnsFalse() { + + assertThat(NetworkUtils.isValidPort(-21)).isFalse(); + assertThat(NetworkUtils.isValidPort(-1)).isFalse(); + assertThat(NetworkUtils.isValidPort(65536)).isFalse(); + assertThat(NetworkUtils.isValidPort(99199)).isFalse(); + } + + @Test + public void withValidNonEphemeralPortsReturnsTrue() { + + for (int port = 1; port < 65536; port++) { + assertThat(NetworkUtils.isValidNonEphemeralPort(port)).isTrue(); + } + } + + @Test + public void withInvalidNonEphemeralPortsReturnsFalse() { + + assertThat(NetworkUtils.isValidNonEphemeralPort(-21)).isFalse(); + assertThat(NetworkUtils.isValidNonEphemeralPort(-1)).isFalse(); + assertThat(NetworkUtils.isValidNonEphemeralPort(0)).isFalse(); + assertThat(NetworkUtils.isValidNonEphemeralPort(65536)).isFalse(); + assertThat(NetworkUtils.isValidNonEphemeralPort(99199)).isFalse(); + } +}