If user has @EnableDiscoveryClient but no implementation (e.g. if he
just has @EnableZuulProxy) the autoconfig will now kick in and
provide an instance of NoopDiscoveryClient.
Fixes gh-80
This commit introduces support to easily discover resources in remote
service APIs and periodically validating they're still available.
The core concept is a RemoteResource and its primary implementation
DiscoveredResource which consists of a ServiceInstanceProvider and a
TraversalDescription. The service instance provider abstracts the location
of the service the DiscoveredResource is hosted at. Currently there are
two implementations available: a StaticServiceInstanceProvider that — as
the name suggests — returns a statically configured instance, as well as
the DynamicServiceInstanceProvider which takes a DiscoveryClient and service
name as input to dynamically discover the ServiceInstance on request.
The TraversalDefinition is a SAM type that allows to define the path traversals
that shall be executed to discover the target resource within the service
instance. This allows the following configuration:
DiscoveryClient client = …
ServiceInstanceProvider provider = new DynamicServiceInstanceProvider(client, "stores");
RemoteResource resource = new DiscoveredResource(provider, traverson -> traverson.follow("stores", "search", "by-location");
This will cause the following to happen:
1. In this default state the resource is undiscovered and calls to getLink()
will return null.
2. A call to verifyOrDiscover() will trigger resource discovery, i.e. lookup
the service instance using the discovery client, execute the path traversal
as defined and store the final link discovered ("by-location") in the
discovered resource.
3. Calls to getLink() will return that link. Calls to verifyOrDiscover()
will issue a HEAD request to verify the resource is still available and
reset the link if not. Subsequent calls to verifyOrDiscover() will trigger
rediscovery.
That means that we basically shield against either the service instance becoming
unavailable or the resource becoming unavailable within the service instance
(due to some URI restructuring or the like).
The calls to verifyOrDiscover() are currently automated by a RemoteResourceRefresher
which is auto-configured if a RemoteResource is declared as Spring bean
and its initial and fixed delay can be configured via properties in the
spring.cloud.hypermedia namespace.
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
That'll show me for trying to code right before the holidays.
Not only was the auto-config in the WRONG package, I forgot to enable it in autoconfiguration!
fixes gh-bonehead
Otherwise multiple instances of a scoped target can be created
if several threads need one at the same time. This isn't always
going to be a problem, but it breaks the singleton semantics, and
might lead to surprising results and/or performance issues if bean
creation is expensive.
It's kind of a corner case, but not a very small corner: if a /refresh
leads to a change in a key that was overridden from its default value (e.g.
n a profile-specific config file) then the key is not identified as changed.
The change is still applied.
This commit fixes the key computation and adds a couple of tests.
Fixes gh-73
The problem is that we do want bootstrap properties to override
default properties in most cases, but if they are decrypted those
values have to be added with the highest possible precedence.
Fixes gh-54