Reputation: 7788
I have a springboot commandline app where one of the production commandline args is the absolute base path. For this example we will call it
"/var/batch/"
I'm setting the basepath in my production.yml file like so with a default value.
company: basePath: ${basePath:/var/default/}
I then have an ApplicationConfig.java file that uses that base path to create a bunch of file paths like so.
@ConfigurationProperties(prefix = "company")
public class ApplicationConfig {
private String basePath;
public String getPrimaryCarePath() {
return basePath + "ADAP-2-PCProv.dat";
}
public String getPrimaryCareDetailPath() {
return basePath + "ADAP-2-" + getBatchNo() + ".det";
}
... additional files.
}
Lastly the file paths get passed into my css parser like so.
public List<T> readCsv() throws IOException {
try (BufferedReader bufferedReader = Files.newBufferedReader(Paths.get(filePath))) {
return new CsvToBeanBuilder(bufferedReader)
.withFieldAsNull(CSVReaderNullFieldIndicator.EMPTY_SEPARATORS)
.withType(subClass)
.withSeparator('\t')
.withIgnoreLeadingWhiteSpace(true)
.build().parse();
}
}
Now everything works fine in production, but we face some issues when attempting to run mutation test. It appears as if the csv parser is looking for an absolute path rather than a relative path. We have the following path in our application-test.yml file.
company:
basePath: src/test/resources/
All our test files are stored in the test resources package, so my question is how can we use a relative path to the test resources populating the ApplicationConfig.java file while still being able to use an absolute path for production? I was thinking I could override the basepath with the test setup using ClassPathResource, but was wondering if there was a better approach.
Upvotes: 1
Views: 432
Reputation: 2109
You need 2 types of configurations : one for resources and one for absolute path.
I would suggest to add a new property app.file.path.type
with values resources
and absolute
. You can define a new interface named FileProvider
.
public interface FilePathProvider(){
Path getFilePath();
}
You can define 2 different beans with @ConditionalOnProperty
and set the file path strategy:
@Configuration
public class ApplicationConfig{
@Bean
@ConditionalOnProperty(
name = "app.file.path.type",
havingValue = "absolute")
public FilePathProvider absoluteFilePathProvider(ApplicationConfig applicationConfig){
return () -> Paths.get(applicationConfig.getBasePath());
}
@ConditionalOnProperty(
name = "app.file.path.type",
havingValue = "resources")
@Bean
public FilePathProvider resourceFilePathProvider(ApplicationConfig applicationConfig){
return () -> Paths.get(this.getClass().getClassLoader().getResource(applicationConfig.getBasePath()).getPath());
}
}
In development and test mode, you will have app.file.path.type=resources
and in production you will have app.file.path.type=absolute
.
The advantage of this approach is that you can set the property to absolute
in development as well.
Upvotes: 1