-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#1001 Application-level profile and property management #1109
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
343dabf
to
17f38c1
Compare
5529e1e
to
ffccdf8
Compare
17f38c1
to
549c169
Compare
Base automatically changed from
feature/#1092-module-migration
to
develop/0.7.0
August 11, 2024 11:35
549c169
to
e1dc83b
Compare
# Conflicts: # pom.xml
# Conflicts: # hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/BuildEnvironmentPredicate.java # hartshorn-launchpad/src/test/java/test/org/dockbox/hartshorn/testsuite/ModifyApplicationTests.java
# Conflicts: # pom.xml
e1dc83b
to
aec4c02
Compare
0bdbce9
to
b5e1d81
Compare
1a03511
to
2962126
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Type of Change
Description
These changes introduce two new modules:
hartshorn-properties
andhartshorn-profiles
. The properties module is integrated inhartshorn-inject
,hartshorn-inject-configurations
, andhartshorn-launchpad
. The profiles module is only integrated inhartshorn-launchpad
.Hartshorn Properties
Properties form an important part of Hartshorn applications. Even more so, they play an important role early in the application bootstrapping process. As such, properties should be loaded early on, without the need for additional application components to be present.
Properties are loaded in three phases:
PropertyRegistryLoader
reads configuration sources, definingConfiguredProperty
instances for each configured propertyPropertyRegistry
receives configured properties from the loader, and stores them in an accessible mannerPropertyRegistry
About registry loaders
The default implementations of the
PropertyRegistryLoader
use Jackson object mapping in the background, transforming configuration into trees, which are formatted into individual property paths in the shape ofConfiguredProperty
instances before proceeding to a property registry. Support for YAML and JavaProps is present by default, though additional implementations can be added with relative ease (including other Jackson mapper implementations, if preferred).Note that current loaders are designed for external properties, coming from generic
Path
definitions. System- and environment variables are currently not integrated, but will be followed up in #1121.About configured properties
Configured properties are intermediate property entries. Their main purpose is to allow for the easy identification of properties within a property registry. Configured properties themselves are nothing more than key-value pairs, where the key is the fully qualified name of the property.
For example, for the YAML sample below, the sole
ConfiguredProperty
instance would besample.list[0].value = xyz
.About property registries and properties
The standard
PropertyRegistry
implementation is theMapPropertyRegistry
which, as the name suggests, stores properties in a local map for easy lookup. While registries store 'configured properties', they rarely expose properties in that form. Instead, properties can be exposed in one of three ways:ListProperty
, which is a list of other properties of any of the three main representationsObjectProperty
, which is a map of key-property entries where each property is one of any of the three main representationsValueProperty
, which is a single value property. Values are saved as string values, and can be parsed either manually of through the use of aValuePropertyParser
About property parsing
As properties are only stored as plain string values, they are rarely in the exact shape callers need them (e.g. as a number, enum, or complex types). To support the base scenarios,
StandardValuePropertyParsers
implements various parsers for primitive types, andEnumValuePropertyParser
implements enum support.Additional parsers can be added easily by either implementing
ValuePropertyParser
directly, or by using eitherGenericConverterValuePropertyParser
orConverterValuePropertyParser
with a pre-existingGenericConverter
orConverter
implementation (most primitive parsers use these implementations as well, so you can expect the same behavior for converters and parsers).Property value injection
In most cases you won't need the full flexibility of the property registries, as you'll only want to resolve a single value. While you can achieve this with
PropertyRegistry.value("property.path", SomeConverterValuePropertyParser)
, this is likely a bit overkill, and not the easiest to figure out if you haven't used it before.As such, it's also possible to directly inject property values into your components (or any other supported injection point). Simply annotate your injection point (field or parameter) with
@PropertyValue
and provide a name and optional default value. The default value is only used if there is no property with the given name.There are four permitted scenarios for property value injection:
ValueProperty
(1),ListProperty
(2), orObjectProperty
(3), in which case the property is directly obtained from the registryValueProperty
is resolved from the property registry, and passed to theConversionService
. All pre-existing string-to-xyz converters are supported. Additional converters which convert eitherValueProperty
orString
to a target type are also supported.Hartshorn Profiles
The profiles module builds on top of the properties module, adding the ability to separate configurations for different scenarios (such as different environments or deployment goals). Profiles are loaded based on the value of the
hartshorn.profiles
property, which is read from the 'root' property registry. The root registry is the first registry to be loaded, typically fromapplication.yml | .properties
files.This module is relatively small, and only adds a utility layer to easily work with multiple profiles in a hierarchical manner. In Launchpad this is integrated more deeply to bootstrap the configurations when the application starts.
Checklist
develop
branchRelated Issue
Closes #1001