-
Notifications
You must be signed in to change notification settings - Fork 535
7457 introduce mpconfig #7463
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
Merged
Merged
7457 introduce mpconfig #7463
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
74f35d8
Introduce Eclipse MicroProfile Config API to the project. #7000
poikilotherm 13447f9
Add MicroBean MicroProfile Config API implementation as a test depend…
poikilotherm a74cc52
Update Testcontainers to 1.15.0.
poikilotherm a535ce8
Introducing an MPCONFIG alias config source. #7457
poikilotherm 5cd0ee9
Merge branch 'develop' into 7457-introduce-mpconfig
poikilotherm 7a2433e
Add missing name to AliasConfigSource. #7457
poikilotherm f7407e3
Adding a config source to retrieve Dataverse DB settings from MicroPr…
poikilotherm 620e9ab
Refactor AliasConfigSource to be more testable and rename aliases fil…
poikilotherm ebf83e2
Fix error in AliasConfigSource, not looking at keys but values of the…
poikilotherm e1cb339
Add tests for AliasConfigSource. #7457
poikilotherm fdb043d
Add integration testing for DbSettingConfigSource to ensure data retr…
poikilotherm b1ea846
Change pom.xml to include the MicroProfile Config API SPI definitions…
poikilotherm 429ea21
Add some docs about introducing MPCONFIG to the dev guide.
poikilotherm 5f73b45
Extend dev docs about MPCONFIG. #7457
poikilotherm 2ffa4c1
Fix DbSettingConfigSource not to throw an exception if the DataSource…
poikilotherm a44b0a4
Refactor DbSettingConfigSource to rely on the SettingsServiceBean, in…
poikilotherm ecc277c
Log warning message for DbSettingConfigSource if the settings service…
poikilotherm e6f38ee
More dev documentation of MPCONFIG usage and sources. #7457
poikilotherm ffe775e
Add release notes for #7457
poikilotherm 00b9533
Add javadoc about what is DbSettingConfigHelper. #7457
poikilotherm f4a88a1
Make Sphinx happy by removing a redundant space in dev docs about con…
poikilotherm f135050
add toc #7457
pdurbin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| ## Introducing MicroProfile Config API | ||
|
|
||
| With this Dataverse release, we start to make use of the MicroProfile Config API. (As you might have noticed | ||
| for the database connection settings.) | ||
|
|
||
| This will benefit both devs and sysadmins, but the codebase will have to be refactored to make use of it. | ||
| As this will take time, we will always provide a backward compatible way of using it. | ||
|
|
||
| For more details, please see the development guide about "Consuming Configuration", which also | ||
| explains the benefits in more detail. |
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| Consuming Configuration | ||
| ======================= | ||
|
|
||
| .. contents:: |toctitle| | ||
| :local: | ||
|
|
||
| Dataverse uses different types of configuration: | ||
|
|
||
| 1. JVM system properties | ||
| 2. Simple database value settings | ||
| 3. Complex database stored data structures | ||
|
|
||
| 1 and 2 are usually simple text strings, boolean switches or digits. All of those can be found in :doc:`/installation/config`. | ||
|
|
||
| Anything for 3 is configured via the API using either TSV or JSON structures. Examples are metadata blocks, | ||
| authentication providers, harvesters and others. | ||
|
|
||
| Simple Configuration Options | ||
| ---------------------------- | ||
|
|
||
| Developers have accessed the simple properties via | ||
|
|
||
| 1. ``System.getProperty(...)`` for JVM system property settings | ||
| 2. ``SettingsServiceBean.get(...)`` for database settings and | ||
| 3. ``SystemConfig.xxx()`` for specially treated settings, maybe mixed from 1 and 2 and other sources. | ||
| 4. ``SettingsWrapper``, reading from 2 and 3 for use in frontend pages based on JSF | ||
|
|
||
| As of Dataverse 5.3, we start to streamline our efforts into using a more consistent approach, also bringing joy and | ||
| happiness to all the system administrators out there. This will be done by adopting the use of | ||
| `MicroProfile Config <https://github.com/eclipse/microprofile-config>`_ over time. | ||
|
|
||
| So far we streamlined configuration of these Dataverse parts: | ||
|
|
||
| - ✅ Database Connection | ||
|
|
||
| Complex Configuration Options | ||
| ----------------------------- | ||
|
|
||
| We should enable variable substitution in JSON configuration. Example: using substitution to retrieve values from | ||
| MicroProfile Config and insert into the authentication provider would allow much easier provisioning of secrets | ||
| into the providers. | ||
|
|
||
| Why should I care about MicroProfile Config API? | ||
| ------------------------------------------------ | ||
|
|
||
| Developers benefit from: | ||
|
|
||
| - A streamlined API to retrieve configuration, backward-compatible renaming strategies and easier testbed configurations. | ||
| - Config API is also pushing for validation of configuration, as it's typesafe and converters for non-standard types | ||
| can be added within our codebase. | ||
| - Defaults in code or bundled in ``META-INF/microprofile-config.properties`` allow for optional values without much hassle. | ||
|
|
||
| System administrators benefit from: | ||
|
|
||
| - Lots of database settings have been introduced in the past, but should be more easily configurable and not rely on a | ||
| database connection. | ||
| - Running Dataverse in containers gets much easier when configuration can be provisioned in a | ||
| streamlined fashion, mitigating the need for scripting glue and distinguishing between setting types. | ||
| - Classic installations have a profit, too: we can enable using a single config file, e.g. living in | ||
| ``/etc/dataverse/config.properties``. | ||
| - Features for monitoring resources and others are easier to use with this streamlined configuration, as we can | ||
| avoid people having to deal with ``asadmin`` commands and change a setting comfortably instead. | ||
|
|
||
| Adopting MicroProfile Config API | ||
| --------------------------------- | ||
|
|
||
| This technology is introduced on a step-by-step basis. There will not be a big shot, crashing upgrades for everyone. | ||
| Instead, we will provide backward compatibility by deprecating renamed or moved config options, while still | ||
| supporting the old way of setting them. | ||
|
|
||
| - Introducing a new setting or moving and old one should result in a key ``dataverse.<scope/task/module/...>.<setting>``. | ||
| That way we enable sys admins to recognize the meaning of an option and avoid name conflicts. | ||
| Starting with ``dataverse`` makes it perfectly clear that this is a setting meant for this application, which is | ||
| important when using environment variables, system properties or other MPCONFIG sources. | ||
| - Replace ``System.getProperty()`` calls with either injected configs or retrieve programmatically if more complex | ||
| handling is necessary. If you rename the property, you should provide an alias. See below. | ||
| - Database settings need to be refactored in multiple steps. First you need to change the code retrieving it to use | ||
| MicroProfile Config API instead (just like above). Then you should provide an alias to retain backward compatibility. | ||
| See below. | ||
|
|
||
| Moving or Replacing a JVM Setting | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| When moving an old key to a new (especially when doing so with a former JVM system property setting), you should | ||
| add an alias to ``src/main/resources/META-INF/microprofile-aliases.properties`` to enable backward compatibility. | ||
| The format is always like ``dataverse.<scope/....>.newname...=old.property.name``. | ||
|
|
||
| Details can be found in ``edu.harvard.iq.dataverse.settings.source.AliasConfigSource`` | ||
|
|
||
| Aliasing Database Setting | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| When moving a database setting (``:ExampleSetting``), configure an alias | ||
| ``dataverse.my.example.setting=dataverse.settings.fromdb.ExampleSetting`` in | ||
| ``src/main/resources/META-INF/microprofile-aliases.properties``. This will enable backward compatibility. | ||
|
|
||
| A database setting with an i18n attribute using *lang* will have available language codes appended to the name. | ||
| Example: ``dataverse.settings.fromdb.ExampleI18nSetting.en``, ``dataverse.settings.fromdb.ExampleI18nSetting.de`` | ||
|
|
||
| More details in ``edu.harvard.iq.dataverse.settings.source.DbSettingConfigSource`` |
This file contains hidden or 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
This file contains hidden or 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
This file contains hidden or 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
98 changes: 98 additions & 0 deletions
98
src/main/java/edu/harvard/iq/dataverse/settings/source/AliasConfigSource.java
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| package edu.harvard.iq.dataverse.settings.source; | ||
|
|
||
| import org.eclipse.microprofile.config.ConfigProvider; | ||
| import org.eclipse.microprofile.config.spi.ConfigSource; | ||
|
|
||
| import java.io.IOException; | ||
| import java.net.URL; | ||
| import java.util.HashMap; | ||
| import java.util.HashSet; | ||
| import java.util.Map; | ||
| import java.util.Properties; | ||
| import java.util.Set; | ||
| import java.util.concurrent.ConcurrentHashMap; | ||
| import java.util.logging.Logger; | ||
|
|
||
| /** | ||
| * Enable using an old name for a new config name. | ||
| * Usages will be logged and this source will ALWAYS stand back if the new name is used anywhere. | ||
| * | ||
| * By using a DbSettingConfigSource value (dataverse.settings.fromdb.XXX) as old name, we can | ||
| * alias a new name to an old db setting, enabling backward compatibility. | ||
| */ | ||
| public final class AliasConfigSource implements ConfigSource { | ||
|
|
||
| private static final Logger logger = Logger.getLogger(AliasConfigSource.class.getName()); | ||
|
|
||
| private final ConcurrentHashMap<String, String> aliases = new ConcurrentHashMap<>(); | ||
| private final String ALIASES_PROP_FILE = "META-INF/microprofile-aliases.properties"; | ||
|
|
||
| public AliasConfigSource() { | ||
| try { | ||
| // read properties from class path file | ||
| Properties aliasProps = readAliases(ALIASES_PROP_FILE); | ||
| // store in our aliases map | ||
| importAliases(aliasProps); | ||
| } catch (IOException e) { | ||
| logger.info("Could not read from "+ALIASES_PROP_FILE+". Skipping MPCONFIG alias setup."); | ||
| } | ||
| } | ||
|
|
||
| Properties readAliases(String filePath) throws IOException { | ||
| // get resource from classpath | ||
| ClassLoader classLoader = this.getClass().getClassLoader(); | ||
| URL aliasesResource = classLoader.getResource(filePath); | ||
|
|
||
| // load properties from file resource (parsing included) | ||
| Properties aliasProps = new Properties(); | ||
| try { | ||
| aliasProps.load(aliasesResource.openStream()); | ||
| } catch (NullPointerException e) { | ||
| throw new IOException(e.getMessage()); | ||
| } | ||
| return aliasProps; | ||
| } | ||
|
|
||
| void importAliases(Properties aliasProps) { | ||
| aliasProps.forEach((key, value) -> aliases.put(key.toString(), value.toString())); | ||
| } | ||
|
|
||
| @Override | ||
| public Map<String, String> getProperties() { | ||
| // No, just no. We're not going to drop a list of stuff. We're only | ||
| // dealiasing on getValue(); | ||
| return new HashMap<>(); | ||
| } | ||
|
|
||
| @Override | ||
| public Set<String> getPropertyNames() { | ||
| // It does not make sense to retrieve the aliased names... | ||
| return new HashSet<>(); | ||
| } | ||
|
|
||
| @Override | ||
| public int getOrdinal() { | ||
| // Any other config source can override us. | ||
| // As soon as someone is starting to use the new property name, this alias becomes pointless. | ||
| return Integer.MIN_VALUE; | ||
| } | ||
|
|
||
| @Override | ||
| public String getValue(String key) { | ||
| String value = null; | ||
| if (this.aliases.containsKey(key)) { | ||
| String oldKey = this.aliases.get(key); | ||
| value = ConfigProvider.getConfig().getOptionalValue(oldKey, String.class).orElse(null); | ||
|
|
||
| if (value != null) { | ||
| logger.warning("Detected deprecated config option '"+oldKey+"' in use. Please update your config to use '"+key+"'."); | ||
| } | ||
| } | ||
| return value; | ||
| } | ||
|
|
||
| @Override | ||
| public String getName() { | ||
| return "Alias"; | ||
| } | ||
| } |
27 changes: 27 additions & 0 deletions
27
src/main/java/edu/harvard/iq/dataverse/settings/source/DbSettingConfigHelper.java
This file contains hidden or 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package edu.harvard.iq.dataverse.settings.source; | ||
|
|
||
| import edu.harvard.iq.dataverse.settings.SettingsServiceBean; | ||
|
|
||
| import javax.annotation.PostConstruct; | ||
| import javax.ejb.EJB; | ||
| import javax.ejb.Singleton; | ||
| import javax.ejb.Startup; | ||
|
|
||
| /** | ||
| * This is a small helper bean for the MPCONFIG DbSettingConfigSource. | ||
| * As it is a singleton and built at application start (=deployment), it will inject the (stateless) | ||
| * settings service into the MPCONFIG POJO once it's ready. | ||
| * | ||
| * MPCONFIG requires it's sources to be POJOs. No direct dependency injection possible. | ||
| */ | ||
| @Singleton | ||
| @Startup | ||
| public class DbSettingConfigHelper { | ||
| @EJB | ||
| SettingsServiceBean settingsSvc; | ||
|
|
||
| @PostConstruct | ||
| public void injectService() { | ||
| DbSettingConfigSource.injectSettingsService(settingsSvc); | ||
| } | ||
| } |
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.