Ok, I have tried the following and it's not producing the effect that I'd have wished for. I have a reference.conf
specifying filesystem locations relative to a prefix, which looks somewhat like this:
// reference.conf
myapp {
// The dummy path makes the error message easy to diagnose
s3.prefix = "s3://environment/variable/S3_PREFIX/missing"
s3.prefix = ${?S3_PREFIX}
file1 = ${myapp.s3.prefix}"/file1.csv"
file2 = ${myapp.s3.prefix}"/file2.csv"
// ...
}
And then I supply an application.conf
file that looks more or less like this:
// application.conf
myapp.s3.prefix = "s3://some-bucket/some/path/to/the/files"
myapp.file2 = "s3://some-other-bucket/some/path/file2.csv"
Now, when my application does a ConfigFactory.load()
, from :
- Parse the
reference.conf
file, perform the substitutions, and generate aConfig
object where:myapp.s3.prefix = "/environment/variable/S3_PREFIX/missing"
myapp.file1 = "/environment/variable/S3_PREFIX/missing/file1.csv"
myapp.file2 = "/environment/variable/S3_PREFIX/missing/file2.csv"
.
- Parse the
application.conf
file and generate aConfig
object where:library.prefix = "/some/path/to/the/files"
myapp.file2 = "s3://some-other-bucket/some/path/file2.csv"
.
- Merge the two objects, with the
reference.conf
object as fallback. The resultingConfig
object therefore has:library.prefix = "s3://some-bucket/some/path/to/the/files"
(as inapplication.conf
)library.file1 = "s3://environment/variable/S3_PREFIX/missing/file1.csv"
(as inreference.conf
).library.file2 = "s3://some-other-bucket/some/path/file2.csv"
(as inapplication.conf
).
But as you may have guessed from my example, what I'm trying to do is have the reference.conf
specify default paths relative to a root directory, and allow any mix of both of these:
- Override the default root directory from the
application.conf
, so that the default relative paths from thereference.conf
are looked up from there. - Override the path for any individual file in the
application.conf
, so the application can use a path not in the root directory.
The only thing I've been able to come up with so far is this:
// reference.conf
myapp {
// The dummy path makes the error message easy to diagnose
s3.prefix = "s3:/environment/variable/S3_PREFIX/missing"
s3.prefix = ${?S3_PREFIX}
file1 = "file1.csv"
file2 = "file2.csv"
// ...
}
// application.conf
myapp.s3.prefix = "s3://some-bucket/some/path/to/the/files"
myapp.file2 = "s3://some-other-bucket/some/path/file2.csv"
// The Java code for using the config must append prefix and file location,
// and needs to have smarts about relative vs. absolute paths.
final Config CONF = ConfigFactory.load();
String getS3URLFor(String file) {
String root = CONF.getString("myapp.s3.prefix");
String path = CONF.getString("myapp." + file);
return relativeVsAbsoluteSensitiveMerge(root, path);
}
String relativeVsAbsoluteSensitiveMerge(String root, String path) {
if (isAbsoluteReference(path)) {
return path;
} else {
return root + "/" + path;
}
}
boolean isAbsoluteReference(String path) {
// ...
}
I don't really like this solution. Can anybody think of something better?
You can parse first and then resolve: