Skip to content

Commit

Permalink
Pass LoaderContext to providers
Browse files Browse the repository at this point in the history
  • Loading branch information
agentgt committed Jan 9, 2025
1 parent a02e034 commit dc319c0
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 deletions.
8 changes: 5 additions & 3 deletions doc/overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ <h4 id="uri-schema-provider">URI schema: <code>provider</code></h4>
This is akin to
<a href="https://github.com/lightbend/config?tab=readme-ov-file#standard-behavior">
Lightbend/Typesafe Config <code>reference.conf</code></a> but without a resource
call for maximum portability with things like GraalVM native, and modular applications
call for maximum portability with things like GraalVM native, Maven Shade plugin, and modular applications
where the config could be an enscapulated resource (properties file) which would
require the module to do the loading and not EZKV.
</p>
Expand All @@ -476,10 +476,10 @@ <h4 id="uri-schema-provider">URI schema: <code>provider</code></h4>
In our database layer we would create a class like:

{@snippet :
class DatabaseConfigProvider implements KeyValuesServiceProvider.KeyValuesProvider {
public class DatabaseConfigProvider implements KeyValuesServiceProvider.KeyValuesProvider {

@Override
public void provide(KeyValues.Builder builder) {
public void provide(KeyValues.Builder builder, LoaderContext context) {
builder.add("database.port", "5245");
}

Expand All @@ -488,6 +488,8 @@ <h4 id="uri-schema-provider">URI schema: <code>provider</code></h4>

And then register it using the {@link java.util.ServiceLoader} registration with
the service class of {@link io.jstach.ezkv.kvs.KeyValuesServiceProvider}.
See {@link io.jstach.ezkv.kvs.KeyValuesServiceProvider.KeyValuesProvider}
for more details on proper usage.

<h3 id="keyvaluesmedia">KeyValuesMedia</h3>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ protected KeyValues load(LoaderContext context, KeyValuesResource resource) thro
.findFirst()
.orElseThrow(() -> new FileNotFoundException("Provider not found. name='" + path + "'"));
var builder = KeyValues.builder(resource);
provider.provide(builder);
provider.provide(builder, context);
return builder.build();

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ default int order() {
* {@value KeyValuesResource#SCHEMA_PROVIDER} URI scheme. This is akin to
* <a href="https://github.com/lightbend/config?tab=readme-ov-file#standard-behavior">
* Lightbend/Typesafe Config <code>reference.conf</code></a> but without a resource
* call for maximum portability with things like GraalVM native, and modular
* applications where the config could be an enscapulated resource (properties file)
* which would require the module to do the loading and not EZKV.
* call for maximum portability with things like GraalVM native, Maven shade plugin,
* and modular applications where the config could be an enscapulated resource
* (properties file) which would require the module to do the loading and not EZKV.
* <p>
* If one would like to load configuration from say properties file the implementation
* will have to do that on its own but is free to use the out of box
Expand All @@ -84,12 +84,17 @@ default int order() {
* example constructing a JDBC URL from a default port that is also provided). The
* idea again is that this reference config that needs to be guaranteed to be there
* for defaults and possibly participate in downstream variable/interpolation usage.
* <strong> It is highly recommended that you do not initialize other parts of the
* module that would initialize logging or something that needs configuration!
* </strong> If you need to use logging use the EZKV logging:
* {@link KeyValuesEnvironment#getLogger()} which will by default not initialize a
* logging framework.
*
* <strong>Example</strong>
* {@snippet :
* class DatabaseConfigProvider implements KeyValuesServiceProvider.KeyValuesProvider {
* public class DatabaseConfigProvider implements KeyValuesServiceProvider.KeyValuesProvider {
*
* public void provide(KeyValues.Builder builder) {
* public void provide(KeyValues.Builder builder, LoaderContext context) {
* builder.add("database.host", "localhost");
* builder.add("database.port", "5245");
* builder.add("database.schema", "mydb");
Expand All @@ -98,20 +103,60 @@ default int order() {
*
* }
* }
*
*
* Down stream <code>database.port</code> could be overriden.
*
* <p>
* Another common usage is some module has an {@link Enum} of configuration options.
* This extension point allows you to fill configuration programmatically so you can
* loop through the enum instances and add the default properties.
*
* {@snippet :
* public class ContextPathProvider implements KeyValuesServiceProvider.KeyValuesProvider {
* public enum ContextPath { // for example purposes this an inner class
* ACCOUNT("/account"), PROFILE("/profile");
*
* final String path;
*
* ContextPath(String path) {
* this.path = path;
* }
* }
*
* public void provide(KeyValues.Builder builder, LoaderContext context) {
* for (ContextPath p : ContextPath.values()) {
* builder.add("contextpath." + p.name().toLowerCase(), p.path);
* }
* }
* }
* }
*
* Note that providers can make {@link KeyValuesResource#KEY_LOAD} keys to load other
* resources if they really would like to have resources loaded.
*
* @see KeyValuesResource#SCHEMA_PROVIDER
*/
public non-sealed interface KeyValuesProvider extends KeyValuesServiceProvider {

// TODO maybe should make another Context class for this

/**
* Implementations should use the mutable builder to add key values. The provided
* builder will already be preconfigured based on the {@link #name()} and other
* resource meta data.
* <p>
* <strong> It is highly recommended that you do not initialize to many things in
* this call that would initialize logging or something that needs configuration!
* </strong>
* <p>
* If you need to use logging use the EZKV logging:
* {@link KeyValuesEnvironment#getLogger()} which will by default not initialize a
* logging framework.
* @param builder used to add key values.
* @param context current load context should be used mainly to use
* {@link KeyValuesEnvironment#getLogger()} and to help parse literal strings that
* are properties.
*/
void provide(KeyValues.Builder builder);
void provide(KeyValues.Builder builder, LoaderContext context);

/**
* The name used to identify where the key values are coming from. The name should
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.junit.jupiter.api.Test;

import io.jstach.ezkv.kvs.KeyValuesEnvironment.Logger;
import io.jstach.ezkv.kvs.KeyValuesServiceProvider.KeyValuesLoaderFinder.LoaderContext;
import io.jstach.ezkv.kvs.KeyValuesServiceProvider.KeyValuesProvider;

class KeyValuesSystemTest {
Expand All @@ -26,7 +27,7 @@ class KeyValuesSystemTest {
record MyProvider() implements KeyValuesProvider {

@Override
public void provide(KeyValues.Builder builder) {
public void provide(KeyValues.Builder builder, LoaderContext context) {
builder.add("ref1", "refValue");
}

Expand Down

0 comments on commit dc319c0

Please sign in to comment.