We need to tread a very fine line. Ideally the process of refreshing
the Environment builds it back exactly as happened on startup.
In particular we probably don't want to have things like
application.properties already there when we start the process.
This change replaces the more liberal copy of all property sources
only a select few (actually only one), paremeterized as a constant.
If there were *no* bootstrapProperties (i.e. properties added by
PropertySourceLocators) on startup, and then in a refresh event
some new sources were picked up, they would have been added to the
end, instead of the beginning of the list.
Fixes https://github.com/spring-cloud/spring-cloud-config/issues/815
When the Environment is resetted the EnvironmentChangedEvent always
contains an empty keySet, since the live view of the cleared map was
used. This commit fixes this.
Instead it depends on ContextRefresher with actually does the work.
This allows applications to use the listener even if they don't depend
on actuator.
fixes gh-171
The fix for gh-153 was sensible, but has now exposed another issue
which is that the bootstrap initializers, whilst they are now only
created once, actually only get applied to the parent context
in a hierarchy.
Most of the time this doesn't matter because the child contexts all
benefit from environment changes and additional beans added
to the parent. If the children are supposed to actually have
different environments, though, there is a problem. So this change
locates the existing bootstrap context and applies it to each
new context created separately.
Unfortunately we have to use reflection to do that for now because
there is no way to discover the parent with a public API before
the context is refreshed.
See gh-190
For RefreshScope this stops Spring from moaning about the @Bean
method with a WARN log (which is benign but hard to get rid of
and confusing for users).
See gh-401
Given the following in one property source
```
mine[0].someValue=Foo
mine[0].someKey={cipher}XXXX
mine[1].someValue=Bar
mine[1].someKey={cipher}XXXX
yours[0].anotherKey=Baz
```
only `mine[*].someKey` were added to "decrypted" property source. Due to house spring boot manages indexed properties, they can not be merged across property source. This change includes all indexed properties in the "decrypted" property source if any one of them is encrypted.
In the above example, `yours[*].*` is included even though unrelated.
fixes gh-466
A couple of tests here make assumptions about the property source
names added using @IntegrationTest. If we are a bit more defensive
and search for a source with a matching name instead of grabbing
one by the precise name, we can have tests that pass in Boot 1.3
and 1.4.
When the bootstrap properties are added back into the main Environment
we have to be careful that any source that is already there (such as
one that was added in a Spring Boot EnvironmentPostProcessor) is not
replaced in the wrong order.
Fixes gh-90
Use SystemEnvironmentPropertySource so that env vars can be
encrypted as well as property values (i.e. FOO_BAR will bind to
@Value("foo.bar")).
Fixes gh-89, fixes gh-87
When the RefreshEndpoint makes a new Environment it creates a new
ApplicationContext with (hopefully) empty sources. If the user has
set spring.main.sources it won't be empty, so we should take care
to mask it off in the process.
Fixes gh-79
Repots DOWN if there are errors in RefreshScope or
ConfigurationProperties rebinding, N.B. RefreshScope instantiates
its beans lazily after a refresh by default, so you won't see an
error until the bean is used.
Fixes gh-85
The fact that PropertySourceBootstrapConfiguration was re-using the
"bootstrap" property source name from the listener was a problem. The
listener has to be able to manage its own temporary property source name.
Fixes gh-83
The bootstrap.properties need to stick with the default properties
during the process of initializing the application.properties
otherwise the ordering ends up wrong because of the addLast()
semantics in an Environment merge. To do this is a bit ugly with
the additional constraint that the default properties has to
remain a MapPropertySource (so that other processors can append
to it if needed). So we created a custom extension of
MapPropertySource that also carries all the bootstrap properties
during the phase where the application.properties are being
processed, but unpacks them as soon as possible afterwards
in an ApplicationContextInitializer, preserving the order, but
making the bootstrap.properties available effectively for the
whole of the startup and initializaion phase of the main context.
The biggest problem addressed here is one where an
EnvironmentPostProcessor (reasonably) adds entries to the
defaultProperties in the bootstrap context, but then that
property source is not merged with the parent, or is merged
too late (because it only happens when the application context
parent is set). The result would be that things that were activated
during bootstrap would be not be activated in the main context, or
would be activated too late (early enough for beans to bind to but
not for other listeners and post processors to get access to the
additional properties).
See https://github.com/spring-cloud/spring-cloud-sleuth/issues/126
We only need one special name for a property source. In the end it
gets used twice, but this simplifies the logic a bit and ensures that
there is never a PropertySource with that name and things like
spring.application.name=bootstrap in it.
This ensures that any fetaures that require a bean to be instantiated
(for instance @Scheduled) behave the same for @RefreshScope and normal
singletons.
Fixes gh-74