diff --git a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java index 4313e62..6768302 100644 --- a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java +++ b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/mock/GemFireMockObjectsSupport.java @@ -137,6 +137,7 @@ import org.springframework.data.gemfire.server.SubscriptionEvictionPolicy; import org.springframework.data.gemfire.tests.mock.support.MockObjectInvocationException; import org.springframework.data.gemfire.tests.util.FileSystemUtils; import org.springframework.data.gemfire.tests.util.ObjectUtils; +import org.springframework.data.gemfire.util.ArrayUtils; import org.springframework.data.util.ReflectionUtils; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -229,8 +230,10 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { private static final Map> regionAttributes = new ConcurrentHashMap<>(); - private static final String CACHE_FACTORY_DS_PROPS_CLASS_VARIABLE_NAME = "dsProps"; - private static final String CLIENT_CACHE_FACTORY_DS_PROPS_CLASS_VARIABLE_NAME = "dsProps"; + private static final String CACHE_FACTORY_DS_PROPS_FIELD_NAME = "dsProps"; + private static final String CACHE_FACTORY_INTERNAL_CACHE_BUILDER_FIELD_NAME = "internalCacheBuilder"; + private static final String CLIENT_CACHE_FACTORY_DS_PROPS_FIELD_NAME = "dsProps"; + private static final String INTERNAL_CACHE_BUILDER_CONFIG_PROPERTIES_FIELD_NAME = "configProperties"; private static final String GEMFIRE_SYSTEM_PROPERTIES_PREFIX = "gemfire."; private static final String FROM_KEYWORD = "FROM"; private static final String WHERE_KEYWORD = "WHERE"; @@ -2915,33 +2918,30 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { } private static void storeConfiguration(CacheFactory cacheFactory) { - storeConfiguration(cacheFactory, CACHE_FACTORY_DS_PROPS_CLASS_VARIABLE_NAME); + storeConfiguration(cacheFactory, CACHE_FACTORY_DS_PROPS_FIELD_NAME); } private static void storeConfiguration(ClientCacheFactory clientCacheFactory) { - storeConfiguration(clientCacheFactory, CLIENT_CACHE_FACTORY_DS_PROPS_CLASS_VARIABLE_NAME); + storeConfiguration(clientCacheFactory, CLIENT_CACHE_FACTORY_DS_PROPS_FIELD_NAME); } - private static void storeConfiguration(Object cacheFactory, String staticDistributedSystemPropertiesVariableName) { + private static void storeConfiguration(Object cacheFactory, String gemfirePropertiesFieldName) { Properties localGemFireProperties = gemfireProperties.get(); - localGemFireProperties.putAll(withGemFireApiProperties(cacheFactory, - staticDistributedSystemPropertiesVariableName)); - + localGemFireProperties.putAll(withGemFireApiProperties(cacheFactory, gemfirePropertiesFieldName)); localGemFireProperties.putAll(withGemFireSystemProperties()); } - private static Properties withGemFireApiProperties(Object cacheFactory, - String staticDistributedSystemPropertiesVariableName) { + private static Properties withGemFireApiProperties(Object cacheFactory, String gemfirePropertiesFieldName) { + + Class cacheFactoryType = Optional.ofNullable(cacheFactory) + .map(Object::getClass) + .orElse((Class) Object.class); try { - Class cacheFactoryType = Optional.ofNullable(cacheFactory) - .map(Object::getClass) - .orElse((Class) Object.class); - - Field dsPropsField = cacheFactoryType.getDeclaredField(staticDistributedSystemPropertiesVariableName); + Field dsPropsField = cacheFactoryType.getDeclaredField(gemfirePropertiesFieldName); dsPropsField.setAccessible(true); @@ -2949,7 +2949,32 @@ public abstract class GemFireMockObjectsSupport extends MockObjectsSupport { return gemfireApiProperties; } - catch (Throwable ignore) { + catch (Throwable cause) { + + if (cause instanceof NoSuchFieldException + && !CACHE_FACTORY_INTERNAL_CACHE_BUILDER_FIELD_NAME.equals(gemfirePropertiesFieldName)) { + + return Arrays.stream(ArrayUtils.nullSafeArray(cacheFactoryType.getDeclaredFields(), Field.class)) + .filter(field -> CACHE_FACTORY_INTERNAL_CACHE_BUILDER_FIELD_NAME.equals(field.getName())) + .findFirst() + .map(field -> { + + field.setAccessible(true); + + Object internalCacheBuilder = + ObjectUtils.doOperationSafely(() -> field.get(cacheFactory), null); + + if (internalCacheBuilder != null) { + return withGemFireApiProperties(internalCacheBuilder, + INTERNAL_CACHE_BUILDER_CONFIG_PROPERTIES_FIELD_NAME); + } + + return null; + + }) + .orElseGet(Properties::new); + } + return new Properties(); } } diff --git a/spring-data-geode-test/src/test/java/org/springframework/data/gemfire/tests/mock/GemFireObjectCreationTriggeredByGemFirePropertyConfigurationIntegrationTests.java b/spring-data-geode-test/src/test/java/org/springframework/data/gemfire/tests/mock/GemFireObjectCreationTriggeredByGemFirePropertyConfigurationIntegrationTests.java new file mode 100644 index 0000000..b21e5a8 --- /dev/null +++ b/spring-data-geode-test/src/test/java/org/springframework/data/gemfire/tests/mock/GemFireObjectCreationTriggeredByGemFirePropertyConfigurationIntegrationTests.java @@ -0,0 +1,69 @@ +/* + * 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.tests.mock; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Properties; + +import org.apache.geode.cache.GemFireCache; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.gemfire.config.annotation.EnableSecurity; +import org.springframework.data.gemfire.config.annotation.PeerCacheApplication; +import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport; +import org.springframework.data.gemfire.tests.mock.annotation.EnableGemFireMockObjects; +import org.springframework.data.gemfire.tests.objects.geode.security.TestSecurityManager; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Integration tests for GemFire/Geode {@link Object} creation when the GemFire/Geode {@link Object} configuration + * and {@link Class} type is expressed in GemFire/Geode {@link Properties}. + * + * @author John Blum + * @see org.junit.Test + * @see org.springframework.data.gemfire.config.annotation.EnableSecurity + * @see org.springframework.data.gemfire.config.annotation.PeerCacheApplication + * @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport + * @see org.springframework.data.gemfire.tests.mock.annotation.EnableGemFireMockObjects + * @see org.springframework.test.context.ContextConfiguration + * @see org.springframework.test.context.junit4.SpringRunner + * @since 1.0.0 + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +@SuppressWarnings("unused") +public class GemFireObjectCreationTriggeredByGemFirePropertyConfigurationIntegrationTests + extends IntegrationTestsSupport { + + @Autowired + private GemFireCache gemfireCache; + + @Test + public void securityManagerIsPresent() { + + assertThat(this.gemfireCache).isNotNull(); + assertThat(TestSecurityManager.getInstance()).isInstanceOf(TestSecurityManager.class); + } + + @PeerCacheApplication + @EnableGemFireMockObjects + @EnableSecurity(securityManagerClassName = "org.springframework.data.gemfire.tests.objects.geode.security.TestSecurityManager") + static class TestConfiguration { } + +}