Skip to content

Commit

Permalink
Add ability to choose property catalog for EachProperty annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
altro3 committed Oct 3, 2024
1 parent eccab50 commit bd38616
Show file tree
Hide file tree
Showing 12 changed files with 334 additions and 3 deletions.
40 changes: 40 additions & 0 deletions core/src/main/java/io/micronaut/core/value/PropertyCatalog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2017-2024 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.core.value;

/**
* The property catalog to use.
*
* @since 4.7.0
*/
public enum PropertyCatalog {
/**
* The catalog that contains the raw keys.
*/
RAW,
/**
* The catalog that contains normalized keys. A key is normalized into
* lower case hyphen separated form. For example an environment variable {@code FOO_BAR} would be
* normalized to {@code foo.bar}.
*/
NORMALIZED,
/**
* The catalog that contains normalized keys and also generated keys. A synthetic key can be generated from
* an environment variable such as {@code FOO_BAR_BAZ} which will produce the following keys: {@code foo.bar.baz},
* {@code foo.bar-baz}, and {@code foo-bar.baz}.
*/
GENERATED
}
23 changes: 23 additions & 0 deletions core/src/main/java/io/micronaut/core/value/PropertyResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,29 @@ public interface PropertyResolver extends ValueResolver<String> {
return Collections.emptySet();
}

/**
* Returns a collection of properties entries under the given key, but .
* For example, if you set {@code PropertyCatalog.RAW} then the following keys:
*
* <pre>
* <code>datasource.MyDs-1.url=localhost
* datasource.MyDs-2.url=someother</code>
* </pre>
*
* Calling {@code getPropertyEntries(String)} with a value of {@code datasource} will result in a collection
* containing {@code MyDs-1} and {@code MyDs-2} (without normalization).
*
* @param name The name to resolve
* @param propertyCatalog property catalog to use
* @return The property entries.
*
* @since 4.7.0
*/
@NonNull
default Collection<String> getPropertyEntries(@NonNull String name, @NonNull PropertyCatalog propertyCatalog) {
return Collections.emptySet();
}

/**
* <p>Resolve the given property for the given name, type and generic type arguments.</p>
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package io.micronaut.inject.configproperties.eachbeanparameter
import io.micronaut.annotation.processing.test.AbstractTypeElementSpec
import io.micronaut.context.ApplicationContext
import io.micronaut.context.Qualifier
import io.micronaut.context.env.PropertySource
import io.micronaut.context.env.SystemPropertiesPropertySource
import io.micronaut.context.exceptions.NonUniqueBeanException
import io.micronaut.inject.qualifiers.PrimaryQualifier
import io.micronaut.inject.qualifiers.Qualifiers
Expand Down Expand Up @@ -59,4 +61,47 @@ class EachBeanParameterSpec extends AbstractTypeElementSpec {
cleanup:
ctx.close()
}

void 'test disabled normalization property keys'() {
when:
Map<String, Object> datasourcesConfiguration = [
'app.raw.Raw_1.url': 'url1',
'app.raw.Raw_2.url': 'url2',
'app.normalized.Normalized_1.url': 'url1',
'app.normalized.Normalized_2.url': 'url2',
'app.default.Default_1.url': 'url1',
'app.default.Default_2.url': 'url2',
'app.generated.Generated_1.url': 'url1',
'app.generated.Generated_2.url': 'url2',
]
ApplicationContext ctx = ApplicationContext.builder()
.propertySources(PropertySource.of(PropertySource.CONTEXT, ['spec': 'DisabledNormalizationSpec'] + datasourcesConfiguration, SystemPropertiesPropertySource.POSITION + 100))
.start()

then:
ctx

def eachPropertyPropertiesRawBeans = ctx.getBeansOfType(EachPropertyPropertiesRaw)
eachPropertyPropertiesRawBeans.size() == 2
ctx.getBean(EachPropertyPropertiesRaw, Qualifiers.byName("Raw_1")).name == "Raw_1"
ctx.getBean(EachPropertyPropertiesRaw, Qualifiers.byName("Raw_2")).name == "Raw_2"

def eachPropertyPropertiesNormalizedBeans = ctx.getBeansOfType(EachPropertyPropertiesNormalized)
eachPropertyPropertiesNormalizedBeans.size() == 2
ctx.getBean(EachPropertyPropertiesNormalized, Qualifiers.byName("normalized-1")).name == "normalized-1"
ctx.getBean(EachPropertyPropertiesNormalized, Qualifiers.byName("normalized-2")).name == "normalized-2"

def eachPropertyPropertiesDefaultBeans = ctx.getBeansOfType(EachPropertyPropertiesDefault)
eachPropertyPropertiesDefaultBeans.size() == 2
ctx.getBean(EachPropertyPropertiesDefault, Qualifiers.byName("default-1")).name == "default-1"
ctx.getBean(EachPropertyPropertiesDefault, Qualifiers.byName("default-2")).name == "default-2"

def eachPropertyPropertiesGeneratedBeans = ctx.getBeansOfType(EachPropertyPropertiesGenerated)
eachPropertyPropertiesGeneratedBeans.size() == 2
ctx.getBean(EachPropertyPropertiesGenerated, Qualifiers.byName("generated-1")).name == "generated-1"
ctx.getBean(EachPropertyPropertiesGenerated, Qualifiers.byName("generated-2")).name == "generated-2"

cleanup:
ctx.close()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.micronaut.inject.configproperties.eachbeanparameter;

import io.micronaut.context.annotation.ConfigurationInject;
import io.micronaut.context.annotation.EachProperty;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Requires;

@Requires(property = "spec", value = "DisabledNormalizationSpec")
@EachProperty(value = "app.default")
public class EachPropertyPropertiesDefault {

private String name;
private String url;
private int serverPort;

@ConfigurationInject
public EachPropertyPropertiesDefault(@Parameter String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getServerPort() {
return serverPort;
}

public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.micronaut.inject.configproperties.eachbeanparameter;

import io.micronaut.context.annotation.ConfigurationInject;
import io.micronaut.context.annotation.EachProperty;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.value.PropertyCatalog;

@Requires(property = "spec", value = "DisabledNormalizationSpec")
@EachProperty(value = "app.generated", catalog = PropertyCatalog.GENERATED)
public class EachPropertyPropertiesGenerated {

private String name;
private String url;
private int serverPort;

@ConfigurationInject
public EachPropertyPropertiesGenerated(@Parameter String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getServerPort() {
return serverPort;
}

public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.micronaut.inject.configproperties.eachbeanparameter;

import io.micronaut.context.annotation.ConfigurationInject;
import io.micronaut.context.annotation.EachProperty;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.value.PropertyCatalog;

@Requires(property = "spec", value = "DisabledNormalizationSpec")
@EachProperty(value = "app.normalized", catalog = PropertyCatalog.NORMALIZED)
public class EachPropertyPropertiesNormalized {

private String name;
private String url;
private int serverPort;

@ConfigurationInject
public EachPropertyPropertiesNormalized(@Parameter String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getServerPort() {
return serverPort;
}

public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.micronaut.inject.configproperties.eachbeanparameter;

import io.micronaut.context.annotation.ConfigurationInject;
import io.micronaut.context.annotation.EachProperty;
import io.micronaut.context.annotation.Parameter;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.value.PropertyCatalog;

@Requires(property = "spec", value = "DisabledNormalizationSpec")
@EachProperty(value = "app.raw", catalog = PropertyCatalog.RAW)
public class EachPropertyPropertiesRaw {

private String name;
private String url;
private int serverPort;

@ConfigurationInject
public EachPropertyPropertiesRaw(@Parameter String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getServerPort() {
return serverPort;
}

public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import io.micronaut.core.type.Argument;
import io.micronaut.core.util.ArgumentUtils;
import io.micronaut.core.util.StringUtils;
import io.micronaut.core.value.PropertyCatalog;
import io.micronaut.inject.BeanConfiguration;
import io.micronaut.inject.BeanDefinition;
import io.micronaut.inject.BeanDefinitionReference;
Expand Down Expand Up @@ -253,6 +254,12 @@ public Collection<String> getPropertyEntries(@NonNull String name) {
return getEnvironment().getPropertyEntries(name);
}

@NonNull
@Override
public Collection<String> getPropertyEntries(@NonNull String name, @NonNull PropertyCatalog propertyCatalog) {
return getEnvironment().getPropertyEntries(name, propertyCatalog);
}

@NonNull
@Override
public Map<String, Object> getProperties(@Nullable String name, @Nullable StringConvention keyFormat) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.micronaut.context.annotation;

import io.micronaut.core.value.PropertyCatalog;
import jakarta.inject.Singleton;

import java.lang.annotation.Documented;
Expand Down Expand Up @@ -92,6 +93,13 @@
@AliasFor(annotation = ConfigurationReader.class, member = ConfigurationReader.PREFIX)
String value();

/**
* @return property catalog to use. By default, uses NORMALIZATION catalog
*
* @since 4.7.0
*/
PropertyCatalog catalog() default PropertyCatalog.NORMALIZED;

/**
* @return The name of the key returned by {@link #value()} that should be regarded as the {@link Primary} bean
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.micronaut.context.annotation.EachProperty;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.value.PropertyCatalog;
import io.micronaut.core.value.PropertyResolver;
import io.micronaut.inject.BeanDefinition;
import io.micronaut.inject.qualifiers.Qualifiers;
Expand Down Expand Up @@ -120,6 +121,16 @@ static ConfigurationPath of(BeanDefinition<?>... definitions) {
*/
int index();

/**
* @return the current property catalog
*
* @since 4.7.0
*/
@NonNull
default PropertyCatalog propertyCatalog() {
return PropertyCatalog.NORMALIZED;
}

/**
* @return The qualifier.
* @param <T> The bean type
Expand Down
Loading

0 comments on commit bd38616

Please sign in to comment.