diff --git a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ClientServerIntegrationTestsSupport.java b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ClientServerIntegrationTestsSupport.java index 5544559..05a7e49 100644 --- a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ClientServerIntegrationTestsSupport.java +++ b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ClientServerIntegrationTestsSupport.java @@ -37,6 +37,9 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.data.gemfire.tests.process.ProcessWrapper; import org.springframework.data.gemfire.tests.util.FileSystemUtils; import org.springframework.data.gemfire.tests.util.SocketUtils; +import org.springframework.data.gemfire.util.ArrayUtils; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; /** * The {@link ClientServerIntegrationTestsSupport} class is a abstract base class encapsulating common functionality @@ -79,23 +82,18 @@ public abstract class ClientServerIntegrationTestsSupport extends IntegrationTes protected static int findAvailablePort() throws IOException { - ServerSocket serverSocket = null; + try (ServerSocket serverSocket = new ServerSocket()) { - try { - serverSocket = new ServerSocket(); serverSocket.setReuseAddress(true); serverSocket.bind(new InetSocketAddress(0)); return serverSocket.getLocalPort(); } - finally { - SocketUtils.close(serverSocket); - } } protected static int findAndReserveAvailablePort() throws IOException { - int availablePort = 0; + int availablePort; do { availablePort = findAvailablePort(); @@ -105,7 +103,7 @@ public abstract class ClientServerIntegrationTestsSupport extends IntegrationTes return availablePort; } - protected static int intValue(Number number) { + protected static int intValue(@Nullable Number number) { return number != null ? number.intValue() : 0; } @@ -117,44 +115,50 @@ public abstract class ClientServerIntegrationTestsSupport extends IntegrationTes return Boolean.getBoolean(PROCESS_RUN_MANUAL_PROPERTY); } - protected static ProcessWrapper run(Class type, String... arguments) throws IOException { + protected static @Nullable ProcessWrapper run(Class type, String... arguments) throws IOException { return run(createDirectory(asDirectoryName(type)), type, arguments); } - protected static ProcessWrapper run(File workingDirectory, Class type, String... arguments) throws IOException { + protected static @Nullable ProcessWrapper run(File workingDirectory, Class type, String... arguments) + throws IOException { + return isProcessRunAuto() ? launch(createDirectory(workingDirectory), type, arguments) : null; } - protected static ProcessWrapper run(String classpath, Class type, String... arguments) throws IOException { + protected static @Nullable ProcessWrapper run(String classpath, Class type, String... arguments) + throws IOException { + return run(createDirectory(asDirectoryName(type)), classpath, type, arguments); } - protected static ProcessWrapper run(File workingDirectory, String classpath, Class type, String... arguments) - throws IOException { + protected static @Nullable ProcessWrapper run(File workingDirectory, String classpath, Class type, + String... arguments) throws IOException { return isProcessRunAuto() ? launch(createDirectory(workingDirectory), classpath, type, arguments) : null; } - protected static AnnotationConfigApplicationContext runSpringApplication(Class annotatedClass, String... args) { + protected static @NonNull AnnotationConfigApplicationContext runSpringApplication(Class annotatedClass, + String... args) { + return runSpringApplication(asArray(annotatedClass), args); } - protected static AnnotationConfigApplicationContext runSpringApplication(Class[] annotatedClasses, + protected static @NonNull AnnotationConfigApplicationContext runSpringApplication(Class[] annotatedClasses, String... args) { - AnnotationConfigApplicationContext applicationContext = - new AnnotationConfigApplicationContext(annotatedClasses); + AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); + applicationContext.register(ArrayUtils.nullSafeArray(annotatedClasses, Class.class)); applicationContext.registerShutdownHook(); return applicationContext; } - protected static boolean stop(ProcessWrapper process) { + protected static boolean stop(@Nullable ProcessWrapper process) { return stop(process, DEFAULT_WAIT_DURATION); } - protected static boolean stop(ProcessWrapper process, long duration) { + protected static boolean stop(@Nullable ProcessWrapper process, long duration) { return Optional.ofNullable(process) .map(it -> { @@ -171,20 +175,19 @@ public abstract class ClientServerIntegrationTestsSupport extends IntegrationTes .orElse(true); } - protected static boolean waitForCacheServerToStart(CacheServer cacheServer) { + protected static boolean waitForCacheServerToStart(@NonNull CacheServer cacheServer) { return waitForServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), DEFAULT_WAIT_DURATION); } - protected static boolean waitForCacheServerToStart(CacheServer cacheServer, long duration) { + protected static boolean waitForCacheServerToStart(@NonNull CacheServer cacheServer, long duration) { return waitForServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), duration); } - @SuppressWarnings("all") - protected static boolean waitForServerToStart(String host, int port) { + protected static boolean waitForServerToStart(@NonNull String host, int port) { return waitForServerToStart(host, port, DEFAULT_WAIT_DURATION); } - protected static boolean waitForServerToStart(String host, int port, long duration) { + protected static boolean waitForServerToStart(@NonNull String host, int port, long duration) { AtomicBoolean connected = new AtomicBoolean(false); @@ -208,11 +211,11 @@ public abstract class ClientServerIntegrationTestsSupport extends IntegrationTes }, duration); } - protected static int waitForProcessToStop(Process process, File directory) { + protected static int waitForProcessToStop(@NonNull Process process, File directory) { return waitForProcessToStop(process, directory, DEFAULT_WAIT_DURATION); } - protected static int waitForProcessToStop(Process process, File directory, long duration) { + protected static int waitForProcessToStop(@NonNull Process process, File directory, long duration) { long timeout = System.currentTimeMillis() + duration; diff --git a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ForkingClientServerIntegrationTestsSupport.java b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ForkingClientServerIntegrationTestsSupport.java index 2e87739..19bfa72 100644 --- a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ForkingClientServerIntegrationTestsSupport.java +++ b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/ForkingClientServerIntegrationTestsSupport.java @@ -15,8 +15,6 @@ */ package org.springframework.data.gemfire.tests.integration; -import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; - import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -34,6 +32,9 @@ import org.springframework.data.gemfire.config.annotation.ClientCacheApplication import org.springframework.data.gemfire.config.annotation.EnablePdx; import org.springframework.data.gemfire.tests.integration.config.ClientServerIntegrationTestsConfiguration; import org.springframework.data.gemfire.tests.process.ProcessWrapper; +import org.springframework.data.gemfire.util.ArrayUtils; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; /** * The {@link ForkingClientServerIntegrationTestsSupport} class is an abstract base class used to configure @@ -55,12 +56,12 @@ public abstract class ForkingClientServerIntegrationTestsSupport extends ClientS private static ProcessWrapper gemfireServer; - public static void startGemFireServer(Class gemfireServerConfigurationClass, String... arguments) + public static void startGemFireServer(@NonNull Class gemfireServerConfigurationClass, String... arguments) throws IOException { int availablePort = setAndGetPoolPortProperty(setAndGetCacheServerPortProperty(findAvailablePort())); - List argumentList = new ArrayList<>(Arrays.asList(nullSafeArray(arguments, String.class))); + List argumentList = new ArrayList<>(Arrays.asList(ArrayUtils.nullSafeArray(arguments, String.class))); argumentList.add(String.format("-D%s=%d", GEMFIRE_CACHE_SERVER_PORT_PROPERTY, availablePort)); @@ -95,7 +96,7 @@ public abstract class ForkingClientServerIntegrationTestsSupport extends ClientS System.clearProperty(GEMFIRE_POOL_SERVERS_PROPERTY); } - protected static synchronized void setGemFireServerProcess(ProcessWrapper gemfireServerProcess) { + protected static synchronized void setGemFireServerProcess(@Nullable ProcessWrapper gemfireServerProcess) { gemfireServer = gemfireServerProcess; } diff --git a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/IntegrationTestsSupport.java b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/IntegrationTestsSupport.java index b45a39c..5b093e2 100644 --- a/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/IntegrationTestsSupport.java +++ b/spring-data-geode-test/src/main/java/org/springframework/data/gemfire/tests/integration/IntegrationTestsSupport.java @@ -50,8 +50,6 @@ import org.apache.geode.internal.cache.InternalCache; import org.apache.geode.internal.net.SSLConfigurationFactory; import org.apache.geode.internal.net.SocketCreatorFactory; -import org.apache.shiro.util.Assert; - import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; @@ -62,6 +60,7 @@ import org.springframework.data.gemfire.tests.util.FileUtils; import org.springframework.data.gemfire.util.CollectionUtils; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; /** @@ -77,6 +76,10 @@ import org.springframework.util.ReflectionUtils; * @see org.apache.geode.DataSerializer * @see org.apache.geode.cache.GemFireCache * @see org.apache.geode.distributed.Locator + * @see org.springframework.context.ApplicationEvent + * @see org.springframework.context.ApplicationEventPublisher + * @see org.springframework.context.ApplicationEventPublisherAware + * @see org.springframework.data.gemfire.support.GemfireBeanFactoryLocator * @see org.springframework.data.gemfire.tests.mock.GemFireMockObjectsSupport * @since 1.0.0 */ @@ -90,7 +93,9 @@ public abstract class IntegrationTestsSupport { protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(30); protected static final long DEFAULT_WAIT_INTERVAL = 500L; // milliseconds + protected static final String DATE_TIME_PATTERN = "yyyy-MM-dd-hh-mm-ss"; protected static final String DIRECTORY_DELETE_ON_EXIT_PROPERTY = "spring.data.gemfire.test.directory.delete-on-exit"; + protected static final String DIRECTORY_NAME_FORMAT = "%1$s-%2$s"; protected static final String GEMFIRE_LOG_FILE = "gemfire-server.log"; protected static final String GEMFIRE_LOG_FILE_PROPERTY = "spring.data.gemfire.log.file"; protected static final String GEMFIRE_LOG_LEVEL = "error"; @@ -231,28 +236,27 @@ public abstract class IntegrationTestsSupport { public static void stopGemFireLocatorWaitOnStopEvent(long duration) { - AtomicBoolean locatorStopped = new AtomicBoolean(false); + AtomicBoolean stopped = new AtomicBoolean(false); waitOn(() -> { try { return Optional.ofNullable(Locator.getLocator()) - .filter(it -> !locatorStopped.get()) + .filter(it -> !stopped.get()) .map(IntegrationTestsSupport::stop) .map(it -> { - locatorStopped.set(!Locator.hasLocator()); - return it; + stopped.set(!Locator.hasLocator()); + return stopped.get(); }) - .map(it -> locatorStopped.get()) .orElse(true); } catch (Exception ignore) { - locatorStopped.set(true); + stopped.set(true); return true; } }, duration); } - private static Locator stop(Locator locator) { + private static @Nullable Locator stop(@Nullable Locator locator) { return Optional.ofNullable(locator) .map(it -> { @@ -262,23 +266,28 @@ public abstract class IntegrationTestsSupport { .orElse(locator); } - protected static String asApplicationName(Class type) { + protected static @NonNull String asApplicationName(@NonNull Class type) { return type.getSimpleName(); } - protected static String asDirectoryName(Class type) { - return String.format("%1$s-%2$s", asApplicationName(type), - LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd-hh-mm-ss"))); + protected static @NonNull String asDirectoryName(@NonNull Class type) { + return String.format(DIRECTORY_NAME_FORMAT, asApplicationName(type), + LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATE_TIME_PATTERN))); } - protected static File createDirectory(String pathname) { + protected static @NonNull File createDirectory(@NonNull String pathname) { return createDirectory(new File(pathname)); } - protected static File createDirectory(File directory) { + protected static @NonNull File createDirectory(@NonNull File directory) { + + assertThat(directory) + .describedAs("A File reference to the directory to create must not be null") + .isNotNull(); assertThat(directory.isDirectory() || directory.mkdirs()) - .describedAs(String.format("Failed to create directory [%s]", directory)).isTrue(); + .describedAs(String.format("Failed to create directory [%s]", directory)) + .isTrue(); if (isDeleteDirectoryOnExit()) { directory.deleteOnExit(); @@ -297,30 +306,30 @@ public abstract class IntegrationTestsSupport { } @SuppressWarnings("rawtypes") - protected static String getClassNameAsPath(Class type) { + protected static @NonNull String getClassNameAsPath(@NonNull Class type) { return type.getName().replaceAll("\\.", "/"); } - protected static String getClassNameAsPath(Object obj) { + protected static @NonNull String getClassNameAsPath(@NonNull Object obj) { return getClassNameAsPath(obj.getClass()); } @SuppressWarnings("rawtypes") - protected static String getPackageNameAsPath(Class type) { + protected static @NonNull String getPackageNameAsPath(@NonNull Class type) { return type.getPackage().getName().replaceAll("\\.", "/"); } - protected static String getPackageNameAsPath(Object obj) { + protected static @NonNull String getPackageNameAsPath(@NonNull Object obj) { return getPackageNameAsPath(obj.getClass()); } @SuppressWarnings("rawtypes") - protected static String getContextXmlFileLocation(Class type) { + protected static @NonNull String getContextXmlFileLocation(@NonNull Class type) { return getClassNameAsPath(type).concat("-context.xml"); } @SuppressWarnings("rawtypes") - protected static String getServerContextXmlFileLocation(Class type) { + protected static @NonNull String getServerContextXmlFileLocation(@NonNull Class type) { return getClassNameAsPath(type).concat("-server-context.xml"); } @@ -345,16 +354,16 @@ public abstract class IntegrationTestsSupport { String.format("%s", CollectionUtils.toString(System.getProperties()))); } - protected static boolean waitOn(Condition condition) { + protected static boolean waitOn(@NonNull Condition condition) { return waitOn(condition, DEFAULT_WAIT_DURATION); } - protected static boolean waitOn(Condition condition, long duration) { + protected static boolean waitOn(@NonNull Condition condition, long duration) { return waitOn(condition, duration, DEFAULT_WAIT_INTERVAL); } @SuppressWarnings("all") - protected static boolean waitOn(Condition condition, long duration, long interval) { + protected static boolean waitOn(@NonNull Condition condition, long duration, long interval) { long resolvedInterval = Math.max(Math.min(interval, duration), 1); long timeout = System.currentTimeMillis() + duration; @@ -430,15 +439,15 @@ public abstract class IntegrationTestsSupport { public static TestContextCacheLifecycleListenerAdapter getInstance() { return INSTANCE.updateAndGet(instance -> instance != null ? instance - : newTestContextCacheLifecycleListener()); + : newTestContextCacheLifecycleListenerAdapter()); } - private static TestContextCacheLifecycleListenerAdapter newTestContextCacheLifecycleListener() { - - TestContextCacheLifecycleListenerAdapter listener = new TestContextCacheLifecycleListenerAdapter(); + private static TestContextCacheLifecycleListenerAdapter newTestContextCacheLifecycleListenerAdapter() { + return registerCacheLifecycleListener(new TestContextCacheLifecycleListenerAdapter()); + } + private static @NonNull T registerCacheLifecycleListener(@NonNull T listener) { GemFireCacheImpl.addCacheLifecycleListener(listener); - return listener; }