javasubstitutionplaybackhocon

HOCON conditional substitution with surrounding text


I have no way currently to test this syntax myself, thus the question:

Will substitution/overriding of a value still happen if it's surrounded by text?

For example, I know that:

foo.baseUrl = "http://foo:1234/" foo.baseUrl = ${?FOO_BASE_URL}

will overwrite foo.baseURL if the ENV var FOO_BASE_URL exists.

What happens here?

foo.baseUrl = "http://foo:1234/" foo.baseUrl = "http://${?FOO_BASE_URL}:1234/"

does the override still happen if the ENV var exists? does putting it within a string negate this?


Solution

  • Just ran a quick test, and the second value will replace the first, missing the middle part. So if FOO_BASE_URL is not defined, and application.conf contains the following (note omission of " in the second line, variable substitution is not performed within double quotes):

    foo.baseUrl = "http://foo:1234/"
    foo.baseUrl = http://${?FOO_BASE_URL}:1234/
    foo.baseUrl = ${?FOO_BASE_URL}
    

    The value of foo.baseUrl will be http://:1234/. The not-found variable is considered an empty string in the second line. The relevant quote from the Substitution section of the docs:

    If a substitution with the ${?foo} syntax is undefined:

    • if it is the value of an object field then the field should not be created. If the field would have overridden a previously-set value for the same field, then the previous value remains.
    • if it is an array element then the element should not be added.
    • if it is part of a value concatenation with another string then it should become an empty string; if part of a value concatenation with an object or array it should become an empty object or array.
    • foo : ${?bar} would avoid creating field foo if bar is undefined. foo : ${?bar}${?baz} would also avoid creating the field if both bar and baz are undefined.

    The way to solve this would be to have two variables, first define foo.hostname, and use that to define foo.baseUrl:

    foo.hostname = "foo"
    foo.hostname = ${FOO_HOSTNAME}
    foo.baseUrl = http://${?FOO_HOSTNAME}:1234/