├── docs └── gestalt-static │ ├── static │ ├── .nojekyll │ └── img │ │ ├── favicon.ico │ │ ├── docusaurus.png │ │ └── docusaurus-social-card.jpg │ ├── babel.config.js │ ├── src │ ├── pages │ │ ├── markdown-page.md │ │ └── index.module.css │ ├── components │ │ └── HomepageFeatures │ │ │ └── styles.module.css │ └── css │ │ └── custom.css │ ├── docs │ ├── tutorial │ │ ├── retrieving-configurations │ │ │ └── _category_.json │ │ ├── annotations │ │ │ └── _category_.json │ │ ├── loading-configuration │ │ │ └── _category_.json │ │ ├── tags-configuration │ │ │ └── _category_.json │ │ └── samples.md │ ├── architecture │ │ ├── overview.md │ │ ├── sentence-lexer.md │ │ └── config-loader.md │ └── modules │ │ ├── kodein-injection.md │ │ ├── koin-injection.md │ │ └── guice-injection.md │ ├── tsconfig.json │ ├── .gitignore │ ├── README.md │ └── sidebars.ts ├── gestalt-core ├── src │ ├── test │ │ ├── resources │ │ │ ├── employee │ │ │ ├── empty.properties │ │ │ ├── myFile.txt │ │ │ ├── serviceMode.txt │ │ │ ├── kubernetes │ │ │ │ ├── db.host.password │ │ │ │ ├── subservice.booking.token │ │ │ │ └── db.host.uri │ │ │ ├── include.properties │ │ │ ├── test │ │ │ ├── test.properties │ │ │ ├── dev.properties │ │ │ ├── integration.properties │ │ │ ├── logging.properties │ │ │ ├── default.properties │ │ │ ├── defaultPPSys.properties │ │ │ └── defaultPPEnv.properties │ │ └── java │ │ │ └── org │ │ │ └── github │ │ │ └── gestalt │ │ │ └── config │ │ │ ├── test │ │ │ └── classes │ │ │ │ ├── Colours.java │ │ │ │ ├── DBInfoInterface.java │ │ │ │ ├── DBInfoInterface2.java │ │ │ │ ├── DBInfoInterfaceDefault.java │ │ │ │ ├── DBInfoInterfaceOptional.java │ │ │ │ ├── IDBInfoMethodAnnotations.java │ │ │ │ ├── IDBInfoAnnotations.java │ │ │ │ ├── IDBInfoBadAnnotations.java │ │ │ │ ├── IDBInfoAnnotationsLong.java │ │ │ │ ├── DBPool.java │ │ │ │ ├── DBPoolInterface.java │ │ │ │ ├── DBPoolInterfaceDefault.java │ │ │ │ ├── DBPoolGenericInterface.java │ │ │ │ ├── DBPoolInterfaceWrapper.java │ │ │ │ ├── ObjectWithWithoutDefaultsPrimitive.java │ │ │ │ ├── ObjectWithDefaultsPrimitive.java │ │ │ │ ├── ObjectWithoutDefaultsWrapper.java │ │ │ │ ├── DBPoolInterfaceDefaultGeneric.java │ │ │ │ ├── DBInfoExtended.java │ │ │ │ ├── ObjectWithDefaultsWrapper.java │ │ │ │ ├── ObjectWithZeroDefaultsWrapper.java │ │ │ │ ├── DBInfoExtendedDefault.java │ │ │ │ ├── DBInfo.java │ │ │ │ ├── DBInfoGeneric.java │ │ │ │ ├── DBInfoIntegerPort.java │ │ │ │ ├── DBInfoSetterChangeValue.java │ │ │ │ ├── DBInfoStatic.java │ │ │ │ ├── DBInfoNoConstructor.java │ │ │ │ ├── DBInfoIntegerPortNonNullGetter.java │ │ │ │ ├── DBInfoPathAnnotation.java │ │ │ │ ├── DBInfoPrivateConstructor.java │ │ │ │ ├── DBInfoBadAnnotations.java │ │ │ │ ├── DBInfoOptional1.java │ │ │ │ ├── DBInfoPathMultiAnnotation.java │ │ │ │ ├── DBInfoBadMethodAnnotations.java │ │ │ │ ├── DBInfoOptional.java │ │ │ │ ├── DBInfoBadAnnotationsWithClassDefault.java │ │ │ │ ├── DBInfoAnnotationsDefault.java │ │ │ │ ├── DBInfoAnnotations.java │ │ │ │ ├── DBInfoMethodAnnotationsDefault.java │ │ │ │ ├── DBInfoAnnotationsLong.java │ │ │ │ ├── DBInfoMethodAnnotations.java │ │ │ │ ├── DBInfoMethodAnnotationsLong.java │ │ │ │ ├── DBInfoBothAnnotations.java │ │ │ │ ├── DBInfoNoDefaultConstructor.java │ │ │ │ ├── DBInfoBooleanEnabledNonNullGetter.java │ │ │ │ └── DBInfoConstructor.java │ │ │ ├── secret │ │ │ └── rules │ │ │ │ ├── MD5SecretObfuscatorTest.java │ │ │ │ └── RegexSecretCheckerTest.java │ │ │ ├── utils │ │ │ ├── SealedClassUtilTestOldJavaTest.java │ │ │ └── ErrorsUtilTest.java │ │ │ ├── observations │ │ │ └── TestObservationRecord.java │ │ │ ├── security │ │ │ └── encrypted │ │ │ │ └── EncryptedSecretModuleTest.java │ │ │ ├── lexer │ │ │ └── PathLexerBuilderTest.java │ │ │ ├── processor │ │ │ └── result │ │ │ │ └── validation │ │ │ │ └── TestConfigValidator.java │ │ │ ├── loader │ │ │ ├── MapLoaderModuleConfigBuilderTest.java │ │ │ ├── PropertyLoaderModuleConfigBuilderTest.java │ │ │ └── EnvironmentVarsLoaderModuleConfigBuilderTest.java │ │ │ └── entity │ │ │ └── GestaltConfigTest.java │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ ├── org.github.gestalt.config.processor.config.RunTimeConfigNodeProcessor │ │ │ ├── org.github.gestalt.config.loader.ConfigLoader │ │ │ ├── org.github.gestalt.config.path.mapper.PathMapper │ │ │ ├── org.github.gestalt.config.processor.config.annotation.AnnotationMetadataTransform │ │ │ ├── org.github.gestalt.config.node.factory.ConfigNodeFactory │ │ │ ├── org.github.gestalt.config.processor.config.ConfigNodeProcessor │ │ │ └── org.github.gestalt.config.processor.config.transform.Transformer │ │ └── java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ ├── entity │ │ ├── GestaltModuleConfig.java │ │ ├── ConfigValue.java │ │ └── ValidationLevel.java │ │ ├── lexer │ │ ├── LowerCaseSentenceNormalizer.java │ │ └── SentenceNormalizer.java │ │ ├── token │ │ └── Token.java │ │ ├── processor │ │ ├── config │ │ │ ├── ConfigNodeProcessor.java │ │ │ ├── RunTimeConfigNodeProcessor.java │ │ │ ├── annotation │ │ │ │ ├── SecretAnnotationMetadataTransform.java │ │ │ │ ├── NoCacheAnnotationMetadataTransform.java │ │ │ │ └── AnnotationMetadataTransform.java │ │ │ └── transform │ │ │ │ ├── URLEncoderTransformer.java │ │ │ │ ├── substitution │ │ │ │ └── SubstitutionNode.java │ │ │ │ └── Base64EncoderTransformer.java │ │ └── result │ │ │ └── DefaultResultProcessor.java │ │ ├── reload │ │ ├── CoreReloadListener.java │ │ └── ConfigReloadListener.java │ │ ├── secret │ │ └── rules │ │ │ ├── SecretObfuscator.java │ │ │ ├── SecretChecker.java │ │ │ ├── RegexSecretChecker.java │ │ │ └── SecretConcealer.java │ │ ├── metadata │ │ ├── MetaDataValue.java │ │ ├── IsSecretMetadata.java │ │ ├── IsEncryptedMetadata.java │ │ ├── IsTemporaryMetadata.java │ │ └── IsRunTimeStringSubstitutionMetadata.java │ │ ├── annotations │ │ ├── ConfigPrefix.java │ │ ├── ConfigPriority.java │ │ ├── Config.java │ │ └── ConfigParameter.java │ │ ├── decoder │ │ ├── ProxyDecoderMode.java │ │ ├── Priority.java │ │ └── StringDecoder.java │ │ ├── observations │ │ └── ObservationRecord.java │ │ ├── node │ │ ├── TagMergingStrategyFallback.java │ │ ├── TagMergingStrategyCombine.java │ │ ├── TagMergingStrategy.java │ │ ├── NodeType.java │ │ └── factory │ │ │ └── ConfigNodeFactory.java │ │ ├── path │ │ └── mapper │ │ │ └── StandardPathMapper.java │ │ ├── exceptions │ │ └── GestaltConfigurationException.java │ │ └── parser │ │ └── ConfigParser.java └── build.gradle.kts ├── gestalt-benchmark ├── results │ └── results-0.12.0-jdk-11.json └── src │ └── jmh │ └── resources │ ├── dev.properties │ └── default.properties ├── gestalt-git ├── src │ ├── test │ │ └── resources │ │ │ ├── dev.properties │ │ │ ├── default.properties │ │ │ └── include.properties │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── org.github.gestalt.config.node.factory.ConfigNodeFactory │ │ └── java │ │ └── module-info.java └── build.gradle.kts ├── gestalt-examples ├── gestalt-sample │ └── src │ │ └── test │ │ ├── resources │ │ ├── employee │ │ ├── serviceMode.txt │ │ ├── kubernetes │ │ │ ├── db.host.password │ │ │ ├── subservice.booking.token │ │ │ └── db.host.uri │ │ ├── include.properties │ │ ├── logging.properties │ │ ├── dev.yml │ │ ├── dev.toml │ │ ├── integration.properties │ │ ├── dev.json │ │ ├── dev.properties │ │ ├── default.yml │ │ ├── default.conf │ │ ├── default.json │ │ ├── defaultPPEnv.properties │ │ ├── defaultPPSys.properties │ │ ├── default.properties │ │ └── defaultPPVault.properties │ │ └── java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── integration │ │ └── TestObservationRecord.java ├── gestalt-sample-module │ └── src │ │ └── main │ │ ├── resources │ │ ├── employee │ │ ├── serviceMode.txt │ │ ├── include.properties │ │ ├── logging.properties │ │ ├── dev.yml │ │ ├── dev.toml │ │ ├── integration.properties │ │ ├── dev.json │ │ ├── dev.properties │ │ ├── default.yml │ │ ├── default.conf │ │ ├── default.json │ │ ├── defaultPPEnv.properties │ │ ├── defaultPPSys.properties │ │ ├── default.properties │ │ └── defaultPPVault.properties │ │ └── kotlin │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── integration │ │ └── MainClassKt.kt └── gestalt-sample-java-records │ ├── src │ └── test │ │ └── resources │ │ ├── logging.properties │ │ ├── dev.properties │ │ └── default.properties │ └── build.gradle.kts ├── gestalt-azure ├── src │ ├── test │ │ └── resources │ │ │ ├── include.properties │ │ │ └── default.properties │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ ├── org.github.gestalt.config.node.factory.ConfigNodeFactory │ │ │ └── org.github.gestalt.config.processor.config.transform.Transformer │ │ └── java │ │ └── module-info.java └── build.gradle.kts ├── gestalt-google-cloud ├── src │ ├── test │ │ └── resources │ │ │ ├── include.properties │ │ │ └── default.properties │ └── main │ │ └── resources │ │ └── META-INF │ │ └── services │ │ ├── org.github.gestalt.config.node.factory.ConfigNodeFactory │ │ └── org.github.gestalt.config.processor.config.transform.Transformer └── build.gradle.kts ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties └── gradle-daemon-jvm.properties ├── gestalt-json ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.github.gestalt.config.loader.ConfigLoader │ │ └── java │ │ │ └── module-info.java │ └── test │ │ └── java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── json │ │ └── JsonModuleConfigTest.java └── build.gradle.kts ├── gestalt-toml ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.github.gestalt.config.loader.ConfigLoader │ │ └── java │ │ │ └── module-info.java │ └── test │ │ └── java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── toml │ │ └── TomlModuleConfigTest.java └── build.gradle.kts ├── gestalt-yaml ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.github.gestalt.config.loader.ConfigLoader │ │ └── java │ │ │ └── module-info.java │ └── test │ │ └── java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── yaml │ │ └── YamlModuleConfigTest.java └── build.gradle.kts ├── gestalt-cdi ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── jakarta.enterprise.inject.spi.Extension │ │ └── java │ │ │ └── org │ │ │ └── github │ │ │ └── gestalt │ │ │ └── config │ │ │ └── cdi │ │ │ ├── InjectConfig.java │ │ │ ├── GestaltConfigException.java │ │ │ ├── InjectConfigs.java │ │ │ └── GestaltConfigProvider.java │ └── test │ │ └── java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── cdi │ │ ├── InnerTestClassCondition.java │ │ └── ConfigClassWithPrefixTest.java ├── Readme.md └── build.gradle.kts ├── gestalt-hocon ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.github.gestalt.config.loader.ConfigLoader │ │ └── java │ │ │ └── module-info.java │ └── test │ │ └── java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── hocon │ │ └── HoconModuleConfigTest.java └── build.gradle.kts ├── gestalt-kodein-di ├── src │ ├── test │ │ └── resources │ │ │ └── default.properties │ └── main │ │ └── kotlin │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── kotlin │ │ └── kodein │ │ └── Kodein.kt └── build.gradle.kts ├── gestalt-koin-di ├── src │ ├── test │ │ └── resources │ │ │ └── default.properties │ └── main │ │ └── kotlin │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── kotlin │ │ └── koin │ │ └── Koin.kt └── build.gradle.kts ├── gestalt-aws ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ ├── org.github.gestalt.config.node.factory.ConfigNodeFactory │ │ │ │ └── org.github.gestalt.config.processor.config.transform.Transformer │ │ └── java │ │ │ └── module-info.java │ └── test │ │ └── resources │ │ └── default.properties └── build.gradle.kts ├── gestalt-vault ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── org.github.gestalt.config.processor.config.transform.Transformer │ │ └── java │ │ ├── module-info.java │ │ └── org │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── vault │ │ └── config │ │ └── VaultModuleConfig.java └── build.gradle.kts ├── .gitattributes ├── gradel.properties ├── gestalt-micrometer ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── org.github.gestalt.config.observations.ObservationRecorder │ │ └── java │ │ └── module-info.java └── build.gradle.kts ├── gestalt-test ├── src │ └── test │ │ ├── java │ │ └── org │ │ │ └── github │ │ │ └── gestalt │ │ │ └── config │ │ │ ├── test │ │ │ └── classes │ │ │ │ ├── Person2.java │ │ │ │ ├── Person.java │ │ │ │ ├── PersonNullable.java │ │ │ │ ├── PersonOptional.java │ │ │ │ ├── Person3.java │ │ │ │ ├── PersonAnnotations.java │ │ │ │ ├── PersonBadAnnotations.java │ │ │ │ ├── PersonAnnotationsLong.java │ │ │ │ ├── DBPool.java │ │ │ │ ├── DBInfoNullableGetter2.java │ │ │ │ ├── DBInfoExtended.java │ │ │ │ ├── DBInfo.java │ │ │ │ ├── DBInfoGeneric.java │ │ │ │ ├── DBInfoNullable.java │ │ │ │ └── DBInfoNullableGetter.java │ │ │ └── model │ │ │ ├── DBInfoRecord.java │ │ │ ├── DBInfoInterface2.java │ │ │ ├── DBInfoOptionalRecord.java │ │ │ ├── DBInfoInterfaceOptional.java │ │ │ └── DBInfo.java │ │ └── resources │ │ ├── logging.properties │ │ ├── dev.properties │ │ └── default.properties └── build.gradle.kts ├── gestalt-validator-hibernate ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ └── services │ │ │ │ └── org.github.gestalt.config.processor.result.validation.ConfigValidator │ │ └── java │ │ │ ├── module-info.java │ │ │ └── com │ │ │ └── github │ │ │ └── gestalt │ │ │ └── config │ │ │ └── validation │ │ │ └── hibernate │ │ │ └── config │ │ │ └── HibernateModuleConfig.java │ └── test │ │ └── java │ │ └── com │ │ └── github │ │ └── gestalt │ │ └── config │ │ └── validation │ │ └── hibernate │ │ └── builder │ │ └── HibernateModuleBuilderTest.java └── build.gradle.kts ├── .gitignore ├── gestalt-kotlin ├── src │ ├── test │ │ └── resources │ │ │ ├── logging.properties │ │ │ ├── dev.properties │ │ │ └── default.properties │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── org.github.gestalt.config.decoder.Decoder │ │ └── java │ │ └── module-info.java └── build.gradle.kts ├── gestalt-guice ├── build.gradle.kts └── src │ └── main │ └── java │ ├── module-info.java │ └── org │ └── github │ └── gestalt │ └── config │ └── guice │ ├── InjectConfig.java │ └── GestaltModule.java ├── benchmark.sh ├── .editorconfig ├── .github └── workflows │ └── test-deploy.yml ├── benchmark.ps1 ├── .sonarcloud.properties └── settings.gradle.kts /docs/gestalt-static/static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/employee: -------------------------------------------------------------------------------- 1 | Janice -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/empty.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gestalt-benchmark/results/results-0.12.0-jdk-11.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/myFile.txt: -------------------------------------------------------------------------------- 1 | hello world -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/serviceMode.txt: -------------------------------------------------------------------------------- 1 | active -------------------------------------------------------------------------------- /gestalt-git/src/test/resources/dev.properties: -------------------------------------------------------------------------------- 1 | hello=colin 2 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/kubernetes/db.host.password: -------------------------------------------------------------------------------- 1 | abcdef -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/employee: -------------------------------------------------------------------------------- 1 | Janice -------------------------------------------------------------------------------- /gestalt-git/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | hello=world 2 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/employee: -------------------------------------------------------------------------------- 1 | Janice -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/serviceMode.txt: -------------------------------------------------------------------------------- 1 | active -------------------------------------------------------------------------------- /gestalt-git/src/test/resources/include.properties: -------------------------------------------------------------------------------- 1 | b=b changed 2 | c=c 3 | -------------------------------------------------------------------------------- /gestalt-azure/src/test/resources/include.properties: -------------------------------------------------------------------------------- 1 | b=b changed 2 | c=c 3 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/include.properties: -------------------------------------------------------------------------------- 1 | b=b changed 2 | c=c 3 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/kubernetes/subservice.booking.token: -------------------------------------------------------------------------------- 1 | 111222333 -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/serviceMode.txt: -------------------------------------------------------------------------------- 1 | active -------------------------------------------------------------------------------- /gestalt-google-cloud/src/test/resources/include.properties: -------------------------------------------------------------------------------- 1 | b=b changed 2 | c=c 3 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/kubernetes/db.host.password: -------------------------------------------------------------------------------- 1 | abcdef -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/kubernetes/db.host.uri: -------------------------------------------------------------------------------- 1 | jdbc:postgresql://localhost:5432/mydb1 -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/include.properties: -------------------------------------------------------------------------------- 1 | b=b changed 2 | c=c 3 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/kubernetes/subservice.booking.token: -------------------------------------------------------------------------------- 1 | 111222333 -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/include.properties: -------------------------------------------------------------------------------- 1 | b=b changed 2 | c=c 3 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/kubernetes/db.host.uri: -------------------------------------------------------------------------------- 1 | jdbc:postgresql://localhost:5432/mydb1 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gestalt-config/gestalt/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /docs/gestalt-static/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/gestalt-static/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gestalt-config/gestalt/HEAD/docs/gestalt-static/static/img/favicon.ico -------------------------------------------------------------------------------- /gestalt-json/src/main/resources/META-INF/services/org.github.gestalt.config.loader.ConfigLoader: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.json.JsonLoader 2 | -------------------------------------------------------------------------------- /gestalt-toml/src/main/resources/META-INF/services/org.github.gestalt.config.loader.ConfigLoader: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.toml.TomlLoader 2 | -------------------------------------------------------------------------------- /gestalt-yaml/src/main/resources/META-INF/services/org.github.gestalt.config.loader.ConfigLoader: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.yaml.YamlLoader 2 | -------------------------------------------------------------------------------- /docs/gestalt-static/static/img/docusaurus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gestalt-config/gestalt/HEAD/docs/gestalt-static/static/img/docusaurus.png -------------------------------------------------------------------------------- /gestalt-cdi/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.cdi.GestaltConfigExtension 2 | -------------------------------------------------------------------------------- /gestalt-hocon/src/main/resources/META-INF/services/org.github.gestalt.config.loader.ConfigLoader: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.hocon.HoconLoader 2 | -------------------------------------------------------------------------------- /gestalt-kodein-di/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | db.uri=jdbc:postgresql://localhost:5432/mydb1 2 | db.password=password 3 | db.port=100 4 | 5 | -------------------------------------------------------------------------------- /gestalt-koin-di/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | db.uri=jdbc:postgresql://localhost:5432/mydb1 2 | db.password=password 3 | db.port=100 4 | 5 | -------------------------------------------------------------------------------- /docs/gestalt-static/static/img/docusaurus-social-card.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gestalt-config/gestalt/HEAD/docs/gestalt-static/static/img/docusaurus-social-card.jpg -------------------------------------------------------------------------------- /gestalt-aws/src/main/resources/META-INF/services/org.github.gestalt.config.node.factory.ConfigNodeFactory: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.aws.node.factory.S3ConfigNodeFactory 2 | -------------------------------------------------------------------------------- /gestalt-git/src/main/resources/META-INF/services/org.github.gestalt.config.node.factory.ConfigNodeFactory: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.git.node.factory.GitConfigNodeFactory 2 | -------------------------------------------------------------------------------- /gestalt-azure/src/main/resources/META-INF/services/org.github.gestalt.config.node.factory.ConfigNodeFactory: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.azure.node.factory.BlobConfigNodeFactory 2 | -------------------------------------------------------------------------------- /gestalt-vault/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.transform.Transformer: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.vault.VaultSecretTransformer 2 | -------------------------------------------------------------------------------- /gestalt-aws/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.transform.Transformer: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.aws.transformer.AWSSecretTransformer 2 | -------------------------------------------------------------------------------- /gestalt-azure/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.transform.Transformer: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.azure.transformer.AzureSecretTransformer 2 | -------------------------------------------------------------------------------- /gestalt-google-cloud/src/main/resources/META-INF/services/org.github.gestalt.config.node.factory.ConfigNodeFactory: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.google.node.factory.GCSConfigNodeFactory 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # These are explicitly windows files and should use crlf 5 | *.bat text eol=crlf 6 | 7 | -------------------------------------------------------------------------------- /docs/gestalt-static/src/pages/markdown-page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Markdown page example 3 | --- 4 | 5 | # Markdown page example 6 | 7 | You don't need React to write simple standalone pages. 8 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/Colours.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public enum Colours { 4 | RED, BLUE, GREEN 5 | } 6 | -------------------------------------------------------------------------------- /gestalt-google-cloud/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.transform.Transformer: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.google.transformer.GCPSecretTransformer 2 | -------------------------------------------------------------------------------- /gradel.properties: -------------------------------------------------------------------------------- 1 | org.gradle.caching=true 2 | org.gradle.parallel=true 3 | org.gradle.jvmargs=-Xmx1g -XX:MaxMetaspaceSize=512m -Xss256m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 4 | -------------------------------------------------------------------------------- /gestalt-micrometer/src/main/resources/META-INF/services/org.github.gestalt.config.observations.ObservationRecorder: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.micrometer.observations.MicrometerObservationRecorder 2 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/Person2.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public record Person2(Integer id, String name) { 4 | } 5 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/test: -------------------------------------------------------------------------------- 1 | db.user=credmond 2 | db.password=password 3 | db.url=jdbc:postgresql://localhost:5432/mydb 4 | db.con.timeout=60 5 | 6 | 7 | cache.size=100 8 | cache.ttl=60 9 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/test.properties: -------------------------------------------------------------------------------- 1 | db.user=credmond 2 | db.password=password 3 | db.url=jdbc:postgresql://localhost:5432/mydb 4 | db.con.timeout=60 5 | cache.size=100 6 | cache.ttl=60 7 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/Person.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public record Person(String name, Integer id) { 4 | } 5 | 6 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/tutorial/retrieving-configurations/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Retrieving - Configurations", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /gestalt-validator-hibernate/src/main/resources/META-INF/services/org.github.gestalt.config.processor.result.validation.ConfigValidator: -------------------------------------------------------------------------------- 1 | com.github.gestalt.config.validation.hibernate.HibernateConfigValidator 2 | -------------------------------------------------------------------------------- /gestalt-core/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.RunTimeConfigNodeProcessor: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.processor.config.transform.RunTimeStringSubstitutionConfigNodeProcessor 2 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/model/DBInfoRecord.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.model; 2 | 3 | public record DBInfoRecord(int port, String uri, String password, Integer connections) { 4 | } 5 | -------------------------------------------------------------------------------- /docs/gestalt-static/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // This file is not used in compilation. It is here just for a nice editor experience. 3 | "extends": "@docusaurus/tsconfig", 4 | "compilerOptions": { 5 | "baseUrl": "." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/gestalt-static/src/components/HomepageFeatures/styles.module.css: -------------------------------------------------------------------------------- 1 | .features { 2 | display: flex; 3 | align-items: center; 4 | padding: 2rem 0; 5 | width: 100%; 6 | } 7 | 8 | .featureSvg { 9 | height: 200px; 10 | width: 200px; 11 | } 12 | -------------------------------------------------------------------------------- /gestalt-core/src/main/resources/META-INF/services/org.github.gestalt.config.loader.ConfigLoader: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.loader.EnvironmentVarsLoader 2 | org.github.gestalt.config.loader.MapConfigLoader 3 | org.github.gestalt.config.loader.PropertyLoader 4 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/PersonNullable.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import jakarta.annotation.Nullable; 4 | 5 | public record PersonNullable(String name, @Nullable Integer id) { 6 | } 7 | 8 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/PersonOptional.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import java.util.Optional; 4 | 5 | public record PersonOptional(Optional name, Optional id) { 6 | } 7 | 8 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/tutorial/annotations/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Annotating - Configurations", 3 | "position": 4, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "5 minutes to learn the most important Gestalt concepts." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/tutorial/loading-configuration/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Loading - Configurations", 3 | "position": 2, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "5 minutes to learn the most important Gestalt concepts." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/tutorial/tags-configuration/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Tagging - Configurations", 3 | "position": 3, 4 | "link": { 5 | "type": "generated-index", 6 | "description": "5 minutes to learn the most important Gestalt concepts." 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoInterface.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public interface DBInfoInterface { 4 | int getPort(); 5 | 6 | String getUri(); 7 | 8 | String getPassword(); 9 | } 10 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/Person3.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public record Person3(@Config(path = "test") Integer id, String name) { 6 | } 7 | -------------------------------------------------------------------------------- /gestalt-cdi/Readme.md: -------------------------------------------------------------------------------- 1 | The CDI functionality is based on the work by [smallrye config version 3.11]( https://github.com/smallrye/smallrye-config/tree/3.1.1/cdi). 2 | 3 | Most of the files have been heavily modified, but I retained the original author and copyright information where applicable. 4 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoInterface2.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public interface DBInfoInterface2 { 4 | 5 | Integer getPort(); 6 | 7 | String getUri(); 8 | 9 | String getPassword(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /gestalt-test/src/test/resources/logging.properties: -------------------------------------------------------------------------------- 1 | .level=TRACE 2 | handlers=java.util.logging.ConsoleHandler 3 | java.util.logging.ConsoleHandler.level=INFO 4 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 5 | java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle 3 | 4 | #ignore intellij directory 5 | .idea 6 | 7 | #ignore the kotlin directory 8 | .kotlin 9 | 10 | # Ignore Gradle build output directory 11 | build 12 | 13 | ## ignore the out directory 14 | **/out 15 | 16 | /cloc.exe 17 | -------------------------------------------------------------------------------- /gestalt-kotlin/src/test/resources/logging.properties: -------------------------------------------------------------------------------- 1 | .level= TRACE 2 | handlers= java.util.logging.ConsoleHandler 3 | java.util.logging.ConsoleHandler.level = INFO 4 | java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter 5 | java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/architecture/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # Architectural details 6 | This section is more for those wishing to know more about how Gestalt works, or how to add their own functionality. If you only wish to get configuration from Gestalt As Is, then feel free to skip it. 7 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/model/DBInfoInterface2.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.model; 2 | 3 | public interface DBInfoInterface2 { 4 | 5 | Integer getPort(); 6 | 7 | String getUri(); 8 | 9 | String getPassword(); 10 | 11 | Integer getConnections(); 12 | } 13 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/PersonAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public record PersonAnnotations(String name, @Config(path = "identity", defaultVal = "1234") Integer id) { 6 | } 7 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/logging.properties: -------------------------------------------------------------------------------- 1 | .level= TRACE 2 | handlers= java.util.logging.ConsoleHandler 3 | java.util.logging.ConsoleHandler.level = INFO 4 | java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter 5 | java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n 6 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/PersonBadAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public record PersonBadAnnotations(String name, @Config(path = "identity", defaultVal = "abc") Integer id) { 6 | } 7 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/logging.properties: -------------------------------------------------------------------------------- 1 | .level= TRACE 2 | handlers= java.util.logging.ConsoleHandler 3 | java.util.logging.ConsoleHandler.level = INFO 4 | java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter 5 | java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n 6 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/PersonAnnotationsLong.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public record PersonAnnotationsLong(String name, @Config(path = "identity.user", defaultVal = "1234") Integer id) { 6 | } 7 | -------------------------------------------------------------------------------- /gestalt-core/src/main/resources/META-INF/services/org.github.gestalt.config.path.mapper.PathMapper: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.path.mapper.DotNotationPathMapper 2 | org.github.gestalt.config.path.mapper.KebabCasePathMapper 3 | org.github.gestalt.config.path.mapper.StandardPathMapper 4 | org.github.gestalt.config.path.mapper.SnakeCasePathMapper 5 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoInterfaceDefault.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public interface DBInfoInterfaceDefault { 4 | default int getPort() { 5 | return 10; 6 | } 7 | 8 | String getUri(); 9 | 10 | String getPassword(); 11 | } 12 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-java-records/src/test/resources/logging.properties: -------------------------------------------------------------------------------- 1 | .level= TRACE 2 | handlers= java.util.logging.ConsoleHandler 3 | java.util.logging.ConsoleHandler.level = INFO 4 | java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter 5 | java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n 6 | -------------------------------------------------------------------------------- /gestalt-hocon/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.hocon) 11 | } 12 | -------------------------------------------------------------------------------- /gestalt-guice/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.guice) 11 | } 12 | 13 | -------------------------------------------------------------------------------- /docs/gestalt-static/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /gestalt-json/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.bundles.jackson) 11 | } 12 | 13 | -------------------------------------------------------------------------------- /gestalt-core/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | val patchArgs = listOf("-parameters") 9 | tasks.compileTestJava { 10 | options.compilerArgs.addAll(patchArgs) 11 | } 12 | -------------------------------------------------------------------------------- /gestalt-micrometer/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | 11 | api(libs.micrometer) 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoInterfaceOptional.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import java.util.Optional; 4 | 5 | public interface DBInfoInterfaceOptional { 6 | 7 | Optional getPort(); 8 | 9 | Optional getUri(); 10 | 11 | Optional getPassword(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/entity/GestaltModuleConfig.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.entity; 2 | 3 | /** 4 | * Interface used to register module specific configuration. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public interface GestaltModuleConfig { 9 | String name(); 10 | } 11 | -------------------------------------------------------------------------------- /gestalt-guice/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Module info definition for gestalt hocon integration 3 | */ 4 | @SuppressWarnings({ "requires-automatic", "requires-transitive-automatic" }) 5 | module org.github.gestalt.guice { 6 | requires org.github.gestalt.core; 7 | requires transitive com.google.guice; 8 | 9 | exports org.github.gestalt.config.guice; 10 | } 11 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/dev.properties: -------------------------------------------------------------------------------- 1 | DB.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | DB.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | DB.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | DB.connectionTimeout=600 5 | http.pool.maxTotal=1000 6 | http.pool.maxPerRoute=50 7 | admin.user=Peter, Kim, Steve 8 | admin.overrideEnabled=true 9 | 10 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/IDBInfoMethodAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public interface IDBInfoMethodAnnotations { 6 | @Config(defaultVal = "1234") 7 | int getPort(); 8 | 9 | String getUri(); 10 | 11 | String getPassword(); 12 | } 13 | -------------------------------------------------------------------------------- /gestalt-toml/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.bundles.jackson) 11 | api(libs.jackson.toml) 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /gestalt-yaml/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.bundles.jackson) 11 | api(libs.jackson.yaml) 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/lexer/LowerCaseSentenceNormalizer.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.lexer; 2 | 3 | import java.util.Locale; 4 | 5 | public class LowerCaseSentenceNormalizer implements SentenceNormalizer { 6 | @Override 7 | public String normalizeSentence(String sentence) { 8 | return sentence.toLowerCase(Locale.ROOT); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/IDBInfoAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public interface IDBInfoAnnotations { 6 | @Config(path = "channel", defaultVal = "1234") 7 | int getPort(); 8 | 9 | String getUri(); 10 | 11 | String getPassword(); 12 | } 13 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/IDBInfoBadAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public interface IDBInfoBadAnnotations { 6 | @Config(path = "channel", defaultVal = "abc") 7 | int getPort(); 8 | 9 | String getUri(); 10 | 11 | String getPassword(); 12 | } 13 | -------------------------------------------------------------------------------- /gestalt-git/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.jgit) 11 | api(libs.jgit.apache.ssh) 12 | api(libs.eddsa) 13 | } 14 | 15 | -------------------------------------------------------------------------------- /gestalt-kotlin/src/test/resources/dev.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | admin.users=Peter, Kim, Steve 10 | admin.overrideEnabled=true 11 | 12 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/tutorial/samples.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Example code 6 | For more examples of how to use gestalt see the [gestalt-sample](https://github.com/gestalt-config/gestalt/tree/main/gestalt-examples/gestalt-sample/src/test) or for Java 17 + samples [gestalt-sample-records](https://github.com/gestalt-config/gestalt/tree/main/gestalt-examples/gestalt-sample-java-records/src/test) 7 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/IDBInfoAnnotationsLong.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public interface IDBInfoAnnotationsLong { 6 | @Config(path = "channel.port", defaultVal = "1234") 7 | int getPort(); 8 | 9 | String getUri(); 10 | 11 | String getPassword(); 12 | } 13 | -------------------------------------------------------------------------------- /benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #gestalt_versions=(0.25.0 0.24.6 0.24.5 0.24.4 0.24.3 0.24.2 0.24.1 0.24.0 0.23.3 0.23.2 0.23.1 0.23.0 0.22.1 0.21.0) 4 | gestalt_versions=(0.25.0 0.24.6) 5 | #jdk_version=(11 17 21) 6 | jdk_version=(11) 7 | 8 | for jdk in ${jdk_version[@]} 9 | do 10 | for v in ${gestalt_versions[@]} 11 | do 12 | ./gradlew jmh -DgestaltVersion=$v -DjdkVersion=$jdk 13 | done 14 | done 15 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/dev.yml: -------------------------------------------------------------------------------- 1 | --- 2 | db: 3 | hosts: 4 | - url: jdbc:postgresql://dev.host.name1:5432/mydb 5 | - url: jdbc:postgresql://dev.host.name2:5432/mydb 6 | - url: jdbc:postgresql://dev.host.name3:5432/mydb 7 | connectionTimeout: 600 8 | http: 9 | pool: 10 | maxTotal: 1000 11 | maxPerRoute: 50 12 | admin: 13 | user: Peter, Kim, Steve 14 | overrideEnabled: true 15 | -------------------------------------------------------------------------------- /gestalt-validator-hibernate/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.hibernate.validator) 11 | 12 | testImplementation(libs.expressly) 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/dev.yml: -------------------------------------------------------------------------------- 1 | --- 2 | db: 3 | hosts: 4 | - url: jdbc:postgresql://dev.host.name1:5432/mydb 5 | - url: jdbc:postgresql://dev.host.name2:5432/mydb 6 | - url: jdbc:postgresql://dev.host.name3:5432/mydb 7 | connectionTimeout: 600 8 | http: 9 | pool: 10 | maxTotal: 1000 11 | maxPerRoute: 50 12 | admin: 13 | user: Peter, Kim, Steve 14 | overrideEnabled: true 15 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/model/DBInfoOptionalRecord.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.model; 2 | 3 | 4 | import org.github.gestalt.config.annotations.Config; 5 | 6 | import java.util.Optional; 7 | 8 | public record DBInfoOptionalRecord( 9 | Optional port, 10 | Optional uri, 11 | Optional password, 12 | @Config(defaultVal = "200") Integer connections) { 13 | } 14 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBPool.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBPool { 4 | public int maxTotal; 5 | public int maxPerRoute; 6 | public int validateAfterInactivity; 7 | public int keepAliveTimeoutMs = 6000; 8 | public int idleTimeoutSec = 10; 9 | public float defaultWait = 33.0F; 10 | 11 | public DBPool() { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gestalt-json/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Module info definition for gestalt json integration 3 | */ 4 | module org.github.gestalt.json { 5 | requires org.github.gestalt.core; 6 | requires transitive com.fasterxml.jackson.databind; 7 | 8 | exports org.github.gestalt.config.json; 9 | 10 | provides org.github.gestalt.config.loader.ConfigLoader with 11 | org.github.gestalt.config.json.JsonLoader; 12 | } 13 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/token/Token.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.token; 2 | 3 | /** 4 | * interface for a token. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public class Token { 9 | /** 10 | * protected constructor so end users cant create this class only Tokens inherited from it. 11 | */ 12 | protected Token() { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBPoolInterface.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public interface DBPoolInterface { 4 | int getMaxTotal(); 5 | 6 | int getMaxPerRoute(); 7 | 8 | int getValidateAfterInactivity(); 9 | 10 | int getKeepAliveTimeoutMs(); 11 | 12 | int getIdleTimeoutSec(); 13 | 14 | float getDefaultWait(); 15 | 16 | boolean isEnabled(); 17 | } 18 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/DBPool.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBPool { 4 | public int maxTotal; 5 | public int maxPerRoute; 6 | public int validateAfterInactivity; 7 | public int keepAliveTimeoutMs = 6000; 8 | public int idleTimeoutSec = 10; 9 | public float defaultWait = 33.0F; 10 | 11 | public DBPool() { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/lexer/SentenceNormalizer.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.lexer; 2 | 3 | public interface SentenceNormalizer { 4 | /** 5 | * Takes a sentence and normalize it so we can match tokens from all various systems. 6 | * 7 | * @param sentence input sentence to normalize 8 | * @return a normalized sentence. 9 | */ 10 | String normalizeSentence(String sentence); 11 | } 12 | -------------------------------------------------------------------------------- /gestalt-test/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.kotlin-common-conventions") 5 | } 6 | 7 | java { 8 | toolchain { 9 | languageVersion.set(JavaLanguageVersion.of(libs.versions.javaLatest.get())) 10 | } 11 | } 12 | 13 | dependencies { 14 | testImplementation(project(":gestalt-core")) 15 | testImplementation(libs.jakarta.annotation) 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/dev.toml: -------------------------------------------------------------------------------- 1 | [db] 2 | connectionTimeout = 600 3 | 4 | [[db.hosts]] 5 | url = "jdbc:postgresql://dev.host.name1:5432/mydb" 6 | 7 | [[db.hosts]] 8 | url = "jdbc:postgresql://dev.host.name2:5432/mydb" 9 | 10 | [[db.hosts]] 11 | url = "jdbc:postgresql://dev.host.name3:5432/mydb" 12 | 13 | [http.pool] 14 | maxTotal = 1_000 15 | maxPerRoute = 50 16 | 17 | [admin] 18 | user = "Peter, Kim, Steve" 19 | overrideEnabled = true 20 | -------------------------------------------------------------------------------- /gestalt-vault/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(libs.vault) 11 | 12 | testImplementation(libs.testcontainers.junit5) 13 | testImplementation(libs.testcontainers.vault) 14 | } 15 | 16 | 17 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/dev.toml: -------------------------------------------------------------------------------- 1 | [db] 2 | connectionTimeout = 600 3 | 4 | [[db.hosts]] 5 | url = "jdbc:postgresql://dev.host.name1:5432/mydb" 6 | 7 | [[db.hosts]] 8 | url = "jdbc:postgresql://dev.host.name2:5432/mydb" 9 | 10 | [[db.hosts]] 11 | url = "jdbc:postgresql://dev.host.name3:5432/mydb" 12 | 13 | [http.pool] 14 | maxTotal = 1_000 15 | maxPerRoute = 50 16 | 17 | [admin] 18 | user = "Peter, Kim, Steve" 19 | overrideEnabled = true 20 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/ConfigNodeProcessor.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config; 2 | 3 | /** 4 | * Interface for the Config Node Processing. This will be run against every node in the tree after the tree has been compiled. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public interface ConfigNodeProcessor extends BaseConfigNodeProcessor { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/kotlin/org/github/gestalt/config/integration/MainClassKt.kt: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.integration 2 | 3 | /** 4 | * @author Colin Redmond (c) 2025. 5 | */ 6 | 7 | fun main() { 8 | 9 | val kotlinTests = GestaltKotlinTest() 10 | kotlinTests.integrationTest() 11 | kotlinTests.integrationTestEnvVars() 12 | kotlinTests.integrationTestWithTypeOf() 13 | } 14 | 15 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/RunTimeConfigNodeProcessor.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config; 2 | 3 | /** 4 | * Interface for the Config Node Processing. This will be run against the found nodes while getting a configuration at runtime. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public interface RunTimeConfigNodeProcessor extends BaseConfigNodeProcessor { 9 | } 10 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/integration.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | http.pool.maxTotal=1000 6 | http.pool.maxPerRoute=50 7 | subservice.booking.service.path=booking 8 | subservice.search.service.isEnabled=false 9 | admin.user=Peter, Kim, Steve 10 | admin.overrideEnabled=true 11 | 12 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/model/DBInfoInterfaceOptional.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.model; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | import java.util.Optional; 6 | 7 | public interface DBInfoInterfaceOptional { 8 | 9 | Optional getPort(); 10 | 11 | Optional getUri(); 12 | 13 | Optional getPassword(); 14 | 15 | @Config(defaultVal = "200") 16 | Integer getConnections(); 17 | } 18 | -------------------------------------------------------------------------------- /gestalt-core/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.annotation.AnnotationMetadataTransform: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.processor.config.annotation.EncryptionAnnotationMetadataTransform 2 | org.github.gestalt.config.processor.config.annotation.TemporaryAnnotationMetadataTransform 3 | org.github.gestalt.config.processor.config.annotation.NoCacheAnnotationMetadataTransform 4 | org.github.gestalt.config.processor.config.annotation.SecretAnnotationMetadataTransform 5 | 6 | -------------------------------------------------------------------------------- /docs/gestalt-static/src/pages/index.module.css: -------------------------------------------------------------------------------- 1 | /** 2 | * CSS files with the .module.css suffix will be treated as CSS modules 3 | * and scoped locally. 4 | */ 5 | 6 | .heroBanner { 7 | padding: 4rem 0; 8 | text-align: center; 9 | position: relative; 10 | overflow: hidden; 11 | } 12 | 13 | @media screen and (max-width: 996px) { 14 | .heroBanner { 15 | padding: 2rem; 16 | } 17 | } 18 | 19 | .buttons { 20 | display: flex; 21 | align-items: center; 22 | justify-content: center; 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/reload/CoreReloadListener.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.reload; 2 | 3 | /** 4 | * Listener for core reload events. Core reload events are triggered when one or more of the config reloads. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public interface CoreReloadListener { 9 | /** 10 | * Called when the core configs have been reloaded. 11 | */ 12 | void reload(); 13 | } 14 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBPoolInterfaceDefault.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public interface DBPoolInterfaceDefault { 4 | int getMaxTotal(); 5 | 6 | int getMaxPerRoute(); 7 | 8 | int getValidateAfterInactivity(); 9 | 10 | int getKeepAliveTimeoutMs(); 11 | 12 | int getIdleTimeoutSec(); 13 | 14 | default float getDefaultWait() { 15 | return 0.26f; 16 | } 17 | 18 | boolean isEnabled(); 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-toml/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Module info definition for gestalt yaml integration 3 | */ 4 | module org.github.gestalt.toml { 5 | requires org.github.gestalt.core; 6 | requires transitive com.fasterxml.jackson.databind; 7 | requires transitive com.fasterxml.jackson.dataformat.toml; 8 | 9 | exports org.github.gestalt.config.toml; 10 | 11 | provides org.github.gestalt.config.loader.ConfigLoader with 12 | org.github.gestalt.config.toml.TomlLoader; 13 | } 14 | -------------------------------------------------------------------------------- /gestalt-yaml/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Module info definition for gestalt yaml integration 3 | */ 4 | module org.github.gestalt.yaml { 5 | requires org.github.gestalt.core; 6 | requires transitive com.fasterxml.jackson.databind; 7 | requires transitive com.fasterxml.jackson.dataformat.yaml; 8 | 9 | exports org.github.gestalt.config.yaml; 10 | 11 | provides org.github.gestalt.config.loader.ConfigLoader with 12 | org.github.gestalt.config.yaml.YamlLoader; 13 | } 14 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBPoolGenericInterface.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import java.util.Optional; 4 | 5 | public interface DBPoolGenericInterface { 6 | int getMaxTotal(); 7 | 8 | int getMaxPerRoute(); 9 | 10 | int getValidateAfterInactivity(); 11 | 12 | int getKeepAliveTimeoutMs(); 13 | 14 | Optional getIdleTimeoutSec(); 15 | 16 | float getDefaultWait(); 17 | 18 | boolean isEnabled(); 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/integration.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | subservice.booking.service.path=booking 10 | subservice.search.service.isEnabled=false 11 | 12 | admin.user=Peter, Kim, Steve 13 | admin.overrideEnabled=true 14 | 15 | -------------------------------------------------------------------------------- /gestalt-hocon/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Module info definition for gestalt hocon integration 3 | */ 4 | @SuppressWarnings({ "requires-automatic", "requires-transitive-automatic" }) 5 | module org.github.gestalt.hocon { 6 | requires org.github.gestalt.core; 7 | requires transitive typesafe.config; 8 | 9 | exports org.github.gestalt.config.hocon; 10 | 11 | provides org.github.gestalt.config.loader.ConfigLoader with 12 | org.github.gestalt.config.hocon.HoconLoader; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /gestalt-azure/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(platform(libs.azure.bom)) 11 | api(libs.azure.blob) 12 | api(libs.azure.identity) 13 | api(libs.azure.secret) 14 | 15 | testImplementation(libs.testcontainers.junit5) 16 | } 17 | 18 | 19 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBPoolInterfaceWrapper.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import java.util.Optional; 4 | 5 | public interface DBPoolInterfaceWrapper { 6 | Integer getMaxTotal(); 7 | 8 | Integer getMaxPerRoute(); 9 | 10 | Integer getValidateAfterInactivity(); 11 | 12 | Integer getKeepAliveTimeoutMs(); 13 | 14 | Optional getIdleTimeoutSec(); 15 | 16 | Float getDefaultWait(); 17 | 18 | Boolean isEnabled(); 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/ObjectWithWithoutDefaultsPrimitive.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class ObjectWithWithoutDefaultsPrimitive { 4 | public byte myByte; 5 | public short myShort; 6 | public int myInteger; 7 | public long myLong; 8 | public float myFloat; 9 | public double myDouble; 10 | public char myChar; 11 | public boolean myBoolean; 12 | 13 | public ObjectWithWithoutDefaultsPrimitive() { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/integration.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | subservice.booking.service.path=booking 10 | subservice.search.service.isEnabled=false 11 | 12 | admin.user=Peter, Kim, Steve 13 | admin.overrideEnabled=true 14 | 15 | -------------------------------------------------------------------------------- /gestalt-cdi/src/test/java/org/github/gestalt/config/cdi/InnerTestClassCondition.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.cdi; 2 | 3 | public final class InnerTestClassCondition { 4 | 5 | public static Boolean isDisabled = true; 6 | 7 | private InnerTestClassCondition() { 8 | 9 | } 10 | 11 | public static boolean isDisabled() { 12 | // Always disable unless running manually 13 | return isDisabled; 14 | } 15 | 16 | public static void reset() { 17 | isDisabled = true; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-koin-di/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.kotlin-common-conventions") 3 | id("gestalt.kotlin-test-conventions") 4 | id("gestalt.kotlin-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | implementation(project(":gestalt-kotlin")) 11 | api(libs.koin.di) 12 | } 13 | 14 | tasks.jar { 15 | manifest { 16 | attributes("Automatic-Module-Name" to "org.github.gestalt.kotlin.koin") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/ObjectWithDefaultsPrimitive.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class ObjectWithDefaultsPrimitive { 4 | public byte myByte = 1; 5 | public short myShort = 2; 6 | public int myInteger = 3; 7 | public long myLong = 4L; 8 | public float myFloat = 5.5F; 9 | public double myDouble = 6.6D; 10 | public char myChar = 'a'; 11 | public boolean myBoolean = true; 12 | 13 | public ObjectWithDefaultsPrimitive() { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/ObjectWithoutDefaultsWrapper.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class ObjectWithoutDefaultsWrapper { 4 | public Byte myByte; 5 | public Short myShort; 6 | public Integer myInteger; 7 | public Long myLong; 8 | public Float myFloat; 9 | public Double myDouble; 10 | public Character myChar; 11 | public String myString; 12 | public Boolean myBoolean; 13 | 14 | public ObjectWithoutDefaultsWrapper() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-kodein-di/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.kotlin-common-conventions") 3 | id("gestalt.kotlin-test-conventions") 4 | id("gestalt.kotlin-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | implementation(project(":gestalt-kotlin")) 11 | api(libs.kodein.di) 12 | } 13 | 14 | tasks.jar { 15 | manifest { 16 | attributes("Automatic-Module-Name" to "org.github.gestalt.kotlin.kodein") 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/architecture/sentence-lexer.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Sentence Lexer 6 | Gestalt uses a SentenceLexer's in several places, to convert a string path into tokens that can be followed and to in the ConfigParser to turn the configuration paths into tokens then into config nodes. 7 | You can customize the SentenceLexer to use your own format of path. For example in Gestalt Environment Variables use a '_' to delimitate the tokens whereas property files use '.'. If you wanted to use camel case you could build a sentence lexer for that. 8 | -------------------------------------------------------------------------------- /gestalt-core/src/main/resources/META-INF/services/org.github.gestalt.config.node.factory.ConfigNodeFactory: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.node.factory.ClassPathConfigNodeFactory 2 | org.github.gestalt.config.node.factory.ConfigNodeImportFactory 3 | org.github.gestalt.config.node.factory.EnvVarsConfigNodeFactory 4 | org.github.gestalt.config.node.factory.FileConfigNodeFactory 5 | org.github.gestalt.config.node.factory.KubernetesSecretConfigNodeFactory 6 | org.github.gestalt.config.node.factory.SystemConfigNodeFactory 7 | org.github.gestalt.config.node.factory.UrlConfigNodeFactory 8 | -------------------------------------------------------------------------------- /gestalt-google-cloud/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(platform(libs.google.libraries)) 11 | api(libs.google.storage) 12 | api(libs.google.secret) 13 | } 14 | 15 | tasks.jar { 16 | manifest { 17 | attributes("Automatic-Module-Name" to "org.github.gestalt.google") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/DBInfoNullableGetter2.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import jakarta.annotation.Nullable; 4 | 5 | public class DBInfoNullableGetter2 { 6 | private int port; 7 | 8 | private String uri; 9 | private String password; 10 | 11 | public int port() { 12 | return port; 13 | } 14 | 15 | @Nullable 16 | public String uri() { 17 | return uri; 18 | } 19 | 20 | public String password() { 21 | return password; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-vault/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Module info definition for gestalt yaml integration 3 | */ 4 | module org.github.gestalt.vault { 5 | requires org.github.gestalt.core; 6 | requires transitive vault.java.driver; 7 | 8 | exports org.github.gestalt.config.vault; 9 | exports org.github.gestalt.config.vault.config; 10 | exports org.github.gestalt.config.vault.errors; 11 | 12 | provides org.github.gestalt.config.processor.config.transform.Transformer with 13 | org.github.gestalt.config.vault.VaultSecretTransformer; 14 | } 15 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBPoolInterfaceDefaultGeneric.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import java.util.List; 4 | 5 | public interface DBPoolInterfaceDefaultGeneric { 6 | int getMaxTotal(); 7 | 8 | int getMaxPerRoute(); 9 | 10 | int getValidateAfterInactivity(); 11 | 12 | int getKeepAliveTimeoutMs(); 13 | 14 | int getIdleTimeoutSec(); 15 | 16 | default List getDefaultWait() { 17 | return List.of(1, 2, 3, 4); 18 | } 19 | 20 | boolean isEnabled(); 21 | } 22 | -------------------------------------------------------------------------------- /gestalt-aws/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | api(platform(libs.aws.bom)) 11 | api(libs.aws.s3) 12 | api(libs.aws.secret) 13 | api(libs.aws.url.client) 14 | api(libs.jackson.databind) 15 | testImplementation(libs.aws.mock) 16 | testImplementation(libs.testcontainers.junit5) 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/secret/rules/SecretObfuscator.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.secret.rules; 2 | 3 | /** 4 | * Specifies how to obscure a secret. Takes a value and obfuscates it. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public interface SecretObfuscator { 9 | /** 10 | * Takes a value and obfuscates it. 11 | * 12 | * @param value the value to obfuscates 13 | * @return the value to obfuscated 14 | */ 15 | String obfuscator(String value); 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "db": { 3 | "hosts": [{ 4 | "url": "jdbc:postgresql://dev.host.name1:5432/mydb" 5 | }, { 6 | "url": "jdbc:postgresql://dev.host.name2:5432/mydb" 7 | }, { 8 | "url": "jdbc:postgresql://dev.host.name3:5432/mydb" 9 | } 10 | ], 11 | "connectionTimeout": 600 12 | }, 13 | "http": { 14 | "pool": { 15 | "maxTotal": 1000, 16 | "maxPerRoute": 50 17 | } 18 | }, 19 | "admin": { 20 | "user": "Peter, Kim, Steve", 21 | "overrideEnabled": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoExtended.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoExtended extends DBInfo { 4 | private int timeout; 5 | private String user; 6 | 7 | public int getTimeout() { 8 | return timeout; 9 | } 10 | 11 | public void setTimeout(int timeout) { 12 | this.timeout = timeout; 13 | } 14 | 15 | public String getUser() { 16 | return user; 17 | } 18 | 19 | public void setUser(String user) { 20 | this.user = user; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "db": { 3 | "hosts": [{ 4 | "url": "jdbc:postgresql://dev.host.name1:5432/mydb" 5 | }, { 6 | "url": "jdbc:postgresql://dev.host.name2:5432/mydb" 7 | }, { 8 | "url": "jdbc:postgresql://dev.host.name3:5432/mydb" 9 | } 10 | ], 11 | "connectionTimeout": 600 12 | }, 13 | "http": { 14 | "pool": { 15 | "maxTotal": 1000, 16 | "maxPerRoute": 50 17 | } 18 | }, 19 | "admin": { 20 | "user": "Peter, Kim, Steve", 21 | "overrideEnabled": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/ObjectWithDefaultsWrapper.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class ObjectWithDefaultsWrapper { 4 | public Byte myByte = (byte) 1; 5 | public Short myShort = 2; 6 | public Integer myInteger = 3; 7 | public Long myLong = 4L; 8 | public Float myFloat = 5.5F; 9 | public Double myDouble = 6.6D; 10 | public Character myChar = 'a'; 11 | public String myString = "a"; 12 | public Boolean myBoolean = true; 13 | 14 | public ObjectWithDefaultsWrapper() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/metadata/MetaDataValue.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.metadata; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public abstract class MetaDataValue { 7 | 8 | protected final T value; 9 | 10 | public MetaDataValue(T value) { 11 | this.value = value; 12 | } 13 | 14 | public abstract String keyValue(); 15 | 16 | public T getMetadata() { 17 | return value; 18 | } 19 | 20 | public abstract Map>> rollup(Map>> metadata); 21 | } 22 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/ObjectWithZeroDefaultsWrapper.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class ObjectWithZeroDefaultsWrapper { 4 | public Byte myByte = (byte) 0; 5 | public Short myShort = 0; 6 | public Integer myInteger = 0; 7 | public Long myLong = 0L; 8 | public Float myFloat = 0F; 9 | public Double myDouble = 0D; 10 | public Character myChar = Character.MIN_VALUE; 11 | public String myString = ""; 12 | public Boolean myBoolean = false; 13 | 14 | public ObjectWithZeroDefaultsWrapper() { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-core/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.ConfigNodeProcessor: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.processor.config.annotation.AnnotationConfigNodeProcessor 2 | org.github.gestalt.config.processor.config.include.IncludeConfigNodeProcessor 3 | org.github.gestalt.config.processor.config.transform.LoadtimeStringSubstitutionConfigNodeProcessor 4 | org.github.gestalt.config.processor.config.transform.RunTimeMetadataConfigNodeProcessor 5 | org.github.gestalt.config.security.encrypted.EncryptedSecretConfigNodeProcessor 6 | org.github.gestalt.config.security.temporary.TemporarySecretConfigNodeProcessor 7 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoExtendedDefault.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoExtendedDefault extends DBInfo { 4 | private int timeout = 10000; 5 | private String user = "admin"; 6 | 7 | public int getTimeout() { 8 | return timeout; 9 | } 10 | 11 | public void setTimeout(int timeout) { 12 | this.timeout = timeout; 13 | } 14 | 15 | public String getUser() { 16 | return user; 17 | } 18 | 19 | public void setUser(String user) { 20 | this.user = user; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/secret/rules/MD5SecretObfuscatorTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.secret.rules; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | class MD5SecretObfuscatorTest { 9 | 10 | @Test 11 | void obfuscator() throws NoSuchAlgorithmException { 12 | 13 | MD5SecretObfuscator md5SecretObfuscator = new MD5SecretObfuscator(); 14 | Assertions.assertEquals("482c811da5d5b4bc6d497ffa98491e38", md5SecretObfuscator.obfuscator("password123")); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/annotations/ConfigPrefix.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.annotations; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.Target; 5 | 6 | import static java.lang.annotation.ElementType.TYPE; 7 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 8 | 9 | /** 10 | * Annotate a class to provide a prefix. 11 | * 12 | * @author Colin Redmond (c) 2025. 13 | */ 14 | @Target(value = {TYPE}) 15 | @Retention(value = RUNTIME) 16 | public @interface ConfigPrefix { 17 | String prefix(); 18 | } 19 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/DBInfoExtended.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoExtended extends DBInfo { 4 | private int timeout = 10000; 5 | private String user = "admin"; 6 | 7 | public int getTimeout() { 8 | return timeout; 9 | } 10 | 11 | public void setTimeout(int timeout) { 12 | this.timeout = timeout; 13 | } 14 | 15 | public String getUser() { 16 | return user; 17 | } 18 | 19 | public void setUser(String user) { 20 | this.user = user; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/decoder/ProxyDecoderMode.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.decoder; 2 | 3 | /** 4 | * Enumeration of all modes for the proxy decoder. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public enum ProxyDecoderMode { 9 | 10 | // Values are cached and saved in the proxy object to be returned. Does not refresh if the configs are reloaded. 11 | CACHE, 12 | 13 | // Calls the gestalt library to get the proxy value for each method call. Will get the most recent values but have more overhead. 14 | PASSTHROUGH 15 | } 16 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/secret/rules/SecretChecker.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.secret.rules; 2 | 3 | public interface SecretChecker { 4 | 5 | /** 6 | * Checks if the given value matches any of the secret patterns. 7 | * 8 | * @param value the value to be checked 9 | * @return true if the value matches any secret pattern, false otherwise 10 | */ 11 | boolean isSecret(String value); 12 | 13 | /** 14 | * Adds a new Secret to the checker. 15 | * 16 | * @param rule the new secret to search for 17 | */ 18 | void addSecret(String rule); 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-test/src/test/resources/dev.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | subservice.booking.isEnabled=true 10 | subservice.booking.service.host=https://dev.bank.host.name 11 | subservice.booking.service.port=443 12 | subservice.booking.service.path=booking 13 | 14 | subservice.search.service.isEnabled=false 15 | 16 | admin.user=Peter, Kim, Steve 17 | admin.overrideEnabled=true 18 | 19 | -------------------------------------------------------------------------------- /gestalt-benchmark/src/jmh/resources/dev.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | subservice.booking.service.isEnabled=true 10 | subservice.booking.service.host=https://dev.bank.host.name 11 | subservice.booking.service.port=443 12 | subservice.booking.service.path=booking 13 | 14 | subservice.search.service.isEnabled=false 15 | 16 | admin.user=Peter, Kim, Steve 17 | admin.overrideEnabled=true 18 | 19 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/utils/SealedClassUtilTestOldJavaTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.utils; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | public class SealedClassUtilTestOldJavaTest { 7 | 8 | @Test 9 | void isSealed() { 10 | Assertions.assertFalse(SealedClassUtil.isSealed(Boolean.class)); 11 | } 12 | 13 | @Test 14 | void getPermittedSubclassesNonSealed() { 15 | Class[] retrieved = SealedClassUtil.getPermittedSubclasses(Boolean.class); 16 | 17 | Assertions.assertTrue(retrieved.length == 0); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/dev.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | subservice.booking.isEnabled=true 10 | subservice.booking.service.host=https://dev.bank.host.name 11 | subservice.booking.service.port=443 12 | subservice.booking.service.path=booking 13 | 14 | subservice.search.service.isEnabled=false 15 | 16 | admin.user=Peter, Kim, Steve 17 | admin.overrideEnabled=true 18 | 19 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/observations/ObservationRecord.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.observations; 2 | 3 | /** 4 | * An interface for an observation record, each observation implementation would add their own details to their implementation 5 | * to propagate observation data between a start call and a finish call. 6 | * 7 | * @author Colin Redmond (c) 2025. 8 | */ 9 | public interface ObservationRecord { 10 | /** 11 | * Get the name of the current metric. 12 | * 13 | * @return the name of the current metric. 14 | */ 15 | String metric(); 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/dev.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | subservice.booking.isEnabled=true 10 | subservice.booking.service.host=https://dev.bank.host.name 11 | subservice.booking.service.port=443 12 | subservice.booking.service.path=booking 13 | 14 | subservice.search.service.isEnabled=false 15 | 16 | admin.user=Peter, Kim, Steve 17 | admin.overrideEnabled=true 18 | 19 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/node/TagMergingStrategyFallback.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.node; 2 | 3 | import org.github.gestalt.config.tag.Tags; 4 | 5 | /** 6 | * Accepts the tags provided or fallback to the defaults. 7 | * 8 | * @author Colin Redmond (c) 2025. 9 | */ 10 | public class TagMergingStrategyFallback implements TagMergingStrategy { 11 | @Override 12 | public Tags mergeTags(Tags provided, Tags defaultTags) { 13 | if (provided != null) { 14 | return provided; 15 | } else { 16 | return defaultTags; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-java-records/src/test/resources/dev.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].url=jdbc:postgresql://dev.host.name1:5432/mydb 2 | db.hosts[1].url=jdbc:postgresql://dev.host.name2:5432/mydb 3 | db.hosts[2].url=jdbc:postgresql://dev.host.name3:5432/mydb 4 | db.connectionTimeout=600 5 | 6 | http.pool.maxTotal=1000 7 | http.pool.maxPerRoute=50 8 | 9 | subservice.booking.service.isEnabled=true 10 | subservice.booking.service.host=https://dev.bank.host.name 11 | subservice.booking.service.port=443 12 | subservice.booking.service.path=booking 13 | 14 | subservice.search.service.isEnabled=false 15 | 16 | admin.user=Peter, Kim, Steve 17 | admin.overrideEnabled=true 18 | 19 | -------------------------------------------------------------------------------- /gestalt-cdi/src/main/java/org/github/gestalt/config/cdi/InjectConfig.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.cdi; 2 | 3 | import jakarta.enterprise.util.Nonbinding; 4 | import jakarta.inject.Qualifier; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | @Qualifier 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) 14 | public @interface InjectConfig { 15 | @Nonbinding 16 | String path() default ""; 17 | 18 | @Nonbinding 19 | String defaultValue() default ""; 20 | } 21 | -------------------------------------------------------------------------------- /gestalt-git/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Module info definition for gestalt git integration 4 | */ 5 | @SuppressWarnings({ "requires-automatic", "requires-transitive-automatic" }) 6 | module org.github.gestalt.git { 7 | requires org.github.gestalt.core; 8 | requires transitive org.eclipse.jgit; 9 | 10 | exports org.github.gestalt.config.git; 11 | exports org.github.gestalt.config.git.builder; 12 | exports org.github.gestalt.config.git.config; 13 | exports org.github.gestalt.config.git.node.factory; 14 | 15 | provides org.github.gestalt.config.node.factory.ConfigNodeFactory with 16 | org.github.gestalt.config.git.node.factory.GitConfigNodeFactory; 17 | } 18 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/observations/TestObservationRecord.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.observations; 2 | 3 | import org.github.gestalt.config.tag.Tags; 4 | 5 | public class TestObservationRecord implements ObservationRecord { 6 | public double data; 7 | public boolean isOptional; 8 | public Tags tags; 9 | public String path; 10 | 11 | public TestObservationRecord(String path, double data, boolean isOptional, Tags tags) { 12 | this.path = path; 13 | this.data = data; 14 | this.isOptional = isOptional; 15 | this.tags = tags; 16 | } 17 | 18 | @Override 19 | public String metric() { 20 | return path; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /gestalt-kotlin/src/main/resources/META-INF/services/org.github.gestalt.config.decoder.Decoder: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.kotlin.decoder.BooleanDecoder 2 | org.github.gestalt.config.kotlin.decoder.ByteDecoder 3 | org.github.gestalt.config.kotlin.decoder.CharDecoder 4 | org.github.gestalt.config.kotlin.decoder.DataClassDecoder 5 | org.github.gestalt.config.kotlin.decoder.DoubleDecoder 6 | org.github.gestalt.config.kotlin.decoder.FloatDecoder 7 | org.github.gestalt.config.kotlin.decoder.IntegerDecoder 8 | org.github.gestalt.config.kotlin.decoder.KSealedDecoder 9 | org.github.gestalt.config.kotlin.decoder.LongDecoder 10 | org.github.gestalt.config.kotlin.decoder.ShortDecoder 11 | org.github.gestalt.config.kotlin.decoder.StringDecoder 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ########################################## 2 | # Common Settings 3 | ########################################## 4 | 5 | # This file is the top-most EditorConfig file 6 | root = true 7 | 8 | # All Files 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | indent_style = space 13 | indent_size = 2 14 | insert_final_newline = true 15 | trim_trailing_whitespace = true 16 | 17 | [*.java] 18 | indent_size = 4 19 | max_line_length = 140 20 | ij_visual_guides = 140 21 | ij_continuation_indent_size = 4 22 | 23 | [*.{kt,kts}] 24 | indent_size = 4 25 | max_line_length = 140 26 | ij_visual_guides = 140 27 | ij_continuation_indent_size = 4 28 | 29 | # Markdown & YAML Settings 30 | [*.{md,yml,yaml}] 31 | trim_trailing_whitespace = false 32 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/metadata/IsSecretMetadata.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.metadata; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class IsSecretMetadata extends MetaDataValue { 7 | public static String SECRET = "secret"; 8 | 9 | public IsSecretMetadata(Boolean value) { 10 | super(value); 11 | } 12 | 13 | @Override 14 | public String keyValue() { 15 | return SECRET; 16 | } 17 | 18 | // We do not want to rollup the IsSecretMetadata to the calling metadata 19 | @Override 20 | public Map>> rollup(Map>> metadata) { 21 | return metadata; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | DB: 3 | hosts: 4 | - user: credmond 5 | url: jdbc:postgresql://localhost:5432/mydb1 6 | - user: credmond 7 | url: jdbc:postgresql://localhost:5432/mydb2 8 | - user: credmond 9 | url: jdbc:postgresql://localhost:5432/mydb3 10 | ConnectionTimeout: 6000 11 | idleTimeout: 600 12 | maxLifetime: 60000 13 | http: 14 | pool: 15 | maxTotal: 100 16 | maxPerRoute: 10 17 | validateAfterInactivity: 6000 18 | keepAliveTimeoutMs: 60000 19 | idleTimeoutSec: 25 20 | ADMIN: 21 | user: John, Sarah 22 | overrideEnabled: false 23 | accessRole: level0 24 | employee: 25 | user: Janice 26 | accessRole: level1 27 | serviceMode: active 28 | -------------------------------------------------------------------------------- /gestalt-cdi/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.java-code-quality-conventions") 5 | id("gestalt.java-publish-conventions") 6 | } 7 | 8 | dependencies { 9 | implementation(project(":gestalt-core")) 10 | implementation(libs.cdi) 11 | testImplementation(libs.weld.junit5) { 12 | exclude(group = "javax.enterprise", module = "cdi-api") 13 | } 14 | testImplementation(libs.weld.core) 15 | testImplementation(libs.junit.testkit) 16 | testImplementation(libs.junit.commons) 17 | } 18 | 19 | tasks.jar { 20 | manifest { 21 | attributes("Automatic-Module-Name" to "org.github.gestalt.cdi") 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/node/TagMergingStrategyCombine.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.node; 2 | 3 | import org.github.gestalt.config.tag.Tags; 4 | 5 | /** 6 | * Merges the tags provided with the request and the default tags, then returns the results. 7 | * 8 | * @author Colin Redmond (c) 2025. 9 | */ 10 | public class TagMergingStrategyCombine implements TagMergingStrategy { 11 | @Override 12 | public Tags mergeTags(Tags provided, Tags defaultTags) { 13 | if (provided != null && !provided.equals(Tags.of())) { 14 | return provided.and(defaultTags); 15 | } else { 16 | return defaultTags; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfo.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfo { 4 | private int port; 5 | private String uri; 6 | private String password; 7 | 8 | public int getPort() { 9 | return port; 10 | } 11 | 12 | public void setPort(int port) { 13 | this.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | DB: 3 | hosts: 4 | - user: credmond 5 | url: jdbc:postgresql://localhost:5432/mydb1 6 | - user: credmond 7 | url: jdbc:postgresql://localhost:5432/mydb2 8 | - user: credmond 9 | url: jdbc:postgresql://localhost:5432/mydb3 10 | ConnectionTimeout: 6000 11 | idleTimeout: 600 12 | maxLifetime: 60000 13 | http: 14 | pool: 15 | maxTotal: 100 16 | maxPerRoute: 10 17 | validateAfterInactivity: 6000 18 | keepAliveTimeoutMs: 60000 19 | idleTimeoutSec: 25 20 | ADMIN: 21 | user: John, Sarah 22 | overrideEnabled: false 23 | accessRole: level0 24 | employee: 25 | user: Janice 26 | accessRole: level1 27 | serviceMode: active 28 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/annotations/ConfigPriority.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.annotations; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.Target; 5 | 6 | import static java.lang.annotation.ElementType.TYPE; 7 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 8 | 9 | /** 10 | * A annotation to apply a priority to a configuration. 11 | * 12 | * @author Colin Redmond (c) 2025. 13 | */ 14 | @Target(value = {TYPE}) 15 | @Retention(value = RUNTIME) 16 | public @interface ConfigPriority { 17 | 18 | /** 19 | * The priority of the Config. 20 | * 21 | * @return the priority value 22 | */ 23 | int value(); 24 | } 25 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/metadata/IsEncryptedMetadata.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.metadata; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class IsEncryptedMetadata extends MetaDataValue { 7 | public static String ENCRYPTED = "encrypted"; 8 | 9 | public IsEncryptedMetadata(Boolean value) { 10 | super(value); 11 | } 12 | 13 | @Override 14 | public String keyValue() { 15 | return ENCRYPTED; 16 | } 17 | 18 | // We do not want to rollup the IsSecretMetadata to the calling metadata 19 | @Override 20 | public Map>> rollup(Map>> metadata) { 21 | return metadata; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/metadata/IsTemporaryMetadata.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.metadata; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class IsTemporaryMetadata extends MetaDataValue { 7 | public static String TEMPORARY = "temporary"; 8 | 9 | public IsTemporaryMetadata(Integer value) { 10 | super(value); 11 | } 12 | 13 | @Override 14 | public String keyValue() { 15 | return TEMPORARY; 16 | } 17 | 18 | // We do not want to rollup the IsSecretMetadata to the calling metadata 19 | @Override 20 | public Map>> rollup(Map>> metadata) { 21 | return metadata; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoGeneric.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoGeneric { 4 | private T port; 5 | private String uri; 6 | private String password; 7 | 8 | public T getPort() { 9 | return port; 10 | } 11 | 12 | public void setPort(T port) { 13 | this.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-micrometer/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | import org.github.gestalt.config.observations.ObservationRecorder; 2 | import org.github.gestalt.config.micrometer.observations.MicrometerObservationRecorder; 3 | 4 | /* 5 | * Module info definition for gestalt micrometer integration 6 | */ 7 | @SuppressWarnings({ "requires-transitive-automatic" }) 8 | module org.github.gestalt.micrometer { 9 | requires org.github.gestalt.core; 10 | requires transitive micrometer.core; 11 | 12 | exports org.github.gestalt.config.micrometer.config; 13 | exports org.github.gestalt.config.micrometer.builder; 14 | exports org.github.gestalt.config.micrometer.observations; 15 | 16 | provides ObservationRecorder with 17 | MicrometerObservationRecorder; 18 | } 19 | -------------------------------------------------------------------------------- /gestalt-kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-library-conventions") 3 | id("gestalt.kotlin-common-conventions") 4 | id("gestalt.kotlin-test-conventions") 5 | id("gestalt.kotlin-code-quality-conventions") 6 | id("gestalt.java-publish-conventions") 7 | } 8 | 9 | dependencies { 10 | implementation(project(":gestalt-core")) 11 | api(libs.kotlin.reflection) 12 | } 13 | 14 | tasks.named("compileJava", JavaCompile::class.java) { 15 | options.compilerArgumentProviders.add(CommandLineArgumentProvider { 16 | // Provide compiled Kotlin classes to javac – needed for Java/Kotlin mixed sources to work 17 | listOf("--patch-module", "org.github.gestalt.config.kotlin=${sourceSets["main"].output.asPath}") 18 | }) 19 | } 20 | 21 | -------------------------------------------------------------------------------- /gestalt-validator-hibernate/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Module info definition for gestalt yaml integration 3 | */ 4 | @SuppressWarnings({ "requires-transitive-automatic" }) 5 | module org.github.gestalt.validation.hibernate { 6 | requires org.github.gestalt.core; 7 | requires transitive jakarta.validation; 8 | requires transitive org.hibernate.validator; 9 | 10 | exports com.github.gestalt.config.validation.hibernate; 11 | exports com.github.gestalt.config.validation.hibernate.config; 12 | exports com.github.gestalt.config.validation.hibernate.builder; 13 | 14 | provides org.github.gestalt.config.processor.result.validation.ConfigValidator with 15 | com.github.gestalt.config.validation.hibernate.HibernateConfigValidator; 16 | } 17 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/annotations/Config.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.annotations; 2 | 3 | import java.lang.annotation.Inherited; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.*; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Annotate a field or a method to optional modify the path or optionally add a default. 12 | * 13 | * @author Colin Redmond (c) 2025. 14 | */ 15 | @Target(value = {FIELD, METHOD}) 16 | @Inherited 17 | @Retention(value = RUNTIME) 18 | public @interface Config { 19 | String path() default ""; 20 | 21 | String defaultVal() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoIntegerPort.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoIntegerPort { 4 | private Integer port; 5 | private String uri; 6 | private String password; 7 | 8 | public Integer getPort() { 9 | return port; 10 | } 11 | 12 | public void setPort(int port) { 13 | this.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/default.conf: -------------------------------------------------------------------------------- 1 | ADMIN { 2 | accessRole=level0 3 | overrideEnabled=false 4 | user="John, Sarah" 5 | } 6 | DB { 7 | ConnectionTimeout=6000 8 | hosts=[ 9 | { 10 | url="jdbc:postgresql://localhost:5432/mydb1" 11 | user=credmond 12 | }, 13 | { 14 | url="jdbc:postgresql://localhost:5432/mydb2" 15 | user=credmond 16 | }, 17 | { 18 | url="jdbc:postgresql://localhost:5432/mydb3" 19 | user=credmond 20 | } 21 | ] 22 | idleTimeout=600 23 | maxLifetime=60000 24 | } 25 | employee { 26 | accessRole=level1 27 | user=Janice 28 | } 29 | http { 30 | pool { 31 | idleTimeoutSec=25 32 | keepAliveTimeoutMs=60000 33 | maxPerRoute=10 34 | maxTotal=100 35 | validateAfterInactivity=6000 36 | } 37 | } 38 | serviceMode=active 39 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/DBInfo.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfo { 4 | private int port; 5 | private String uri; 6 | private String password; 7 | 8 | public int getPort() { 9 | return port; 10 | } 11 | 12 | public void setPort(int port) { 13 | this.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/default.conf: -------------------------------------------------------------------------------- 1 | ADMIN { 2 | accessRole=level0 3 | overrideEnabled=false 4 | user="John, Sarah" 5 | } 6 | DB { 7 | ConnectionTimeout=6000 8 | hosts=[ 9 | { 10 | url="jdbc:postgresql://localhost:5432/mydb1" 11 | user=credmond 12 | }, 13 | { 14 | url="jdbc:postgresql://localhost:5432/mydb2" 15 | user=credmond 16 | }, 17 | { 18 | url="jdbc:postgresql://localhost:5432/mydb3" 19 | user=credmond 20 | } 21 | ] 22 | idleTimeout=600 23 | maxLifetime=60000 24 | } 25 | employee { 26 | accessRole=level1 27 | user=Janice 28 | } 29 | http { 30 | pool { 31 | idleTimeoutSec=25 32 | keepAliveTimeoutMs=60000 33 | maxPerRoute=10 34 | maxTotal=100 35 | validateAfterInactivity=6000 36 | } 37 | } 38 | serviceMode=active 39 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/decoder/Priority.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.decoder; 2 | 3 | /** 4 | * Ordered priority of the decoder. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public enum Priority { 9 | /** 10 | * HIGHEST Priority. 11 | */ 12 | HIGHEST, 13 | /** 14 | * VERY_HIGH Priority. 15 | */ 16 | VERY_HIGH, 17 | /** 18 | * HIGH Priority. 19 | */ 20 | HIGH, 21 | /** 22 | * MEDIUM Priority. 23 | */ 24 | MEDIUM, 25 | /** 26 | * LOW Priority. 27 | */ 28 | LOW, 29 | /** 30 | * VERY_LOW Priority. 31 | */ 32 | VERY_LOW, 33 | /** 34 | * LOWEST Priority. 35 | */ 36 | LOWEST 37 | } 38 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoSetterChangeValue.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoSetterChangeValue { 4 | private int port; 5 | private String uri; 6 | private String password; 7 | 8 | public int getPort() { 9 | return port; 10 | } 11 | 12 | public void setPort(int port) { 13 | this.port = port * 2; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri + "abc"; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = "****"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoStatic.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoStatic { 4 | private static int port; 5 | private String uri; 6 | private String password; 7 | 8 | public static int getPort() { 9 | return port; 10 | } 11 | 12 | public static void setPort(int port) { 13 | DBInfoStatic.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-guice/src/main/java/org/github/gestalt/config/guice/InjectConfig.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.guice; 2 | 3 | import java.lang.annotation.Inherited; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.FIELD; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Annotation to mark an object as a configuration for injection. 12 | * Must provide a path to the configuration. 13 | * Only supports fields. (limit of Guice) 14 | * 15 | * @author Colin Redmond (c) 2025. 16 | */ 17 | @Target(value = {FIELD}) 18 | @Inherited 19 | @Retention(value = RUNTIME) 20 | public @interface InjectConfig { 21 | String path(); 22 | } 23 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/DBInfoGeneric.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoGeneric { 4 | private T port; 5 | private String uri; 6 | private String password; 7 | 8 | public T getPort() { 9 | return port; 10 | } 11 | 12 | public void setPort(T port) { 13 | this.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/annotations/ConfigParameter.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.annotations; 2 | 3 | import java.lang.annotation.Inherited; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.Target; 6 | 7 | import static java.lang.annotation.ElementType.*; 8 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 9 | 10 | /** 11 | * Annotate a Parameters or a method to optional modify the path or optionally add a default. 12 | * 13 | * @author Colin Redmond (c) 2025. 14 | */ 15 | @Target(value = {PARAMETER}) 16 | @Inherited 17 | @Retention(value = RUNTIME) 18 | public @interface ConfigParameter { 19 | String path() default ""; 20 | 21 | String defaultVal() default ""; 22 | } 23 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoNoConstructor.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoNoConstructor { 4 | private int port = 100; 5 | private String uri = "test"; 6 | private String password = "password"; 7 | 8 | public int getPort() { 9 | return port; 10 | } 11 | 12 | public void setPort(int port) { 13 | this.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/java/org/github/gestalt/config/integration/TestObservationRecord.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.integration; 2 | 3 | import org.github.gestalt.config.observations.ObservationRecord; 4 | import org.github.gestalt.config.tag.Tags; 5 | 6 | public class TestObservationRecord implements ObservationRecord { 7 | public double data; 8 | public boolean isOptional; 9 | public Tags tags; 10 | public String path; 11 | 12 | public TestObservationRecord(String path, double data, boolean isOptional, Tags tags) { 13 | this.path = path; 14 | this.data = data; 15 | this.isOptional = isOptional; 16 | this.tags = tags; 17 | } 18 | 19 | @Override 20 | public String metric() { 21 | return path; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/reload/ConfigReloadListener.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.reload; 2 | 3 | import org.github.gestalt.config.exceptions.GestaltException; 4 | import org.github.gestalt.config.source.ConfigSourcePackage; 5 | 6 | /** 7 | * Listener for when configs need to reloads. This is for use internally, end users most likely should not use this. 8 | * 9 | * @author Colin Redmond (c) 2025. 10 | */ 11 | public interface ConfigReloadListener { 12 | /** 13 | * Called when a config needs to be reloaded. 14 | * 15 | * @param source the source we should reload. 16 | * @throws GestaltException any exceptions 17 | */ 18 | void reload(ConfigSourcePackage source) throws GestaltException; 19 | } 20 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/node/TagMergingStrategy.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.node; 2 | 3 | import org.github.gestalt.config.tag.Tags; 4 | 5 | /** 6 | * Merges the tags provided with the request and the default tags, then returns the results. 7 | * 8 | * @author Colin Redmond (c) 2025. 9 | */ 10 | public interface TagMergingStrategy { 11 | 12 | /** 13 | * Merges the tags provided with the request and the default tags, then returns the results. 14 | * 15 | * @param provided the tags provided with the request, can be null if not provided 16 | * @param defaultTags the default tags registered with Gestalt 17 | * @return the merged results 18 | */ 19 | Tags mergeTags(Tags provided, Tags defaultTags); 20 | } 21 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/path/mapper/StandardPathMapper.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.path.mapper; 2 | 3 | import org.github.gestalt.config.annotations.ConfigPriority; 4 | import org.github.gestalt.config.lexer.SentenceLexer; 5 | import org.github.gestalt.config.token.Token; 6 | import org.github.gestalt.config.utils.GResultOf; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Standard Path mapper looks for an exact match. 12 | * 13 | * @author Colin Redmond (c) 2025. 14 | */ 15 | @ConfigPriority(1000) 16 | public final class StandardPathMapper implements PathMapper { 17 | @Override 18 | public GResultOf> map(String path, String sentence, SentenceLexer lexer) { 19 | return lexer.scan(sentence); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoIntegerPortNonNullGetter.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoIntegerPortNonNullGetter { 4 | private Integer port; 5 | private String uri; 6 | private String password; 7 | 8 | public Integer getPort() { 9 | return port != null ? port : 1234; 10 | } 11 | 12 | public void setPort(int port) { 13 | this.port = port; 14 | } 15 | 16 | public String getUri() { 17 | return uri; 18 | } 19 | 20 | public void setUri(String uri) { 21 | this.uri = uri; 22 | } 23 | 24 | public String getPassword() { 25 | return password; 26 | } 27 | 28 | public void setPassword(String password) { 29 | this.password = password; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/node/NodeType.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.node; 2 | 3 | /** 4 | * Enumeration of all valid node types. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public enum NodeType { 9 | /** 10 | * Array node type. 11 | */ 12 | ARRAY("array"), 13 | /** 14 | * Map node type. 15 | */ 16 | MAP("map"), 17 | /** 18 | * Leaf node type. 19 | */ 20 | LEAF("leaf"); 21 | 22 | private final String type; 23 | 24 | NodeType(String type) { 25 | this.type = type; 26 | } 27 | 28 | /** 29 | * Get the type of this node. 30 | * 31 | * @return Get the type of this node 32 | */ 33 | public String getType() { 34 | return type; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/DBInfoNullable.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import jakarta.annotation.Nullable; 4 | 5 | public class DBInfoNullable { 6 | private int port; 7 | 8 | @Nullable 9 | private String uri; 10 | private String password; 11 | 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | public String getUri() { 21 | return uri; 22 | } 23 | 24 | public void setUri(String uri) { 25 | this.uri = uri; 26 | } 27 | 28 | public String getPassword() { 29 | return password; 30 | } 31 | 32 | public void setPassword(String password) { 33 | this.password = password; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/test/classes/DBInfoNullableGetter.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import jakarta.annotation.Nullable; 4 | 5 | public class DBInfoNullableGetter { 6 | private int port; 7 | 8 | private String uri; 9 | private String password; 10 | 11 | public int getPort() { 12 | return port; 13 | } 14 | 15 | public void setPort(int port) { 16 | this.port = port; 17 | } 18 | 19 | @Nullable 20 | public String getUri() { 21 | return uri; 22 | } 23 | 24 | public void setUri(String uri) { 25 | this.uri = uri; 26 | } 27 | 28 | public String getPassword() { 29 | return password; 30 | } 31 | 32 | public void setPassword(String password) { 33 | this.password = password; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gestalt-vault/src/main/java/org/github/gestalt/config/vault/config/VaultModuleConfig.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.vault.config; 2 | 3 | import io.github.jopenlibs.vault.Vault; 4 | import org.github.gestalt.config.entity.GestaltModuleConfig; 5 | 6 | 7 | /** 8 | * Vault specific configuration. 9 | * Provides a Vault client to the Vault transformer. 10 | * 11 | * @author Colin Redmond (c) 2025. 12 | */ 13 | public final class VaultModuleConfig implements GestaltModuleConfig { 14 | 15 | private final Vault vault; 16 | 17 | public VaultModuleConfig(Vault vault) { 18 | this.vault = vault; 19 | } 20 | 21 | @Override 22 | public String name() { 23 | return "vault"; 24 | } 25 | 26 | public Vault getVault() { 27 | return vault; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/metadata/IsRunTimeStringSubstitutionMetadata.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.metadata; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class IsRunTimeStringSubstitutionMetadata extends MetaDataValue { 7 | public static String RUN_TIME_STRING_SUBSTITUTION = "runTimeStringSubstitution"; 8 | 9 | public IsRunTimeStringSubstitutionMetadata(Boolean value) { 10 | super(value); 11 | } 12 | 13 | @Override 14 | public String keyValue() { 15 | return RUN_TIME_STRING_SUBSTITUTION; 16 | } 17 | 18 | // We do not want to rollup the IsSecretMetadata to the calling metadata 19 | @Override 20 | public Map>> rollup(Map>> metadata) { 21 | return metadata; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/logging.properties: -------------------------------------------------------------------------------- 1 | # Logs to file and console 2 | # handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler 3 | 4 | # Logs to console only 5 | handlers= java.util.logging.ConsoleHandler 6 | 7 | # Global logging levels, 7 levels 8 | .level= ALL 9 | 10 | # Log file output in user's home directory, %h 11 | java.util.logging.FileHandler.pattern = %h/java%u.log 12 | java.util.logging.FileHandler.limit = 40000 13 | java.util.logging.FileHandler.count = 1 14 | java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter 15 | # java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter 16 | 17 | java.util.logging.ConsoleHandler.level = ALL 18 | java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter 19 | 20 | java.util.logging.SimpleFormatter.format=[%1$tc] %4$s: %5$s %n 21 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/entity/ConfigValue.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.entity; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * Value for a config. Used to store the leaf value while parsing the configs. 7 | * 8 | * @author Colin Redmond (c) 2025. 9 | */ 10 | public final class ConfigValue { 11 | private final String value; 12 | 13 | /** 14 | * Constructor to hold a config value. 15 | * 16 | * @param value to hld hor the config 17 | */ 18 | public ConfigValue(String value) { 19 | this.value = Objects.requireNonNull(value, "value can not be null"); 20 | } 21 | 22 | /** 23 | * Get the config value. 24 | * 25 | * @return config value 26 | */ 27 | public String getValue() { 28 | return value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoPathAnnotation.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.ConfigPrefix; 4 | 5 | @ConfigPrefix(prefix = "db") 6 | public class DBInfoPathAnnotation { 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | public int getPort() { 12 | return port; 13 | } 14 | 15 | public void setPort(int port) { 16 | this.port = port; 17 | } 18 | 19 | public String getUri() { 20 | return uri; 21 | } 22 | 23 | public void setUri(String uri) { 24 | this.uri = uri; 25 | } 26 | 27 | public String getPassword() { 28 | return password; 29 | } 30 | 31 | public void setPassword(String password) { 32 | this.password = password; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoPrivateConstructor.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public final class DBInfoPrivateConstructor { 4 | private int port; 5 | private String uri; 6 | private String password; 7 | 8 | // private constructor 9 | private DBInfoPrivateConstructor() { 10 | } 11 | 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | public String getUri() { 21 | return uri; 22 | } 23 | 24 | public void setUri(String uri) { 25 | this.uri = uri; 26 | } 27 | 28 | public String getPassword() { 29 | return password; 30 | } 31 | 32 | public void setPassword(String password) { 33 | this.password = password; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoBadAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoBadAnnotations { 6 | @Config(path = "channel", defaultVal = "abc") 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | public int getPort() { 12 | return port; 13 | } 14 | 15 | public void setPort(int port) { 16 | this.port = port; 17 | } 18 | 19 | public String getUri() { 20 | return uri; 21 | } 22 | 23 | public void setUri(String uri) { 24 | this.uri = uri; 25 | } 26 | 27 | public String getPassword() { 28 | return password; 29 | } 30 | 31 | public void setPassword(String password) { 32 | this.password = password; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoOptional1.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import java.util.Optional; 4 | 5 | public class DBInfoOptional1 { 6 | private Integer port; 7 | private Optional uri; 8 | private Optional password; 9 | 10 | public Integer getPort() { 11 | return port; 12 | } 13 | 14 | public void setPort(int port) { 15 | this.port = port; 16 | } 17 | 18 | public Optional getUri() { 19 | return uri; 20 | } 21 | 22 | public void setUri(String uri) { 23 | this.uri = Optional.ofNullable(uri); 24 | } 25 | 26 | public Optional getPassword() { 27 | return password; 28 | } 29 | 30 | public void setPassword(String password) { 31 | this.password = Optional.ofNullable(password); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoPathMultiAnnotation.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.ConfigPrefix; 4 | 5 | @ConfigPrefix(prefix = "user.db") 6 | public class DBInfoPathMultiAnnotation { 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | public int getPort() { 12 | return port; 13 | } 14 | 15 | public void setPort(int port) { 16 | this.port = port; 17 | } 18 | 19 | public String getUri() { 20 | return uri; 21 | } 22 | 23 | public void setUri(String uri) { 24 | this.uri = uri; 25 | } 26 | 27 | public String getPassword() { 28 | return password; 29 | } 30 | 31 | public void setPassword(String password) { 32 | this.password = password; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gestalt-aws/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=600 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=false 16 | subservice.booking.service.host=http://localhost 17 | subservice.booking.service.port=8081 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /gestalt-azure/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=600 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=false 16 | subservice.booking.service.host=http://localhost 17 | subservice.booking.service.port=8081 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idle-timeout=600 9 | db.max_lifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=false 16 | subservice.booking.service.host=http://localhost 17 | subservice.booking.service.port=8081 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /gestalt-google-cloud/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=600 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=false 16 | subservice.booking.service.host=http://localhost 17 | subservice.booking.service.port=8081 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /.github/workflows/test-deploy.yml: -------------------------------------------------------------------------------- 1 | name: Test deployment 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | # Review gh actions docs if you want to further define triggers, paths, etc 8 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on 9 | 10 | defaults: 11 | run: 12 | shell: bash 13 | working-directory: ./docs/gestalt-static 14 | 15 | jobs: 16 | test-deploy: 17 | name: Test deployment 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v5 21 | with: 22 | fetch-depth: 0 23 | - uses: actions/setup-node@v5 24 | with: 25 | node-version: 18 26 | cache: npm 27 | cache-dependency-path: '**/package-lock.json' 28 | 29 | - name: Install dependencies 30 | run: npm ci 31 | - name: Test build website 32 | run: npm run build 33 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/modules/kodein-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # Kodein Dependency Injection 6 | When you are using Kodein you can use it to inject your configurations directly into your objects. 7 | By using the extension method `gestalt` within the scope of the Kodein DI DSL you can specify the path to your configurations, and it will automatically inject configurations into your object. 8 | 9 | See the [unit tests](https://github.com/gestalt-config/gestalt/blob/main/gestalt-kodein-di/src/test/kotlin/org/github/gestalt/config/kotlin/kodein/test/KodeinTest.kt) for examples of use. 10 | 11 | ```kotlin 12 | val kodein = DI { 13 | bindInstance { gestalt!! } 14 | bindSingleton { DBService1(gestalt("db")) } 15 | bindSingleton { DBService2(gestalt("db", DBInfoPOJO(port = 1000, password = "default"))) } 16 | } 17 | 18 | val dbService1 = kodein.direct.instance() 19 | ``` 20 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoBadMethodAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoBadMethodAnnotations { 6 | 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | @Config(path = "channel", defaultVal = "abc") 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | public String getUri() { 21 | return uri; 22 | } 23 | 24 | public void setUri(String uri) { 25 | this.uri = uri; 26 | } 27 | 28 | public String getPassword() { 29 | return password; 30 | } 31 | 32 | public void setPassword(String password) { 33 | this.password = password; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /gestalt-azure/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | import org.github.gestalt.config.azure.node.factory.BlobConfigNodeFactory; 2 | 3 | // Module info definition for gestalt azure integration 4 | module org.github.gestalt.azure { 5 | requires org.github.gestalt.core; 6 | requires com.azure.storage.blob; 7 | requires com.azure.security.keyvault.secrets; 8 | requires com.azure.identity; 9 | 10 | exports org.github.gestalt.config.azure.blob; 11 | exports org.github.gestalt.config.azure.config; 12 | exports org.github.gestalt.config.azure.errors; 13 | exports org.github.gestalt.config.azure.transformer; 14 | 15 | provides org.github.gestalt.config.processor.config.transform.Transformer with 16 | org.github.gestalt.config.azure.transformer.AzureSecretTransformer; 17 | 18 | provides org.github.gestalt.config.node.factory.ConfigNodeFactory with 19 | BlobConfigNodeFactory; 20 | } 21 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoOptional.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import java.util.Optional; 4 | 5 | public class DBInfoOptional { 6 | private Optional port; 7 | private Optional uri; 8 | private Optional password; 9 | 10 | public Optional getPort() { 11 | return port; 12 | } 13 | 14 | public void setPort(int port) { 15 | this.port = Optional.of(port); 16 | } 17 | 18 | public Optional getUri() { 19 | return uri; 20 | } 21 | 22 | public void setUri(String uri) { 23 | this.uri = Optional.ofNullable(uri); 24 | } 25 | 26 | public Optional getPassword() { 27 | return password; 28 | } 29 | 30 | public void setPassword(String password) { 31 | this.password = Optional.ofNullable(password); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /gestalt-guice/src/main/java/org/github/gestalt/config/guice/GestaltModule.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.guice; 2 | 3 | import com.google.inject.AbstractModule; 4 | import com.google.inject.matcher.Matchers; 5 | import org.github.gestalt.config.Gestalt; 6 | 7 | /** 8 | * Example of a module you can use to inject an instance of Gestalt 9 | * and bind the typeListener needed to inject using annotation @InjectConfig. 10 | * 11 | * @author Colin Redmond (c) 2025. 12 | */ 13 | public final class GestaltModule extends AbstractModule { 14 | private final Gestalt gestalt; 15 | 16 | public GestaltModule(Gestalt gestalt) { 17 | this.gestalt = gestalt; 18 | } 19 | 20 | @Override 21 | protected void configure() { 22 | bindListener(Matchers.any(), new GestaltConfigTypeListener(gestalt)); 23 | bind(Gestalt.class).toInstance(gestalt); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoBadAnnotationsWithClassDefault.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoBadAnnotationsWithClassDefault { 6 | @Config(path = "channel", defaultVal = "abc") 7 | private Integer port = 1000; 8 | private String uri; 9 | private String password; 10 | 11 | public Integer getPort() { 12 | return port; 13 | } 14 | 15 | public void setPort(int port) { 16 | this.port = port; 17 | } 18 | 19 | public String getUri() { 20 | return uri; 21 | } 22 | 23 | public void setUri(String uri) { 24 | this.uri = uri; 25 | } 26 | 27 | public String getPassword() { 28 | return password; 29 | } 30 | 31 | public void setPassword(String password) { 32 | this.password = password; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gestalt-kotlin/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.connectionTimeout=6000 8 | db.idleTimeout=600 9 | db.maxLifetime=60000.0 10 | 11 | http.pool.maxTotal=100 12 | http.pool.maxPerRoute=10 13 | http.pool.validateAfterInactivity=6000 14 | http.pool.keepAliveTimeoutMs=60000 15 | http.pool.idleTimeoutSec=25 16 | 17 | subservice.booking.isEnabled=false 18 | subservice.booking.service.host=http://localhost 19 | subservice.booking.service.port=8081 20 | subservice.booking.service.path=booking 21 | 22 | 23 | admin.users=John, Sarah 24 | admin.overrideEnabled=false 25 | admin.accessRole=level0 26 | 27 | employee.users=Janice 28 | employee.accessRole=level1 29 | 30 | serviceMode=active 31 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/modules/koin-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Koin Dependency Injection 6 | When you are using Koin you can use it to inject your configurations directly into your objects. 7 | By using the extension method `gestalt` within the scope of the koin module DSL you can specify the path to your configurations, and it will automatically inject configurations into your object. 8 | 9 | See the [unit tests](https://github.com/gestalt-config/gestalt/blob/main/gestalt-koin-di/src/test/kotlin/org/github/gestalt/config/kotlin/koin/test/KoinTest.kt) for examples of use. 10 | 11 | ```kotlin 12 | val koinModule = module { 13 | single { gestalt!! } 14 | single { DBService1(gestalt("db")) } 15 | single { DBService2(gestalt("db", DBInfoPOJO(port = 1000, password = "default"))) } 16 | } 17 | 18 | val myApp = koinApplication { 19 | modules(koinModule) 20 | } 21 | 22 | val dbService1: DBService1 = myApp.koin.get() 23 | ``` 24 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/secret/rules/RegexSecretCheckerTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.secret.rules; 2 | 3 | 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.HashSet; 8 | import java.util.Set; 9 | 10 | class RegexSecretCheckerTest { 11 | 12 | @Test 13 | public void checkIsSecret() { 14 | Set secretRegex = new HashSet<>(); 15 | secretRegex.add(".*secret.*"); // Sample secret regex 16 | SecretChecker secretChecker = new RegexSecretChecker(secretRegex); 17 | 18 | Assertions.assertTrue(secretChecker.isSecret("my.secret")); 19 | Assertions.assertFalse(secretChecker.isSecret("password")); 20 | 21 | secretChecker.addSecret(".*password.*"); 22 | Assertions.assertTrue(secretChecker.isSecret("my.secret")); 23 | Assertions.assertTrue(secretChecker.isSecret("password")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /benchmark.ps1: -------------------------------------------------------------------------------- 1 | #$gestaltVersions = @("0.32.0", "0.31.3", "0.31.2", "0.31.1", "0.31.0", "0.30.0", "0.29.0", "0.28.0", "0.27.0", "0.26.0", "0.25.3", "0.25.2", "0.25.1", "0.25.0", "0.24.6", "0.24.5", "0.24.4", "0.24.3", "0.24.2", "0.24.1", "0.24.0", "0.23.3", "0.23.2", "0.23.1", "0.23.0", "0.22.1", "0.21.0", "0.20.6", "0.20.5", "0.20.4", "0.20.3", "0.20.2", "0.20.1", "0.19.0", "0.18.0", "0.16.6", "0.16.5", "0.16.4", "0.16.3", "0.16.2", "0.16.1", "0.16.0", "0.15.0", "0.14.1", "0.14.0", "0.13.0", "0.12.0") 2 | $gestaltVersions = @("0.35.0", "0.34.0", "0.33.1", "0.33.0", "0.32.0", "0.32.2", "0.32.1","0.32.0", "0.31.3", "0.31.2", "0.31.1", "0.31.0") 3 | #jdkVersions = @(11 17 21) 4 | $jdkVersions = @(11) 5 | 6 | foreach ($jdkVersion in $jdkVersions) 7 | { 8 | foreach ($gestaltVersion in $gestaltVersions) 9 | { 10 | $gradleCommand = "./gradlew jmh -PgestaltVersion=`"$gestaltVersion`" -PjdkVersion=`"$jdkVersion`"" 11 | Invoke-Expression $gradleCommand 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /docs/gestalt-static/README.md: -------------------------------------------------------------------------------- 1 | # Website 2 | 3 | This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. 4 | 5 | ### Installation 6 | 7 | ``` 8 | $ yarn 9 | ``` 10 | 11 | ### Local Development 12 | 13 | ``` 14 | $ yarn start 15 | ``` 16 | 17 | This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. 18 | 19 | ### Build 20 | 21 | ``` 22 | $ yarn build 23 | ``` 24 | 25 | This command generates static content into the `build` directory and can be served using any static contents hosting service. 26 | 27 | ### Deployment 28 | 29 | Using SSH: 30 | 31 | ``` 32 | $ USE_SSH=true yarn deploy 33 | ``` 34 | 35 | Not using SSH: 36 | 37 | ``` 38 | $ GIT_USER= yarn deploy 39 | ``` 40 | 41 | If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. 42 | -------------------------------------------------------------------------------- /.sonarcloud.properties: -------------------------------------------------------------------------------- 1 | # Path to sources 2 | #sonar.sources= 3 | #sonar.exclusions= 4 | #sonar.inclusions= 5 | 6 | # Path to tests 7 | #sonar.tests= 8 | #sonar.test.exclusions= 9 | #sonar.test.inclusions= 10 | 11 | # Source encoding 12 | #sonar.sourceEncoding=UTF-8 13 | 14 | # Exclusions for copy-paste detection 15 | #sonar.cpd.exclusions= 16 | 17 | # Ignore Issues on Files 18 | sonar.issue.ignore.allfile= 19 | 20 | # Restrict Scope of Coding Rules 21 | sonar.issue.ignore.multicriteria.S6201.resourceKey="**/*" 22 | sonar.issue.ignore.multicriteria.S6201.ruleKey="java:S6201" 23 | 24 | sonar.issue.ignore.multicriteria.S6204.resourceKey="**/*" 25 | sonar.issue.ignore.multicriteria.S6204.ruleKey="java:S6204" 26 | 27 | sonar.issue.ignore.multicriteria.S6206.resourceKey="**/*" 28 | sonar.issue.ignore.multicriteria.S6206.ruleKey="java:S6206" 29 | 30 | sonar.issue.ignore.multicriteria.S6208.resourceKey="**/*" 31 | sonar.issue.ignore.multicriteria.S6208.ruleKey="java:S6208" 32 | 33 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/entity/ValidationLevel.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.entity; 2 | 3 | /** 4 | * Level of the error, we can recover from warnings but may want to fail on errors. 5 | * 6 | * @author Colin Redmond (c) 2025. 7 | */ 8 | public enum ValidationLevel { 9 | /** 10 | * Error validation level. 11 | */ 12 | ERROR, 13 | /** 14 | * Missing value validation level. Represents a class of errors where we are missing a value. 15 | */ 16 | MISSING_VALUE, 17 | /** 18 | * Missing optional value validation level. Represents a class of errors where we are missing a value. 19 | * But the value is optional, so in most cases it is ok. 20 | */ 21 | MISSING_OPTIONAL_VALUE, 22 | /** 23 | * Warning validation level. 24 | */ 25 | WARN, 26 | /** 27 | * debug validation level. 28 | */ 29 | DEBUG 30 | } 31 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoAnnotationsDefault.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoAnnotationsDefault implements IDBInfoAnnotations { 6 | @Config(defaultVal = "1234") 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | @Override 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | @Override 21 | public String getUri() { 22 | return uri; 23 | } 24 | 25 | public void setUri(String uri) { 26 | this.uri = uri; 27 | } 28 | 29 | @Override 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | public void setPassword(String password) { 35 | this.password = password; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gestalt-hocon/src/test/java/org/github/gestalt/config/hocon/HoconModuleConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.hocon; 2 | 3 | import com.typesafe.config.ConfigParseOptions; 4 | import org.github.gestalt.config.lexer.PathLexer; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | 9 | class HoconModuleConfigTest { 10 | 11 | @Test 12 | public void createModuleConfig() { 13 | var configParser = ConfigParseOptions.defaults(); 14 | var lexer = new PathLexer(); 15 | var builder = HoconModuleConfigBuilder.builder() 16 | .setConfigParseOptions(configParser) 17 | .setLexer(lexer); 18 | 19 | var moduleConfig = builder.build(); 20 | 21 | Assertions.assertEquals(configParser, moduleConfig.getConfigParseOptions()); 22 | Assertions.assertEquals(lexer, moduleConfig.getLexer()); 23 | Assertions.assertEquals("hocon", moduleConfig.name()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gestalt-json/src/test/java/org/github/gestalt/config/json/JsonModuleConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.json; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.github.gestalt.config.lexer.PathLexer; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | 9 | class JsonModuleConfigTest { 10 | 11 | @Test 12 | public void createModuleConfig() { 13 | var objectMapper = new ObjectMapper().findAndRegisterModules(); 14 | var lexer = new PathLexer(); 15 | var builder = JsonModuleConfigBuilder.builder() 16 | .setObjectMapper(objectMapper) 17 | .setLexer(lexer); 18 | 19 | var moduleConfig = builder.build(); 20 | 21 | Assertions.assertEquals(objectMapper, moduleConfig.getObjectMapper()); 22 | Assertions.assertEquals(lexer, moduleConfig.getLexer()); 23 | Assertions.assertEquals("json", moduleConfig.name()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoAnnotations implements IDBInfoAnnotations { 6 | @Config(path = "channel", defaultVal = "1234") 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | @Override 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | @Override 21 | public String getUri() { 22 | return uri; 23 | } 24 | 25 | public void setUri(String uri) { 26 | this.uri = uri; 27 | } 28 | 29 | @Override 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | public void setPassword(String password) { 35 | this.password = password; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/secret/rules/RegexSecretChecker.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.secret.rules; 2 | 3 | import java.util.Set; 4 | import java.util.regex.Pattern; 5 | import java.util.stream.Collectors; 6 | 7 | public class RegexSecretChecker implements SecretChecker { 8 | private final Set secretRegex; 9 | 10 | public RegexSecretChecker(String secretRegex) { 11 | this.secretRegex = Set.of(Pattern.compile(secretRegex)); 12 | } 13 | 14 | public RegexSecretChecker(Set secretRegex) { 15 | this.secretRegex = secretRegex.stream().map(Pattern::compile).collect(Collectors.toSet()); 16 | } 17 | 18 | @Override 19 | public boolean isSecret(String value) { 20 | return secretRegex.stream().anyMatch(rule -> rule.matcher(value).find()); 21 | } 22 | 23 | @Override 24 | public void addSecret(String rule) { 25 | secretRegex.add(Pattern.compile(rule)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoMethodAnnotationsDefault.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoMethodAnnotationsDefault implements IDBInfoAnnotations { 6 | private int port; 7 | private String uri; 8 | private String password; 9 | 10 | @Override 11 | @Config(defaultVal = "1234") 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | @Override 21 | public String getUri() { 22 | return uri; 23 | } 24 | 25 | public void setUri(String uri) { 26 | this.uri = uri; 27 | } 28 | 29 | @Override 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | public void setPassword(String password) { 35 | this.password = password; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "DB": { 3 | "hosts": [{ 4 | "user": "credmond", 5 | "url": "jdbc:postgresql://localhost:5432/mydb1" 6 | }, { 7 | "user": "credmond", 8 | "url": "jdbc:postgresql://localhost:5432/mydb2" 9 | }, { 10 | "user": "credmond", 11 | "url": "jdbc:postgresql://localhost:5432/mydb3" 12 | } 13 | ], 14 | "ConnectionTimeout": 6000, 15 | "idleTimeout": 600, 16 | "maxLifetime": 60000.0 17 | }, 18 | "http": { 19 | "pool": { 20 | "maxTotal": 100, 21 | "maxPerRoute": 10, 22 | "validateAfterInactivity": 6000, 23 | "keepAliveTimeoutMs": 60000, 24 | "idleTimeoutSec": 25 25 | } 26 | }, 27 | "ADMIN": { 28 | "user": "John, Sarah", 29 | "overrideEnabled": false, 30 | "accessRole": "level0" 31 | }, 32 | "employee": { 33 | "user": "Janice", 34 | "accessRole": "level1" 35 | }, 36 | "serviceMode": "active" 37 | } 38 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "gestalt" 2 | include( 3 | "gestalt-aws", "gestalt-azure", "gestalt-cdi", "gestalt-core", "gestalt-hocon", "gestalt-json", "gestalt-git", 4 | "gestalt-google-cloud", "gestalt-guice", "gestalt-kotlin", "gestalt-micrometer", "gestalt-kodein-di", 5 | "gestalt-koin-di", "gestalt-toml", "gestalt-validator-hibernate", "gestalt-vault", "gestalt-yaml" 6 | ) 7 | 8 | // testing utility projects 9 | include( 10 | "code-coverage-report", "gestalt-benchmark", "gestalt-examples:gestalt-sample", 11 | "gestalt-examples:gestalt-sample-module", "gestalt-examples:gestalt-sample-java-records", "gestalt-test") 12 | 13 | pluginManagement { 14 | repositories { 15 | gradlePluginPortal() 16 | mavenCentral() 17 | } 18 | } 19 | 20 | plugins { 21 | id("org.gradle.toolchains.foojay-resolver-convention") version("1.0.0") 22 | } 23 | 24 | dependencyResolutionManagement { 25 | repositories { 26 | mavenCentral() 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoAnnotationsLong.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoAnnotationsLong implements IDBInfoAnnotations { 6 | @Config(path = "channel.port", defaultVal = "1234") 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | @Override 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | @Override 21 | public String getUri() { 22 | return uri; 23 | } 24 | 25 | public void setUri(String uri) { 26 | this.uri = uri; 27 | } 28 | 29 | @Override 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | public void setPassword(String password) { 35 | this.password = password; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoMethodAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoMethodAnnotations implements IDBInfoAnnotations { 6 | private int port; 7 | private String uri; 8 | private String password; 9 | 10 | @Override 11 | @Config(path = "channel", defaultVal = "1234") 12 | public int getPort() { 13 | return port; 14 | } 15 | 16 | public void setPort(int port) { 17 | this.port = port; 18 | } 19 | 20 | @Override 21 | public String getUri() { 22 | return uri; 23 | } 24 | 25 | public void setUri(String uri) { 26 | this.uri = uri; 27 | } 28 | 29 | @Override 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | public void setPassword(String password) { 35 | this.password = password; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "DB": { 3 | "hosts": [{ 4 | "user": "credmond", 5 | "url": "jdbc:postgresql://localhost:5432/mydb1" 6 | }, { 7 | "user": "credmond", 8 | "url": "jdbc:postgresql://localhost:5432/mydb2" 9 | }, { 10 | "user": "credmond", 11 | "url": "jdbc:postgresql://localhost:5432/mydb3" 12 | } 13 | ], 14 | "ConnectionTimeout": 6000, 15 | "idleTimeout": 600, 16 | "maxLifetime": 60000.0 17 | }, 18 | "http": { 19 | "pool": { 20 | "maxTotal": 100, 21 | "maxPerRoute": 10, 22 | "validateAfterInactivity": 6000, 23 | "keepAliveTimeoutMs": 60000, 24 | "idleTimeoutSec": 25 25 | } 26 | }, 27 | "ADMIN": { 28 | "user": "John, Sarah", 29 | "overrideEnabled": false, 30 | "accessRole": "level0" 31 | }, 32 | "employee": { 33 | "user": "Janice", 34 | "accessRole": "level1" 35 | }, 36 | "serviceMode": "active" 37 | } 38 | -------------------------------------------------------------------------------- /gestalt-validator-hibernate/src/test/java/com/github/gestalt/config/validation/hibernate/builder/HibernateModuleBuilderTest.java: -------------------------------------------------------------------------------- 1 | package com.github.gestalt.config.validation.hibernate.builder; 2 | 3 | import jakarta.validation.Validation; 4 | import jakarta.validation.ValidatorFactory; 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | class HibernateModuleBuilderTest { 9 | 10 | @Test 11 | public void builderTest() { 12 | ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 13 | var validator = factory.getValidator(); 14 | HibernateModuleBuilder builder = HibernateModuleBuilder.builder().setValidator(validator); 15 | 16 | Assertions.assertEquals(validator, builder.getValidator()); 17 | 18 | var config = builder.build(); 19 | Assertions.assertEquals(validator, config.getValidator()); 20 | Assertions.assertEquals("hibernate-validator", config.name()); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoMethodAnnotationsLong.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoMethodAnnotationsLong implements IDBInfoAnnotations { 6 | 7 | private int port; 8 | private String uri; 9 | private String password; 10 | 11 | @Override 12 | @Config(path = "channel.port", defaultVal = "1234") 13 | public int getPort() { 14 | return port; 15 | } 16 | 17 | public void setPort(int port) { 18 | this.port = port; 19 | } 20 | 21 | @Override 22 | public String getUri() { 23 | return uri; 24 | } 25 | 26 | public void setUri(String uri) { 27 | this.uri = uri; 28 | } 29 | 30 | @Override 31 | public String getPassword() { 32 | return password; 33 | } 34 | 35 | public void setPassword(String password) { 36 | this.password = password; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gestalt-kodein-di/src/main/kotlin/org/github/gestalt/config/kotlin/kodein/Kodein.kt: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.kotlin.kodein 2 | 3 | import org.github.gestalt.config.Gestalt 4 | import org.github.gestalt.config.kotlin.reflect.KTypeCapture 5 | import org.kodein.di.DirectDIAware 6 | import org.kodein.di.instance 7 | import kotlin.reflect.typeOf 8 | 9 | /** 10 | * Extension function for Kodein to allow us to inject configuration using the method gestalt 11 | * 12 | * @author Colin Redmond (c) 2025. 13 | */ 14 | inline fun DirectDIAware.gestalt( 15 | path: String, 16 | default: T? = null, 17 | gestaltTag: Any? = null 18 | ): T { 19 | val gestalt = this.directDI.instance(gestaltTag) 20 | return if (default != null) { 21 | gestalt.getConfig(path, default, KTypeCapture.of(typeOf())) as T 22 | } else { 23 | gestalt.getConfig(path, KTypeCapture.of(typeOf())) as T 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/defaultPPSys.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${sys:DB_IDLETIMEOUT} 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${sys:SUBSERVICE_BOOKING_ISENABLED} 16 | subservice.booking.service.host=${sys:SUBSERVICE_BOOKING_SERVICE_HOST} 17 | subservice.booking.service.port=${sys:SUBSERVICE_BOOKING_SERVICE_PORT} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/annotation/SecretAnnotationMetadataTransform.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config.annotation; 2 | 3 | import org.github.gestalt.config.metadata.IsSecretMetadata; 4 | import org.github.gestalt.config.metadata.MetaDataValue; 5 | import org.github.gestalt.config.utils.GResultOf; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public class SecretAnnotationMetadataTransform implements AnnotationMetadataTransform { 11 | @Override 12 | public String name() { 13 | return "secret"; 14 | } 15 | 16 | @Override 17 | public GResultOf>>> annotationTransform(String name, String parameter) { 18 | boolean value = true; 19 | if (parameter != null && !parameter.isEmpty()) { 20 | value = Boolean.parseBoolean(parameter); 21 | } 22 | 23 | return GResultOf.result(Map.of(IsSecretMetadata.SECRET, List.of(new IsSecretMetadata(value)))); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gestalt-core/src/test/resources/defaultPPEnv.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${env:DB_IDLETIMEOUT:=900} 9 | db.maxLifetime=${env:NO_RESULTS_FOUND:=60000.0} 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${env:SUBSERVICE_BOOKING_ISENABLED} 16 | subservice.booking.service.host=${env:SUBSERVICE_BOOKING_SERVICE_HOST} 17 | subservice.booking.service.port=${env:SUBSERVICE_BOOKING_SERVICE_PORT} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/annotation/NoCacheAnnotationMetadataTransform.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config.annotation; 2 | 3 | import org.github.gestalt.config.metadata.IsNoCacheMetadata; 4 | import org.github.gestalt.config.metadata.MetaDataValue; 5 | import org.github.gestalt.config.utils.GResultOf; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | public class NoCacheAnnotationMetadataTransform implements AnnotationMetadataTransform { 11 | @Override 12 | public String name() { 13 | return "nocache"; 14 | } 15 | 16 | @Override 17 | public GResultOf>>> annotationTransform(String name, String parameter) { 18 | boolean value = true; 19 | if (parameter != null && !parameter.isEmpty()) { 20 | value = Boolean.parseBoolean(parameter); 21 | } 22 | 23 | return GResultOf.result(Map.of(IsNoCacheMetadata.NO_CACHE, List.of(new IsNoCacheMetadata(value)))); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoBothAnnotations.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfoBothAnnotations implements IDBInfoAnnotations { 6 | 7 | @Config(path = "channel", defaultVal = "1234") 8 | private int port; 9 | private String uri; 10 | private String password; 11 | 12 | @Override 13 | @Config(path = "socket", defaultVal = "6789") 14 | public int getPort() { 15 | return port; 16 | } 17 | 18 | public void setPort(int port) { 19 | this.port = port; 20 | } 21 | 22 | @Override 23 | public String getUri() { 24 | return uri; 25 | } 26 | 27 | public void setUri(String uri) { 28 | this.uri = uri; 29 | } 30 | 31 | @Override 32 | public String getPassword() { 33 | return password; 34 | } 35 | 36 | public void setPassword(String password) { 37 | this.password = password; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/secret/rules/SecretConcealer.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.secret.rules; 2 | 3 | import org.github.gestalt.config.metadata.MetaDataValue; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Interface to system to conceal secret. For a node the path and value are passed in, and it returns either the value or a masked value. 10 | * 11 | * @author Colin Redmond (c) 2025. 12 | */ 13 | public interface SecretConcealer { 14 | 15 | /** 16 | * returns the value that is concealed if it is a secret. Otherwise, returns the value. 17 | * 18 | * @param path path of the value 19 | * @param value value we are checking if we need to conceal. 20 | * @param metadata metadata used to decide if this is a secret. 21 | * @return the value that is concealed if it is a secret. 22 | */ 23 | String concealSecret(String path, String value, Map>> metadata); 24 | } 25 | -------------------------------------------------------------------------------- /gestalt-test/src/test/java/org/github/gestalt/config/model/DBInfo.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.model; 2 | 3 | import org.github.gestalt.config.annotations.Config; 4 | 5 | public class DBInfo { 6 | private int port; 7 | private String uri; 8 | private String password; 9 | private Integer connections; 10 | 11 | public int getPort() { 12 | return port; 13 | } 14 | 15 | public void setPort(int port) { 16 | this.port = port; 17 | } 18 | 19 | public String getUri() { 20 | return uri; 21 | } 22 | 23 | public void setUri(String uri) { 24 | this.uri = uri; 25 | } 26 | 27 | public String getPassword() { 28 | return password; 29 | } 30 | 31 | public void setPassword(String password) { 32 | this.password = password; 33 | } 34 | 35 | public Integer getConnections() { 36 | return connections; 37 | } 38 | 39 | public void setConnections(Integer connections) { 40 | this.connections = connections; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /gestalt-toml/src/test/java/org/github/gestalt/config/toml/TomlModuleConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.toml; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.dataformat.toml.TomlFactory; 5 | import org.github.gestalt.config.lexer.PathLexer; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | 10 | class TomlModuleConfigTest { 11 | 12 | @Test 13 | public void createModuleConfig() { 14 | var objectMapper = new ObjectMapper(new TomlFactory()).findAndRegisterModules(); 15 | var lexer = new PathLexer(); 16 | var builder = TomlModuleConfigBuilder.builder() 17 | .setObjectMapper(objectMapper) 18 | .setLexer(lexer); 19 | 20 | var moduleConfig = builder.build(); 21 | 22 | Assertions.assertEquals(objectMapper, moduleConfig.getObjectMapper()); 23 | Assertions.assertEquals(lexer, moduleConfig.getLexer()); 24 | Assertions.assertEquals("toml", moduleConfig.name()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gestalt-yaml/src/test/java/org/github/gestalt/config/yaml/YamlModuleConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.yaml; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; 5 | import org.github.gestalt.config.lexer.PathLexer; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | 10 | class YamlModuleConfigTest { 11 | 12 | @Test 13 | public void createModuleConfig() { 14 | var objectMapper = new ObjectMapper(new YAMLFactory()).findAndRegisterModules(); 15 | var lexer = new PathLexer(); 16 | var builder = YamlModuleConfigBuilder.builder() 17 | .setObjectMapper(objectMapper) 18 | .setLexer(lexer); 19 | 20 | var moduleConfig = builder.build(); 21 | 22 | Assertions.assertEquals(objectMapper, moduleConfig.getObjectMapper()); 23 | Assertions.assertEquals(lexer, moduleConfig.getLexer()); 24 | Assertions.assertEquals("yaml", moduleConfig.name()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/modules/guice-injection.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Guice Dependency Injection. 6 | Allow Gestalt to inject configuration directly into your classes using Guice using the `@InjectConfig` annotation on any class fields. This does not support constructor injection (due to Guice limitation) 7 | To enable add the `new GestaltModule(gestalt)` to your Guice Modules, then pass in your instance of Gestalt. 8 | 9 | See the [unit tests](https://github.com/gestalt-config/gestalt/blob/main/gestalt-guice/src/test/java/org/github/gestalt/config/guice/GuiceTest.java) for examples of use. 10 | ```java 11 | Injector injector = Guice.createInjector(new GestaltModule(gestalt)); 12 | 13 | MyService service = injector.getInstance(MyService.class); 14 | 15 | // use the InjectConfig along with the path to inject configuration. 16 | public static class MyService { 17 | @InjectConfig(path = "db.user") DBConnection connection; 18 | 19 | public DBConnection getConnection() { 20 | return connection; 21 | } 22 | } 23 | ````` 24 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/defaultPPEnv.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${env:DB_IDLETIMEOUT:=900} 9 | db.maxLifetime=${env:NO_RESULTS_FOUND:=60000.0} 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${env:SUBSERVICE_BOOKING_ISENABLED} 16 | subservice.booking.service.host=${env:SUBSERVICE_BOOKING_SERVICE_HOST} 17 | subservice.booking.service.port=${env:SUBSERVICE_BOOKING_SERVICE_PORT} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/annotation/AnnotationMetadataTransform.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config.annotation; 2 | 3 | import org.github.gestalt.config.metadata.MetaDataValue; 4 | import org.github.gestalt.config.utils.GResultOf; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public interface AnnotationMetadataTransform { 10 | 11 | /** 12 | * the name that will match the ${annotation:parameter} the transform is selected that matches the same name. 13 | * 14 | * @return the name of the transform 15 | */ 16 | String name(); 17 | 18 | /** 19 | * Takes in the name of the annotation along with any parameters then returns a MetaDataValue. 20 | * 21 | * @param name name of the annotation 22 | * @param parameter parameters for the annotation 23 | * @return a annotation converted into a MetaDataValue 24 | */ 25 | GResultOf>>> annotationTransform(String name, String parameter); 26 | } 27 | -------------------------------------------------------------------------------- /gestalt-core/src/main/resources/META-INF/services/org.github.gestalt.config.processor.config.transform.Transformer: -------------------------------------------------------------------------------- 1 | org.github.gestalt.config.processor.config.transform.Base64DecoderTransformer 2 | org.github.gestalt.config.processor.config.transform.Base64EncoderTransformer 3 | org.github.gestalt.config.processor.config.transform.ClasspathTransformer 4 | org.github.gestalt.config.processor.config.transform.Distribution100Transformer 5 | org.github.gestalt.config.processor.config.transform.EnvironmentVariablesTransformer 6 | org.github.gestalt.config.processor.config.transform.EnvironmentVariablesTransformerOld 7 | org.github.gestalt.config.processor.config.transform.FileTransformer 8 | org.github.gestalt.config.processor.config.transform.SystemPropertiesTransformer 9 | org.github.gestalt.config.processor.config.transform.NodeTransformer 10 | org.github.gestalt.config.processor.config.transform.RandomTransformer 11 | org.github.gestalt.config.processor.config.transform.URLDecoderTransformer 12 | org.github.gestalt.config.processor.config.transform.URLEncoderTransformer 13 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoNoDefaultConstructor.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoNoDefaultConstructor { 4 | private int port; 5 | private String uri; 6 | private String password; 7 | 8 | // no default constructor 9 | public DBInfoNoDefaultConstructor(int port, String uri, String password, String passwordPrefix) { 10 | this.port = port; 11 | this.uri = uri; 12 | this.password = passwordPrefix + password; 13 | } 14 | 15 | public int getPort() { 16 | return port; 17 | } 18 | 19 | public void setPort(int port) { 20 | this.port = port; 21 | } 22 | 23 | public String getUri() { 24 | return uri; 25 | } 26 | 27 | public void setUri(String uri) { 28 | this.uri = uri; 29 | } 30 | 31 | public String getPassword() { 32 | return password; 33 | } 34 | 35 | public void setPassword(String password) { 36 | this.password = password; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gestalt-cdi/src/main/java/org/github/gestalt/config/cdi/GestaltConfigException.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.cdi; 2 | 3 | public final class GestaltConfigException extends RuntimeException { 4 | private final String configPropertyName; 5 | 6 | public GestaltConfigException(String message) { 7 | super(message); 8 | this.configPropertyName = null; 9 | } 10 | 11 | public GestaltConfigException(String message, String configPropertyName) { 12 | super(message); 13 | this.configPropertyName = configPropertyName; 14 | } 15 | 16 | public GestaltConfigException(String message, Throwable cause) { 17 | super(message, cause); 18 | this.configPropertyName = null; 19 | } 20 | 21 | public GestaltConfigException(String message, String configPropertyName, Throwable cause) { 22 | super(message, cause); 23 | this.configPropertyName = configPropertyName; 24 | } 25 | 26 | public String getConfigPropertyName() { 27 | return configPropertyName; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /gestalt-cdi/src/main/java/org/github/gestalt/config/cdi/InjectConfigs.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.cdi; 2 | 3 | import jakarta.enterprise.util.AnnotationLiteral; 4 | import jakarta.enterprise.util.Nonbinding; 5 | import jakarta.inject.Qualifier; 6 | 7 | import java.lang.annotation.*; 8 | 9 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE}) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Documented 12 | @Qualifier 13 | public @interface InjectConfigs { 14 | @Nonbinding 15 | String prefix() default ""; 16 | 17 | final class Literal extends AnnotationLiteral implements InjectConfigs { 18 | 19 | private final String prefix; 20 | 21 | private Literal(String prefix) { 22 | this.prefix = prefix; 23 | } 24 | 25 | public static Literal of(String prefix) { //NOPMD 26 | return new Literal(prefix); 27 | } 28 | 29 | @Override 30 | public String prefix() { 31 | return this.prefix; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/defaultPPEnv.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${envVar:DB_IDLETIMEOUT:=900} 9 | db.maxLifetime=${envVar:NO_RESULTS_FOUND:=60000.0} 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${env:SUBSERVICE_BOOKING_ISENABLED} 16 | subservice.booking.service.host=${env:SUBSERVICE_BOOKING_SERVICE_HOST} 17 | subservice.booking.service.port=${env:SUBSERVICE_BOOKING_SERVICE_PORT} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/transform/URLEncoderTransformer.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config.transform; 2 | 3 | import org.github.gestalt.config.entity.ValidationError; 4 | import org.github.gestalt.config.utils.GResultOf; 5 | 6 | import java.net.URLEncoder; 7 | import java.nio.charset.Charset; 8 | 9 | /** 10 | * Allows you to URL encode a string. 11 | * 12 | * @author Colin Redmond (c) 2025. 13 | */ 14 | public final class URLEncoderTransformer implements Transformer { 15 | @Override 16 | public String name() { 17 | return "urlEncode"; 18 | } 19 | 20 | @Override 21 | public GResultOf process(String path, String key, String rawValue) { 22 | if (key != null) { 23 | return GResultOf.result(URLEncoder.encode(key, Charset.defaultCharset())); 24 | } else { 25 | return GResultOf.errors(new ValidationError.InvalidStringSubstitutionPostProcess(path, rawValue, name())); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoBooleanEnabledNonNullGetter.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoBooleanEnabledNonNullGetter { 4 | private Integer port; 5 | private String uri; 6 | private String password; 7 | 8 | private Boolean enabled; 9 | 10 | public Integer getPort() { 11 | return port != null ? port : 1234; 12 | } 13 | 14 | public void setPort(int port) { 15 | this.port = port; 16 | } 17 | 18 | public String getUri() { 19 | return uri; 20 | } 21 | 22 | public void setUri(String uri) { 23 | this.uri = uri; 24 | } 25 | 26 | public String getPassword() { 27 | return password; 28 | } 29 | 30 | public void setPassword(String password) { 31 | this.password = password; 32 | } 33 | 34 | public Boolean isEnabled() { 35 | return enabled == null || enabled; 36 | } 37 | 38 | public void setEnabled(Boolean enabled) { 39 | this.enabled = enabled; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/utils/ErrorsUtilTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.utils; 2 | 3 | import org.github.gestalt.config.entity.ValidationError; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | 11 | class ErrorsUtilTest { 12 | 13 | @Test 14 | void testBuildErrorMessage() { 15 | String error = ErrorsUtil.buildErrorMessage("my errors: ", List.of(new ValidationError.ArrayInvalidIndex(1, "db.hosts"))); 16 | 17 | Assertions.assertEquals("my errors: \n" + 18 | " - level: ERROR, message: Invalid array index: 1 for path: db.hosts", error); 19 | } 20 | 21 | @Test 22 | void testBuildErrorMessageAsList() { 23 | String error = ErrorsUtil.buildErrorMessage( 24 | Collections.singletonList(new ValidationError.ArrayInvalidIndex(1, "db.hosts"))); 25 | 26 | Assertions.assertEquals("level: ERROR, message: Invalid array index: 1 for path: db.hosts", error); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/defaultPPSys.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${DB_IDLETIMEOUT} 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${SUBSERVICE_BOOKING_ISENABLED} 16 | subservice.booking.service.host=${sys:SUBSERVICE_BOOKING_SERVICE_HOST} 17 | subservice.booking.service.port=${sys:SUBSERVICE_BOOKING_SERVICE_PORT} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | appUUID=${random:uuid} 26 | appId=${random:int(20, 21)} 27 | -------------------------------------------------------------------------------- /gestalt-cdi/src/test/java/org/github/gestalt/config/cdi/ConfigClassWithPrefixTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.cdi; 2 | 3 | 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | class ConfigClassWithPrefixTest { 8 | 9 | @Test 10 | public void tests() { 11 | ConfigClassWithPrefix prefix1 = new ConfigClassWithPrefix(String.class, "test"); 12 | ConfigClassWithPrefix prefix2 = ConfigClassWithPrefix.configClassWithPrefix(String.class, "test"); 13 | ConfigClassWithPrefix prefix3 = ConfigClassWithPrefix.configClassWithPrefix(String.class, "notTest"); 14 | ConfigClassWithPrefix prefix4 = ConfigClassWithPrefix.configClassWithPrefix(Integer.class, "test"); 15 | 16 | Assertions.assertEquals(prefix1, prefix1); 17 | Assertions.assertEquals(prefix1, prefix2); 18 | Assertions.assertNotEquals(prefix1, prefix3); 19 | Assertions.assertNotEquals(prefix1, prefix4); 20 | Assertions.assertNotEquals(prefix1, null); 21 | Assertions.assertNotEquals(prefix1, 1); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/defaultPPSys.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${DB_IDLETIMEOUT} 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${SUBSERVICE_BOOKING_ISENABLED} 16 | subservice.booking.service.host=${sys:SUBSERVICE_BOOKING_SERVICE_HOST} 17 | subservice.booking.service.port=${sys:SUBSERVICE_BOOKING_SERVICE_PORT} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | appUUID=${random:uuid} 26 | appId=${random:int(20, 21)} 27 | -------------------------------------------------------------------------------- /gestalt-koin-di/src/main/kotlin/org/github/gestalt/config/kotlin/koin/Koin.kt: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.kotlin.koin 2 | 3 | import org.github.gestalt.config.Gestalt 4 | import org.github.gestalt.config.kotlin.reflect.KTypeCapture 5 | import org.koin.core.parameter.ParametersDefinition 6 | import org.koin.core.qualifier.Qualifier 7 | import org.koin.core.scope.Scope 8 | import kotlin.reflect.typeOf 9 | 10 | /** 11 | * Extension function for koin to allow us to inject configuration using the method gestalt 12 | * 13 | * @author Colin Redmond (c) 2025. 14 | */ 15 | inline fun Scope.gestalt( 16 | path: String, 17 | default: T? = null, 18 | qualifier: Qualifier? = null, 19 | noinline parameters: ParametersDefinition? = null 20 | ): T { 21 | val gestalt = this.get(qualifier, parameters) 22 | return if (default != null) { 23 | gestalt.getConfig(path, default, KTypeCapture.of(typeOf())) as T 24 | } else { 25 | gestalt.getConfig(path, KTypeCapture.of(typeOf())) as T 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/result/DefaultResultProcessor.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.result; 2 | 3 | import org.github.gestalt.config.annotations.ConfigPriority; 4 | import org.github.gestalt.config.exceptions.GestaltException; 5 | import org.github.gestalt.config.reflect.TypeCapture; 6 | import org.github.gestalt.config.tag.Tags; 7 | import org.github.gestalt.config.utils.GResultOf; 8 | 9 | @ConfigPriority(600) 10 | public class DefaultResultProcessor implements ResultProcessor { 11 | 12 | @Override 13 | public GResultOf processResults(GResultOf results, String path, boolean isOptional, 14 | T defaultVal, TypeCapture klass, Tags tags) throws GestaltException { 15 | 16 | // If this is an optional config, and it doesn't have a result, return the optional value. 17 | if (isOptional && !results.hasResults()) { 18 | return GResultOf.result(defaultVal, true); 19 | } 20 | 21 | // otherwise return the original result. 22 | return results; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/security/encrypted/EncryptedSecretModuleTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.security.encrypted; 2 | 3 | import org.github.gestalt.config.secret.rules.RegexSecretChecker; 4 | import org.github.gestalt.config.secret.rules.SecretChecker; 5 | import org.junit.jupiter.api.BeforeEach; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import java.util.Set; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | 12 | class EncryptedSecretModuleTest { 13 | 14 | private SecretChecker secretChecker; 15 | private EncryptedSecretModule encryptedSecretModule; 16 | 17 | @BeforeEach 18 | void setUp() { 19 | secretChecker = new RegexSecretChecker(Set.of()); 20 | encryptedSecretModule = new EncryptedSecretModule(secretChecker); 21 | } 22 | 23 | @Test 24 | void testName() { 25 | assertEquals("TemporarySecretModule", encryptedSecretModule.name()); 26 | } 27 | 28 | @Test 29 | void testGetSecretChecker() { 30 | assertEquals(secretChecker, encryptedSecretModule.getSecretChecker()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gestalt-test/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | DB.hosts[0].user=credmond 2 | DB.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | DB.hosts[1].user=credmond 4 | DB.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | DB.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idle-timeout=600 9 | db.max_lifetime=60000.0 10 | 11 | http.pool.maxTotal=100 12 | http.pool.maxPerRoute=10 13 | http.pool.validateAfterInactivity=6000 14 | http.pool.keepAliveTimeoutMs=60000 15 | http.pool.idleTimeoutSec=25 16 | 17 | subservice.booking.service.isEnabled=false 18 | subservice.booking.service.host=http://localhost 19 | subservice.booking.service.port=8081 20 | subservice.booking.service.path=booking 21 | 22 | subservice.search.service.isEnabled=false 23 | subservice.search.service.host=http://localhost 24 | subservice.search.service.port=8082 25 | subservice.search.service.path=search 26 | 27 | ADMIN.user=John, Sarah 28 | ADMIN.overrideEnabled=false 29 | ADMIN.accessRole=level0 30 | 31 | employee.user=Janice 32 | employee.accessRole=level1 33 | 34 | serviceMode=active 35 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/lexer/PathLexerBuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.lexer; 2 | 3 | 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | class PathLexerBuilderTest { 8 | 9 | @Test 10 | public void testBuilder() { 11 | 12 | PathLexerBuilder builder = PathLexerBuilder.builder() 13 | .setDelimiter("*") 14 | .setNormalizedDelimiter("_") 15 | .setNormalizedArrayOpenTag("{") 16 | .setNormalizedArrayCloseTag("}") 17 | .setNormalizedMapTag(":") 18 | .setSentenceNormalizer(new LowerCaseSentenceNormalizer()) 19 | .setPathPatternRegex("ABC"); 20 | 21 | var lexer = builder.build(); 22 | Assertions.assertEquals("*", lexer.getDeliminator()); 23 | Assertions.assertEquals("_", lexer.getNormalizedDeliminator()); 24 | Assertions.assertEquals("{", lexer.getNormalizedArrayOpenTag()); 25 | Assertions.assertEquals("}", lexer.getNormalizedArrayCloseTag()); 26 | Assertions.assertEquals(":", lexer.getNormalizedMapTag()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | DB.hosts[0].user=credmond 2 | DB.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | DB.hosts[1].user=credmond 4 | DB.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | DB.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idle-timeout=600 9 | db.max_lifetime=60000.0 10 | 11 | http.pool.maxTotal=100 12 | http.pool.maxPerRoute=10 13 | http.pool.validateAfterInactivity=6000 14 | http.pool.keepAliveTimeoutMs=60000 15 | http.pool.idleTimeoutSec=25 16 | 17 | subservice.booking.service.isEnabled=false 18 | subservice.booking.service.host=http://localhost 19 | subservice.booking.service.port=8081 20 | subservice.booking.service.path=booking 21 | 22 | subservice.search.service.isEnabled=false 23 | subservice.search.service.host=http://localhost 24 | subservice.search.service.port=8082 25 | subservice.search.service.path=search 26 | 27 | ADMIN.user=John, Sarah 28 | ADMIN.overrideEnabled=false 29 | ADMIN.accessRole=level0 30 | 31 | employee.user=Janice 32 | employee.accessRole=level1 33 | 34 | serviceMode=active 35 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/processor/result/validation/TestConfigValidator.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.result.validation; 2 | 3 | import org.github.gestalt.config.entity.ValidationError; 4 | import org.github.gestalt.config.entity.ValidationLevel; 5 | import org.github.gestalt.config.reflect.TypeCapture; 6 | import org.github.gestalt.config.tag.Tags; 7 | import org.github.gestalt.config.utils.GResultOf; 8 | 9 | public class TestConfigValidator implements ConfigValidator { 10 | public boolean isOk = true; 11 | 12 | public TestConfigValidator(boolean isOk) { 13 | this.isOk = isOk; 14 | } 15 | 16 | @Override 17 | public GResultOf validator(T obj, String path, TypeCapture klass, Tags tags) { 18 | if (isOk) { 19 | return GResultOf.result(obj); 20 | } else { 21 | return GResultOf.errors(new ValidationError(ValidationLevel.ERROR) { 22 | @Override 23 | public String description() { 24 | return "something broke"; 25 | } 26 | }); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/default.properties: -------------------------------------------------------------------------------- 1 | DB.hosts[0].user=credmond 2 | DB.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | DB.hosts[1].user=credmond 4 | DB.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | DB.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idle-timeout=600 9 | db.max_lifetime=60000.0 10 | 11 | http.pool.maxTotal=100 12 | http.pool.maxPerRoute=10 13 | http.pool.validateAfterInactivity=6000 14 | http.pool.keepAliveTimeoutMs=60000 15 | http.pool.idleTimeoutSec=25 16 | 17 | subservice.booking.service.isEnabled=false 18 | subservice.booking.service.host=http://localhost 19 | subservice.booking.service.port=8081 20 | subservice.booking.service.path=booking 21 | 22 | subservice.search.service.isEnabled=false 23 | subservice.search.service.host=http://localhost 24 | subservice.search.service.port=8082 25 | subservice.search.service.path=search 26 | 27 | ADMIN.user=John, Sarah 28 | ADMIN.overrideEnabled=false 29 | ADMIN.accessRole=level0 30 | 31 | employee.user=Janice 32 | employee.accessRole=level1 33 | 34 | serviceMode=active 35 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/decoder/StringDecoder.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.decoder; 2 | 3 | import org.github.gestalt.config.node.ConfigNode; 4 | import org.github.gestalt.config.reflect.TypeCapture; 5 | import org.github.gestalt.config.tag.Tags; 6 | import org.github.gestalt.config.utils.GResultOf; 7 | 8 | /** 9 | * Decode a String. 10 | * 11 | * @author Colin Redmond (c) 2025. 12 | */ 13 | public final class StringDecoder extends LeafDecoder { 14 | 15 | @Override 16 | public Priority priority() { 17 | return Priority.MEDIUM; 18 | } 19 | 20 | @Override 21 | public String name() { 22 | return "String"; 23 | } 24 | 25 | @Override 26 | public boolean canDecode(String path, Tags tags, ConfigNode node, TypeCapture type) { 27 | return String.class.isAssignableFrom(type.getRawType()); 28 | } 29 | 30 | @Override 31 | protected GResultOf leafDecode(String path, ConfigNode node, DecoderContext decoderContext) { 32 | return GResultOf.result(node.getValue().orElse("")); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/transform/substitution/SubstitutionNode.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config.transform.substitution; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Nodes to build a substitution tree. 7 | * 8 | * @author Colin Redmond (c) 2025. 9 | */ 10 | public class SubstitutionNode { 11 | 12 | private SubstitutionNode() { 13 | } 14 | 15 | public static class TextNode extends SubstitutionNode { 16 | private final String text; 17 | 18 | public TextNode(String text) { 19 | this.text = text; 20 | } 21 | 22 | public String getText() { 23 | return text; 24 | } 25 | } 26 | 27 | public static class TransformNode extends SubstitutionNode { 28 | private final List subNodes; 29 | 30 | public TransformNode(List subNodes) { 31 | this.subNodes = subNodes; 32 | } 33 | 34 | public List getSubNodes() { 35 | return subNodes; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gestalt-benchmark/src/jmh/resources/default.properties: -------------------------------------------------------------------------------- 1 | DB.hosts[0].user=credmond 2 | DB.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | DB.hosts[1].user=credmond 4 | DB.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | DB.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=600 9 | db.maxLifetime=60000.0 10 | 11 | http.pool.maxTotal=100 12 | http.pool.maxPerRoute=10 13 | http.pool.validateAfterInactivity=6000 14 | http.pool.keepAliveTimeoutMs=60000 15 | http.pool.idleTimeoutSec=25 16 | 17 | subservice.booking.service.isEnabled=false 18 | subservice.booking.service.host=http://localhost 19 | subservice.booking.service.port=8081 20 | subservice.booking.service.path=booking 21 | 22 | subservice.search.service.isEnabled=false 23 | subservice.search.service.host=http://localhost 24 | subservice.search.service.port=8082 25 | subservice.search.service.path=search 26 | 27 | ADMIN.user=John, Sarah 28 | ADMIN.overrideEnabled=false 29 | ADMIN.accessRole=level0 30 | 31 | employee.user=Janice 32 | employee.accessRole=level1 33 | 34 | serviceMode=active 35 | 36 | cache.size = ${sys:cacheSize} 37 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/processor/config/transform/Base64EncoderTransformer.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.processor.config.transform; 2 | 3 | import org.github.gestalt.config.entity.ValidationError; 4 | import org.github.gestalt.config.utils.GResultOf; 5 | 6 | import java.nio.charset.Charset; 7 | import java.util.Base64; 8 | 9 | /** 10 | * Allows you to encode a string to base 64. 11 | * 12 | * @author Colin Redmond (c) 2025. 13 | */ 14 | public final class Base64EncoderTransformer implements Transformer { 15 | @Override 16 | public String name() { 17 | return "base64Encode"; 18 | } 19 | 20 | @Override 21 | public GResultOf process(String path, String key, String rawValue) { 22 | if (key != null) { 23 | String encodedBytes = Base64.getEncoder().encodeToString(key.getBytes(Charset.defaultCharset())); 24 | return GResultOf.result(encodedBytes); 25 | } else { 26 | return GResultOf.errors(new ValidationError.InvalidStringSubstitutionPostProcess(path, rawValue, name())); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/loader/MapLoaderModuleConfigBuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.loader; 2 | 3 | import org.github.gestalt.config.entity.GestaltConfig; 4 | import org.github.gestalt.config.lexer.PathLexer; 5 | import org.github.gestalt.config.parser.MapConfigParser; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | 10 | class MapLoaderModuleConfigBuilderTest { 11 | 12 | @Test 13 | public void createModuleConfig() { 14 | var configParser = new MapConfigParser(); 15 | var lexer = new PathLexer(); 16 | var builder = MapConfigLoaderModuleConfigBuilder.builder() 17 | .setConfigParser(configParser) 18 | .setLexer(lexer); 19 | 20 | var moduleConfig = builder.build(); 21 | 22 | GestaltConfig config = new GestaltConfig(); 23 | config.registerModuleConfig(moduleConfig); 24 | 25 | Assertions.assertEquals(configParser, moduleConfig.getConfigParse()); 26 | Assertions.assertEquals(lexer, moduleConfig.getLexer()); 27 | Assertions.assertEquals("mapLoader", moduleConfig.name()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gestalt-validator-hibernate/src/main/java/com/github/gestalt/config/validation/hibernate/config/HibernateModuleConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.gestalt.config.validation.hibernate.config; 2 | 3 | import jakarta.validation.Validator; 4 | import org.github.gestalt.config.entity.GestaltModuleConfig; 5 | 6 | 7 | /** 8 | * Module config for Hibernate. Provides a jakarta Validator to validate objects. 9 | * 10 | * @author Colin Redmond (c) 2025. 11 | */ 12 | public final class HibernateModuleConfig implements GestaltModuleConfig { 13 | 14 | private final Validator validator; 15 | 16 | /** 17 | * Create the HibernateModuleConfig. 18 | * 19 | * @param validator jakarta Validator 20 | */ 21 | public HibernateModuleConfig(Validator validator) { 22 | this.validator = validator; 23 | } 24 | 25 | @Override 26 | public String name() { 27 | return "hibernate-validator"; 28 | } 29 | 30 | /** 31 | * Get the jakarta Validator. 32 | * 33 | * @return jakarta Validator 34 | */ 35 | public Validator getValidator() { 36 | return validator; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/loader/PropertyLoaderModuleConfigBuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.loader; 2 | 3 | import org.github.gestalt.config.entity.GestaltConfig; 4 | import org.github.gestalt.config.lexer.PathLexer; 5 | import org.github.gestalt.config.parser.MapConfigParser; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | 10 | class PropertyLoaderModuleConfigBuilderTest { 11 | 12 | @Test 13 | public void createModuleConfig() { 14 | var configParser = new MapConfigParser(); 15 | var lexer = new PathLexer(); 16 | var builder = PropertyLoaderModuleConfigBuilder.builder() 17 | .setConfigParser(configParser) 18 | .setLexer(lexer); 19 | 20 | var moduleConfig = builder.build(); 21 | 22 | GestaltConfig config = new GestaltConfig(); 23 | config.registerModuleConfig(moduleConfig); 24 | 25 | Assertions.assertEquals(configParser, moduleConfig.getConfigParse()); 26 | Assertions.assertEquals(lexer, moduleConfig.getLexer()); 27 | Assertions.assertEquals("propertiesLoader", moduleConfig.name()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /docs/gestalt-static/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #2e8555; 10 | --ifm-color-primary-dark: #29784c; 11 | --ifm-color-primary-darker: #277148; 12 | --ifm-color-primary-darkest: #205d3b; 13 | --ifm-color-primary-light: #33925d; 14 | --ifm-color-primary-lighter: #359962; 15 | --ifm-color-primary-lightest: #3cad6e; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #25c2a0; 23 | --ifm-color-primary-dark: #21af90; 24 | --ifm-color-primary-darker: #1fa588; 25 | --ifm-color-primary-darkest: #1a8870; 26 | --ifm-color-primary-light: #29d5b0; 27 | --ifm-color-primary-lighter: #32d8b4; 28 | --ifm-color-primary-lightest: #4fddbf; 29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 30 | } 31 | -------------------------------------------------------------------------------- /gestalt-cdi/src/main/java/org/github/gestalt/config/cdi/GestaltConfigProvider.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.cdi; 2 | 3 | import org.github.gestalt.config.Gestalt; 4 | 5 | public final class GestaltConfigProvider { 6 | private static volatile Gestalt gestalt = null; 7 | 8 | private GestaltConfigProvider() { 9 | } 10 | 11 | public static void registerGestalt(Gestalt regGestalt) { 12 | if (gestalt == null) { // NOPMD 13 | synchronized (GestaltConfigProvider.class) { 14 | if (gestalt == null) { 15 | gestalt = regGestalt; 16 | return; 17 | } 18 | } 19 | } 20 | throw new GestaltConfigException("Gestalt has already been registered"); 21 | } 22 | 23 | public static Gestalt getGestaltConfig() { 24 | return gestalt; 25 | } 26 | 27 | public static void unRegisterGestalt() { 28 | if (gestalt != null) { // NOPMD 29 | synchronized (GestaltConfigProvider.class) { 30 | if (gestalt != null) { 31 | gestalt = null; 32 | } 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/test/classes/DBInfoConstructor.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.test.classes; 2 | 3 | public class DBInfoConstructor { 4 | private int port; 5 | private String uri; 6 | private String password; 7 | 8 | public DBInfoConstructor() { 9 | 10 | } 11 | 12 | public DBInfoConstructor(int port, String uri, String password) { 13 | this.port = port; 14 | this.uri = uri; 15 | this.password = password; 16 | } 17 | 18 | public DBInfoConstructor(int port, String uri) { 19 | this.port = port; 20 | this.uri = uri; 21 | this.password = "unknown"; 22 | } 23 | 24 | 25 | public int getPort() { 26 | return port; 27 | } 28 | 29 | public void setPort(int port) { 30 | this.port = port; 31 | } 32 | 33 | public String getUri() { 34 | return uri; 35 | } 36 | 37 | public void setUri(String uri) { 38 | this.uri = uri; 39 | } 40 | 41 | public String getPassword() { 42 | return password; 43 | } 44 | 45 | public void setPassword(String password) { 46 | this.password = password; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gradle/gradle-daemon-jvm.properties: -------------------------------------------------------------------------------- 1 | #This file is generated by updateDaemonJvm 2 | toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/fd88a209e0f18ca6eaf97d9fa9e45e01/redirect 3 | toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/1543f336911ae3d7d37bedec8b74d98c/redirect 4 | toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/fd88a209e0f18ca6eaf97d9fa9e45e01/redirect 5 | toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/1543f336911ae3d7d37bedec8b74d98c/redirect 6 | toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/7799fb2cb9f9eb382df2b8b6fb793b77/redirect 7 | toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/99a42fd36e2e41c7c8ed49f423f49fdf/redirect 8 | toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/fd88a209e0f18ca6eaf97d9fa9e45e01/redirect 9 | toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/1543f336911ae3d7d37bedec8b74d98c/redirect 10 | toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/3087f28f30be41ab6818c16a488f5f8a/redirect 11 | toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/638dfeab250dbbb0639b82816307982e/redirect 12 | toolchainVersion=21 13 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/exceptions/GestaltConfigurationException.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.exceptions; 2 | 3 | import org.github.gestalt.config.entity.ValidationError; 4 | import org.github.gestalt.config.utils.ErrorsUtil; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Configuration type exception for gestalt. 10 | * 11 | * @author Colin Redmond (c) 2025. 12 | */ 13 | public final class GestaltConfigurationException extends GestaltException { 14 | /** 15 | * Create a GestaltConfigurationException with a message and a list of ValidationError. 16 | * 17 | * @param message message for the error 18 | * @param errors list of ValidationErrors 19 | */ 20 | public GestaltConfigurationException(String message, List errors) { 21 | super(ErrorsUtil.buildErrorMessage(message, errors)); 22 | } 23 | 24 | /** 25 | * Create a GestaltConfigurationException with a message. 26 | * 27 | * @param message message for the error 28 | */ 29 | public GestaltConfigurationException(String message) { 30 | super(message); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-java-records/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gestalt.java-common-conventions") 3 | id("gestalt.java-test-conventions") 4 | id("gestalt.kotlin-common-conventions") 5 | id("gestalt.kotlin-test-conventions") 6 | } 7 | 8 | repositories { 9 | mavenLocal() 10 | mavenCentral() 11 | } 12 | 13 | java { 14 | toolchain { 15 | languageVersion.set(JavaLanguageVersion.of(libs.versions.javaLatest.get())) 16 | } 17 | } 18 | 19 | testing { 20 | suites { 21 | val test by getting(JvmTestSuite::class) { 22 | useJUnitJupiter() 23 | 24 | dependencies { 25 | implementation(project(":gestalt-core")) 26 | implementation(project(":gestalt-hocon")) 27 | implementation(project(":gestalt-kotlin")) 28 | implementation(project(":gestalt-json")) 29 | implementation(project(":gestalt-toml")) 30 | implementation(project(":gestalt-yaml")) 31 | } 32 | } 33 | } 34 | } 35 | 36 | tasks.jar { 37 | manifest { 38 | attributes("Automatic-Module-Name" to "org.github.gestalt.config.integration.latest") 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-java-records/src/test/resources/default.properties: -------------------------------------------------------------------------------- 1 | DB.hosts[0].user=credmond 2 | DB.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | DB.hosts[1].user=credmond 4 | DB.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | DB.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=600 9 | db.maxLifetime=60000.0 10 | db.isEnabled=false 11 | 12 | http.pool.maxTotal=100 13 | http.pool.maxPerRoute=10 14 | http.pool.validateAfterInactivity=6000 15 | http.pool.keepAliveTimeoutMs=60000 16 | http.pool.idleTimeoutSec=25 17 | http.pool.defaultWait=33.0 18 | 19 | subservice.booking.service.isEnabled=false 20 | subservice.booking.service.host=http://localhost 21 | subservice.booking.service.port=8081 22 | subservice.booking.service.path=booking 23 | 24 | subservice.search.service.isEnabled=false 25 | subservice.search.service.host=http://localhost 26 | subservice.search.service.port=8082 27 | subservice.search.service.path=search 28 | 29 | ADMIN.user=John, Sarah 30 | ADMIN.overrideEnabled=false 31 | ADMIN.accessRole=level0 32 | 33 | employee.user=Janice 34 | employee.accessRole=level1 35 | 36 | serviceMode=active 37 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/node/factory/ConfigNodeFactory.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.node.factory; 2 | 3 | import org.github.gestalt.config.node.ConfigNode; 4 | import org.github.gestalt.config.utils.GResultOf; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | /** 10 | * Factory to build Config Node from a set of parameters. 11 | * 12 | * @author Colin Redmond (c) 2025. 13 | */ 14 | public interface ConfigNodeFactory { 15 | 16 | default void applyConfig(ConfigNodeFactoryConfig config) { 17 | 18 | } 19 | 20 | /** 21 | * Returns true if it supports a specific config Node type. 22 | * 23 | * @param type type of the config Node 24 | * @return true if it supports a specific config type. 25 | */ 26 | Boolean supportsType(String type); 27 | 28 | /** 29 | * Takes in a map of parameters to then use a builder to generate a Config Node. 30 | * 31 | * @param parameters parameters used to define a config Node, such as file location, or url 32 | * @return Config Node 33 | */ 34 | GResultOf> build(Map parameters); 35 | } 36 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/loader/EnvironmentVarsLoaderModuleConfigBuilderTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.loader; 2 | 3 | import org.github.gestalt.config.entity.GestaltConfig; 4 | import org.github.gestalt.config.lexer.PathLexer; 5 | import org.github.gestalt.config.parser.MapConfigParser; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | 9 | 10 | class EnvironmentVarsLoaderModuleConfigBuilderTest { 11 | 12 | @Test 13 | public void createModuleConfig() { 14 | var configParser = new MapConfigParser(); 15 | var lexer = new PathLexer(); 16 | var builder = EnvironmentVarsLoaderModuleConfigBuilder.builder() 17 | .setConfigParser(configParser) 18 | .setLexer(lexer); 19 | 20 | var moduleConfig = builder.build(); 21 | 22 | GestaltConfig config = new GestaltConfig(); 23 | config.registerModuleConfig(moduleConfig); 24 | 25 | Assertions.assertEquals(configParser, moduleConfig.getConfigParse()); 26 | Assertions.assertEquals(lexer, moduleConfig.getLexer()); 27 | Assertions.assertEquals("environmentVarsLoader", moduleConfig.name()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /docs/gestalt-static/sidebars.ts: -------------------------------------------------------------------------------- 1 | import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; 2 | 3 | /** 4 | * Creating a sidebar enables you to: 5 | - create an ordered group of docs 6 | - render a sidebar for each doc of that group 7 | - provide next/previous navigation 8 | 9 | The sidebars can be generated from the filesystem, or explicitly defined here. 10 | 11 | Create as many sidebars as you want. 12 | */ 13 | const sidebars: SidebarsConfig = { 14 | // By default, Docusaurus generates a sidebar from the docs folder structure 15 | tutorialSidebar: [{type: 'autogenerated', dirName: 'tutorial'}], 16 | advancedSidebar: [{type: 'autogenerated', dirName: 'advanced'}], 17 | modulesSidebar: [{type: 'autogenerated', dirName: 'modules'}], 18 | usecaseSidebar: [{type: 'autogenerated', dirName: 'usecase'}], 19 | architectureSidebar: [{type: 'autogenerated', dirName: 'architecture'}], 20 | 21 | // But you can create a sidebar manually 22 | /* 23 | tutorialSidebar: [ 24 | 'intro', 25 | 'hello', 26 | { 27 | type: 'category', 28 | label: 'Tutorial', 29 | items: ['tutorial-basics/create-a-document'], 30 | }, 31 | ], 32 | */ 33 | }; 34 | 35 | export default sidebars; 36 | -------------------------------------------------------------------------------- /docs/gestalt-static/docs/architecture/config-loader.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Config Loader 6 | A ConfigLoader accepts a specific source format. It reads in the config source as either a list or input stream. It is then responsible for converting the sources into a GResultOf with either a config node tree or validation errors. 7 | You can write your own ConfigLoader by implementing the interface and accepting a specific format. Then read in the provided ConfigSource InputStream or list and parse the values. For example you can add a json loader that takes an InputStream and uses Jackson to load and build a config tree. 8 | ```java 9 | /** 10 | * True if the config loader accepts the format. 11 | * 12 | * @param format config format. 13 | * @return True if the config loader accepts the format. 14 | */ 15 | boolean accepts(String format); 16 | 17 | /** 18 | * Load a ConfigSource then build the validated config node. 19 | * 20 | * @param source source we want to load with this config loader. 21 | * @return the validated config node. 22 | * @throws GestaltException any exceptions 23 | */ 24 | GResultOf loadSource(ConfigSource source) throws GestaltException; 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /gestalt-core/src/main/java/org/github/gestalt/config/parser/ConfigParser.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.parser; 2 | 3 | import org.github.gestalt.config.entity.ConfigValue; 4 | import org.github.gestalt.config.lexer.SentenceLexer; 5 | import org.github.gestalt.config.node.ConfigNode; 6 | import org.github.gestalt.config.token.Token; 7 | import org.github.gestalt.config.utils.GResultOf; 8 | import org.github.gestalt.config.utils.Pair; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Takes in a tokenized config and returns a config node tree. 14 | * 15 | * @author Colin Redmond (c) 2025. 16 | */ 17 | public interface ConfigParser { 18 | 19 | /** 20 | * Takes in a tokenized config and returns a config node tree. 21 | * 22 | * @param lexer lexer used to get the delimiter to build the path 23 | * @param configs configs to parse 24 | * @param failOnErrors if we want to fail on errors while parsing or try and recover. Results can be unpredictable if it continues 25 | * @return the config node built 26 | */ 27 | GResultOf parse(SentenceLexer lexer, List, ConfigValue>> configs, boolean failOnErrors); 28 | } 29 | -------------------------------------------------------------------------------- /gestalt-core/src/test/java/org/github/gestalt/config/entity/GestaltConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.github.gestalt.config.entity; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class GestaltConfigTest { 7 | 8 | @Test 9 | void getExtension() { 10 | GestaltConfig config = new GestaltConfig(); 11 | MyModule extension = new MyModule(); 12 | 13 | config.registerModuleConfig(extension); 14 | 15 | MyModule test = config.getModuleConfig(MyModule.class); 16 | 17 | Assertions.assertEquals("test", test.name()); 18 | Assertions.assertEquals("myConfig", test.myConfig()); 19 | } 20 | 21 | private static final class MyModule implements GestaltModuleConfig { 22 | 23 | @Override 24 | public String name() { 25 | return "test"; 26 | } 27 | 28 | public String myConfig() { 29 | return "myConfig"; 30 | } 31 | } 32 | 33 | @SuppressWarnings("removal") 34 | @Test 35 | void codeCoverage() { 36 | GestaltConfig config = new GestaltConfig(); 37 | config.setTreatNullValuesInClassAsErrors(true); 38 | config.isTreatNullValuesInClassAsErrors(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample/src/test/resources/defaultPPVault.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${vault:secret/path:timeout} 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${vault:secret/path:bookingIsEnabled} 16 | subservice.booking.service.host=${vault:secret/path:bookingHost} 17 | subservice.booking.service.port=${vault:secret/path:bookingPort} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | 26 | alternate.db.idleTimeout=123 27 | alternate.subservice.booking.isEnabled=true 28 | alternate.subservice.booking.service.host=https://dev.booking.host.name 29 | alternate.subservice.booking.service.port=443 30 | -------------------------------------------------------------------------------- /gestalt-examples/gestalt-sample-module/src/main/resources/defaultPPVault.properties: -------------------------------------------------------------------------------- 1 | db.hosts[0].user=credmond 2 | db.hosts[0].url=jdbc:postgresql://localhost:5432/mydb1 3 | db.hosts[1].user=credmond 4 | db.hosts[1].url=jdbc:postgresql://localhost:5432/mydb2 5 | db.hosts[2].user=credmond 6 | db.hosts[2].url=jdbc:postgresql://localhost:5432/mydb3 7 | db.ConnectionTimeout=6000 8 | db.idleTimeout=${vault:secret/path:timeout} 9 | db.maxLifetime=60000.0 10 | http.Pool.maxTotal=100 11 | http.Pool.maxPerRoute=10 12 | http.Pool.validateAfterInactivity=6000 13 | http.Pool.keepAliveTimeoutMs=60000 14 | http.Pool.idleTimeoutSec=25 15 | subservice.booking.isEnabled=${vault:secret/path:bookingIsEnabled} 16 | subservice.booking.service.host=${vault:secret/path:bookingHost} 17 | subservice.booking.service.port=${vault:secret/path:bookingPort} 18 | subservice.booking.service.path=booking 19 | Admin.user=John, Sarah 20 | Admin.overrideEnabled=false 21 | Admin.accessRole=level0 22 | employee.user=Janice 23 | employee.accessRole=level1 24 | serviceMode=active 25 | 26 | alternate.db.idleTimeout=123 27 | alternate.subservice.booking.isEnabled=true 28 | alternate.subservice.booking.service.host=https://dev.booking.host.name 29 | alternate.subservice.booking.service.port=443 30 | -------------------------------------------------------------------------------- /gestalt-kotlin/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Module info definition for gestalt kotlin integration 3 | */ 4 | module org.github.gestalt.config.kotlin { 5 | requires org.github.gestalt.core; 6 | requires transitive kotlin.reflect; 7 | requires java.base; 8 | 9 | exports org.github.gestalt.config.kotlin; 10 | exports org.github.gestalt.config.kotlin.decoder; 11 | exports org.github.gestalt.config.kotlin.entity; 12 | exports org.github.gestalt.config.kotlin.reflect; 13 | 14 | provides org.github.gestalt.config.decoder.Decoder with 15 | org.github.gestalt.config.kotlin.decoder.BooleanDecoder, 16 | org.github.gestalt.config.kotlin.decoder.ByteDecoder, 17 | org.github.gestalt.config.kotlin.decoder.CharDecoder, 18 | org.github.gestalt.config.kotlin.decoder.DataClassDecoder, 19 | org.github.gestalt.config.kotlin.decoder.DoubleDecoder, 20 | org.github.gestalt.config.kotlin.decoder.FloatDecoder, 21 | org.github.gestalt.config.kotlin.decoder.IntegerDecoder, 22 | org.github.gestalt.config.kotlin.decoder.LongDecoder, 23 | org.github.gestalt.config.kotlin.decoder.ShortDecoder, 24 | org.github.gestalt.config.kotlin.decoder.StringDecoder; 25 | } 26 | -------------------------------------------------------------------------------- /gestalt-aws/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | // Module info definition for gestalt aws integration 2 | @SuppressWarnings({ "requires-automatic", "requires-transitive-automatic" }) 3 | module org.github.gestalt.aws { 4 | requires org.github.gestalt.core; 5 | requires transitive software.amazon.awssdk.services.s3; 6 | requires transitive software.amazon.awssdk.core; 7 | requires transitive software.amazon.awssdk.auth; 8 | requires transitive software.amazon.awssdk.regions; 9 | requires transitive software.amazon.awssdk.services.secretsmanager; 10 | requires transitive software.amazon.awssdk.http.urlconnection; 11 | requires transitive com.fasterxml.jackson.databind; 12 | 13 | exports org.github.gestalt.config.aws.config; 14 | exports org.github.gestalt.config.aws.errors; 15 | exports org.github.gestalt.config.aws.s3; 16 | exports org.github.gestalt.config.aws.transformer; 17 | 18 | provides org.github.gestalt.config.processor.config.transform.Transformer with 19 | org.github.gestalt.config.aws.transformer.AWSSecretTransformer; 20 | 21 | provides org.github.gestalt.config.node.factory.ConfigNodeFactory with 22 | org.github.gestalt.config.aws.node.factory.S3ConfigNodeFactory; 23 | } 24 | 25 | --------------------------------------------------------------------------------