Add support for configuring the working directory of the Locator created/started by the LocatorFactoryBean.
Resolves #623.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.gemfire;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -64,6 +65,8 @@ public class LocatorFactoryBean extends AbstractFactoryBeanSupport<Locator> impl
|
||||
private boolean useBeanFactoryLocator = false;
|
||||
private boolean useClusterConfigurationService = false;
|
||||
|
||||
private File workingDirectory;
|
||||
|
||||
private Integer port = DEFAULT_PORT;
|
||||
|
||||
private final List<LocatorConfigurer> locatorConfigurers = new ArrayList<>();
|
||||
@@ -120,6 +123,10 @@ public class LocatorFactoryBean extends AbstractFactoryBeanSupport<Locator> impl
|
||||
getLocators().ifPresent(locators -> locatorBuilder.set(LOCATORS_PROPERTY, locators));
|
||||
getName().ifPresent(locatorBuilder::setMemberName);
|
||||
|
||||
getWorkingDirectory()
|
||||
.map(File::getAbsolutePath)
|
||||
.ifPresent(locatorBuilder::setWorkingDirectory);
|
||||
|
||||
locatorBuilder.set(LOG_LEVEL_PROPERTY, getLogLevel());
|
||||
locatorBuilder.setPort(getPort());
|
||||
|
||||
@@ -305,4 +312,49 @@ public class LocatorFactoryBean extends AbstractFactoryBeanSupport<Locator> impl
|
||||
public boolean isUseClusterConfigurationService() {
|
||||
return this.useClusterConfigurationService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file system {@link File directory} in which the {@link Locator} will write all files to disk.
|
||||
*
|
||||
* This configuration setting should not be taken to mean this is the {@link File directory} in which
|
||||
* the {@link Locator} process will run, or in other words, the {@link Locator} process's actual
|
||||
* {@link File working directory}. If this {@link LocatorFactoryBean} is used to create and start
|
||||
* a {@link Locator}, then the {@link Locator} will run in an embedded mode, or the same JVM process
|
||||
* as the Spring application that called this {@link LocatorFactoryBean} and started the {@link Locator})
|
||||
* and therefore will inherit the same {@link File working directory} as the parent Spring application process.
|
||||
*
|
||||
* This configuration property is named after the same
|
||||
* {@link LocatorLauncher.Builder#getWorkingDirectory() workingDirectory} configuration property
|
||||
* on the {@link LocatorLauncher.Builder}.
|
||||
*
|
||||
* @param workingDirectory {@link File directory} in which the {@link Locator} will write its files to disk.
|
||||
* @see org.apache.geode.distributed.LocatorLauncher.Builder#setWorkingDirectory(String)
|
||||
* @see java.io.File
|
||||
*/
|
||||
public void setWorkingDirectory(@Nullable File workingDirectory) {
|
||||
this.workingDirectory = workingDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file system {@link File directory} in which the {@link Locator} will write all files to disk.
|
||||
*
|
||||
* This configuration setting should not be taken to mean this is the {@link File directory} in which
|
||||
* the {@link Locator} process will run, or in other words, the {@link Locator} process's actual
|
||||
* {@link File working directory}. If this {@link LocatorFactoryBean} is used to create and start
|
||||
* a {@link Locator}, then the {@link Locator} will run in an embedded mode, or the same JVM process
|
||||
* as the Spring application that called this {@link LocatorFactoryBean} and started the {@link Locator})
|
||||
* and therefore will inherit the same {@link File working directory} as the parent Spring application process.
|
||||
*
|
||||
* This configuration property is named after the same
|
||||
* {@link LocatorLauncher.Builder#getWorkingDirectory() workingDirectory} configuration property
|
||||
* on the {@link LocatorLauncher.Builder}.
|
||||
*
|
||||
* @return the {@link File directory} in which the {@link Locator} will write its files to disk.
|
||||
* @see org.apache.geode.distributed.LocatorLauncher.Builder#getWorkingDirectory()
|
||||
* @see java.util.Optional
|
||||
* @see java.io.File
|
||||
*/
|
||||
public Optional<File> getWorkingDirectory() {
|
||||
return Optional.ofNullable(this.workingDirectory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -132,6 +133,12 @@ public class LocatorFactoryBeanUnitTests {
|
||||
@Test
|
||||
public void initBuildsLocator() throws Exception {
|
||||
|
||||
File workingDirectory = new File(System.getProperty("java.io.tmpdir"));
|
||||
|
||||
assertThat(workingDirectory)
|
||||
.describedAs("Working directory [%s] does not exist", workingDirectory.getAbsolutePath())
|
||||
.isDirectory();
|
||||
|
||||
Locator mockLocator = mock(Locator.class);
|
||||
|
||||
LocatorLauncher mockLocatorLauncher = mock(LocatorLauncher.class);
|
||||
@@ -150,6 +157,7 @@ public class LocatorFactoryBeanUnitTests {
|
||||
this.locatorFactoryBean.setLocators("host1[1234],host2[6789]");
|
||||
this.locatorFactoryBean.setName("TestMember");
|
||||
this.locatorFactoryBean.setPort(54321);
|
||||
this.locatorFactoryBean.setWorkingDirectory(workingDirectory);
|
||||
this.locatorFactoryBean.init();
|
||||
|
||||
assertThat(this.locatorFactoryBean.getLocator()).isEqualTo(mockLocator);
|
||||
@@ -161,6 +169,7 @@ public class LocatorFactoryBeanUnitTests {
|
||||
verify(locatorBuilderSpy, times(1)).setHostnameForClients(eq("skullbox"));
|
||||
verify(locatorBuilderSpy, times(1)).setMemberName(eq("TestMember"));
|
||||
verify(locatorBuilderSpy, times(1)).setPort(eq(54321));
|
||||
verify(locatorBuilderSpy, times(1)).setWorkingDirectory(eq(workingDirectory.getAbsolutePath()));
|
||||
verify(this.locatorFactoryBean, times(1)).postProcess(eq(locatorBuilderSpy));
|
||||
verify(this.locatorFactoryBean, times(1)).postProcess(eq(mockLocatorLauncher));
|
||||
verify(mockLocatorLauncher, times(1)).start();
|
||||
@@ -203,7 +212,7 @@ public class LocatorFactoryBeanUnitTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getObjectThrowsIllegalStateException() throws Exception {
|
||||
public void getObjectThrowsIllegalStateException() {
|
||||
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.locatorFactoryBean.getObject())
|
||||
|
||||
@@ -16,8 +16,13 @@
|
||||
package org.springframework.data.gemfire.config.annotation;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -29,11 +34,16 @@ import org.apache.geode.distributed.DistributedSystem;
|
||||
import org.apache.geode.distributed.Locator;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.data.gemfire.GemFireProperties;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.LocatorFactoryBean;
|
||||
import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport;
|
||||
import org.springframework.data.gemfire.util.SpringExtensions;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Integration Tests for {@link LocatorApplication} and {@link LocatorApplicationConfiguration} asserting that
|
||||
@@ -112,6 +122,47 @@ public class LocatorApplicationIntegrationTests extends IntegrationTestsSupport
|
||||
bindAddress = "localhost",
|
||||
port = 0
|
||||
)
|
||||
static class TestConfiguration { }
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
LocatorConfigurer workingDirectoryLocatorConfigurer() {
|
||||
|
||||
return (beanName, locatorFactoryBean) -> {
|
||||
|
||||
File workingDirectory = newWorkingDirectory(locatorFactoryBean);
|
||||
|
||||
Function<Throwable, Boolean> workingDirectoryCreationErrorHandler = cause -> {
|
||||
throw newRuntimeException(cause, "Failed to create temporary working directory [%s]", workingDirectory);
|
||||
};
|
||||
|
||||
SpringExtensions.ValueReturningThrowableOperation<Boolean> createWorkingDirectory = () -> {
|
||||
boolean result = workingDirectory.mkdirs();
|
||||
workingDirectory.deleteOnExit();
|
||||
return result;
|
||||
};
|
||||
|
||||
SpringExtensions.safeGetValue(createWorkingDirectory, workingDirectoryCreationErrorHandler);
|
||||
|
||||
assertThat(workingDirectory).isDirectory();
|
||||
|
||||
locatorFactoryBean.setWorkingDirectory(workingDirectory);
|
||||
};
|
||||
}
|
||||
|
||||
private String fromTemporaryDirectory(String... pathElements) {
|
||||
|
||||
StringBuilder relativePath = new StringBuilder(System.getProperty("java.io.tmpdir"));
|
||||
|
||||
Arrays.stream(pathElements)
|
||||
.filter(StringUtils::hasText)
|
||||
.forEach(pathElement -> relativePath.append(File.separator).append(pathElement));
|
||||
|
||||
return relativePath.toString();
|
||||
}
|
||||
|
||||
private @NonNull File newWorkingDirectory(@NonNull LocatorFactoryBean locatorBean) {
|
||||
return new File(fromTemporaryDirectory("locator",
|
||||
locatorBean.getName().orElse("NO-NAME"), UUID.randomUUID().toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user