Skip to content

Commit

Permalink
Fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
onukristo committed Mar 27, 2024
1 parent 20aa618 commit e6ad48d
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 27 deletions.
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,37 @@ Allows to set default properties for specific environments.
Typical use case is for various Wise libraries to set environment specific default properties in their `EnvironmentPostProcessor` implementations.

```java
WiseEnvironment.setDefaultProperty(WiseEnvironment.PRODUCTION, "tw-reliable-jdbc.sslMode", SslMode.VERIFY_FULL);
WiseEnvironment.setDefaultProperty(WiseEnvironment.STAGING, "tw-reliable-jdbc.sslMode", SslMode.PREFERRED);
WiseEnvironment.setDefaultProperty(WiseEnvironment.CUSTOM_ENVIRONMENT, "tw-reliable-jdbc.sslMode", SslMode.VERIFY_CA);
WiseEnvironment.setDefaultProperty("my-library", WiseEnvironment.PRODUCTION, "tw-reliable-jdbc.sslMode", SslMode.VERIFY_FULL);
WiseEnvironment.setDefaultProperty("my-library", WiseEnvironment.STAGING, "tw-reliable-jdbc.sslMode", SslMode.PREFERRED);
WiseEnvironment.setDefaultProperty("my-library", WiseEnvironment.CUSTOM_ENVIRONMENT, "tw-reliable-jdbc.sslMode", SslMode.VERIFY_CA);
```

See `WiseEnvironment` class for other optional use cases. E.g. asking which environments are currently active.

The environments themselves can be hierarchical. In that sense, that if you set a default property to `STAGING`, it would also apply to
`CUSTOM_ENVIRONMENT`, unless a different value is specifically set for `CUSTOM_ENVIRONMENT`.

Also, a convenience DSL is available for setting properties. E.g.

```java
WiseEnvironment.setDefaultProperties(dsl -> dsl
.source("tw-reliable-jdbc")

.environment(WiseEnvironment.WISE)
.set(TW_OBS_BASE_EXTREMUM_CONFIG_PATH, gaugeNames)
.set("spring.flyway.validate-migration-naming", "true")

.keyPrefix("tw-reliable-jdbc.")
.environment(WiseEnvironment.PRODUCTION)
.set("sslMode", SslMode.VERIFY_FULL)
.set("requiredSslModeLevel", SslMode.VERIFY_CA)
.set("requireMinPoolSizePct", 100d)

.environment(WiseEnvironment.STAGING)
.set("sslMode", SslMode.VERIFY_FULL)
);
```

## License
Copyright 2024 TransferWise Ltd.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.wise.common.environment.impl;
package com.wise.common.environment;

import com.wise.common.environment.WiseEnvironment;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.wise.common.environment;

public class DefaultPropertiesSetterDsl implements PropertiesSetterDsl {

private String source;
private WiseEnvironment wiseEnvironment;

private String keyPrefix;

private Dsl0 dsl0 = new Dsl0Impl();
private Dsl1 dsl1 = new Dsl1Impl();
private Dsl2 dsl2 = new Dsl2Impl();

@Override
public Dsl0 source(String source) {
this.source = source;
return dsl0;
}

class Dsl0Impl implements Dsl0 {

@Override
public Dsl2 environment(WiseEnvironment wiseEnvironment) {
DefaultPropertiesSetterDsl.this.wiseEnvironment = wiseEnvironment;
return dsl2;
}

@Override
public Dsl1 keyPrefix(String keyPrefix) {
DefaultPropertiesSetterDsl.this.keyPrefix = keyPrefix;
return dsl1;
}
}

class Dsl1Impl implements Dsl1 {

@Override
public Dsl2 environment(WiseEnvironment wiseEnvironment) {
DefaultPropertiesSetterDsl.this.wiseEnvironment = wiseEnvironment;
return dsl2;
}
}

class Dsl2Impl implements Dsl2 {

@Override
public Dsl2 environment(WiseEnvironment wiseEnvironment) {
DefaultPropertiesSetterDsl.this.wiseEnvironment = wiseEnvironment;
return this;
}

@Override
public Dsl2 keyPrefix(String keyPrefix) {
DefaultPropertiesSetterDsl.this.keyPrefix = keyPrefix;
return this;
}

@Override
public Dsl2 set(String name, Object value) {
WiseEnvironment.setDefaultProperty(source, wiseEnvironment, keyPrefix == null ? name : keyPrefix + name, value);
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.wise.common.environment.impl;
package com.wise.common.environment;

import com.wise.common.environment.WiseEnvironment;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.wise.common.environment;

public interface PropertiesSetterDsl {

Dsl0 source(String source);

interface Dsl0 {

Dsl2 environment(WiseEnvironment environment);

Dsl1 keyPrefix(String prefix);
}

interface Dsl1 {

Dsl2 environment(WiseEnvironment wiseEnvironment);

}

interface Dsl2 {

Dsl2 environment(WiseEnvironment environment);

Dsl2 keyPrefix(String keyPrefix);

Dsl2 set(String property, Object value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.wise.common.environment;

import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.boot.origin.Origin;
import org.springframework.util.Assert;

@Data
@Accessors(chain = true)
public class PropertyContainer {

private Object value;

private WiseEnvironmentOrigin origin;

public PropertyContainer(String source, WiseEnvironment environment, Object value) {
Assert.notNull(value, "Value must not be null");
this.origin = new WiseEnvironmentOrigin(source, environment);
this.value = value;
}

@Data
public static class WiseEnvironmentOrigin implements Origin {

private String source;

private WiseEnvironment environment;

public WiseEnvironmentOrigin(String source, WiseEnvironment environment) {
Assert.notNull(source, "Source must not be null");
Assert.notNull(environment, "Environment must not be null");
this.source = source;
this.environment = environment;
}

public String toString() {
return "Wise environment: '" + environment + "', source: '" + source + "'";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.wise.common.environment;

import com.wise.common.environment.impl.CachingWiseEnvironmentProvider;
import com.wise.common.environment.impl.WiseEnvironmentProvider;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
Expand Down Expand Up @@ -51,7 +50,7 @@ public static WiseEnvironment getByName(String name) {
return StringUtils.isAllLowerCase(name) ? NAME_INDEX.get(name) : NAME_INDEX.get(name.toLowerCase());
}

private static final Map<WiseEnvironment, Map<String, Object>> defaultProperties = new ConcurrentHashMap<>();
private static final Map<WiseEnvironment, Map<String, PropertyContainer>> defaultProperties = new ConcurrentHashMap<>();

private static final Map<List<WiseEnvironment>, String[]> defaultPropertyNamesCache = new ConcurrentHashMap<>();

Expand All @@ -61,14 +60,14 @@ public static void init(List<WiseEnvironment> activeEnvironments) {
wiseEnvironmentProvider = new CachingWiseEnvironmentProvider(activeEnvironments);
}

public static void setDefaultProperty(String key, Object value) {
setDefaultProperty(WiseEnvironment.WISE, key, value);
public static void setDefaultProperty(String source, String name, Object value) {
setDefaultProperty(source, WiseEnvironment.WISE, name, value);
}

public static void setDefaultProperty(WiseEnvironment wiseEnvironment, String key, Object value) {
public static void setDefaultProperty(String source, WiseEnvironment wiseEnvironment, String name, Object value) {
defaultProperties
.computeIfAbsent(wiseEnvironment, k -> new ConcurrentHashMap<>())
.put(key, value);
.put(name, new PropertyContainer(source, wiseEnvironment, value));

defaultPropertyNamesCache.clear();
}
Expand All @@ -81,7 +80,7 @@ public static boolean isEnvironmentActive(WiseEnvironment environment) {
return wiseEnvironmentProvider.isEnvironmentActive(environment);
}

public static Object getDefaultProperty(String name) {
static PropertyContainer getDefaultPropertyContainer(String name) {
var activeEnvironments = getActiveEnvironments();

if (activeEnvironments != null) {
Expand All @@ -103,6 +102,11 @@ public static Object getDefaultProperty(String name) {
return null;
}

public static Object getDefaultProperty(String name) {
var container = getDefaultPropertyContainer(name);
return container == null ? null : container.getValue();
}

public static String[] getDefaultPropertyNames() {
var activeEnvironments = getActiveEnvironments();

Expand All @@ -126,4 +130,8 @@ public static String[] getDefaultPropertyNames() {
return result.toArray(new String[0]);
});
}

public static void setDefaultProperties(Consumer<PropertiesSetterDsl> dslConsumer) {
dslConsumer.accept(new DefaultPropertiesSetterDsl());
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package com.wise.common.environment.impl;
package com.wise.common.environment;

import com.wise.common.environment.WiseEnvironment;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.OriginLookup;
import org.springframework.core.env.EnumerablePropertySource;

public class WiseEnvironmentDefaultsPropertySource extends EnumerablePropertySource<String> {
public class WiseEnvironmentDefaultsPropertySource extends EnumerablePropertySource<String> implements OriginLookup<String> {

public WiseEnvironmentDefaultsPropertySource() {
super("WiseEnvironmentAwareDefaultsPropertySource", "WiseEnvironmentAwareDefaultsPropertySource");
Expand All @@ -18,4 +19,10 @@ public Object getProperty(String name) {
public String[] getPropertyNames() {
return WiseEnvironment.getDefaultPropertyNames();
}

@Override
public Origin getOrigin(String name) {
var container = WiseEnvironment.getDefaultPropertyContainer(this.name);
return container == null ? null : container.getOrigin();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wise.common.environment.impl;
package com.wise.common.environment;

import com.wise.common.environment.WiseEnvironment;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.wise.common.environment.impl;
package com.wise.common.environment;

import com.wise.common.environment.WiseEnvironment;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.ConfigurableEnvironment;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.wise.common.environment.impl;
package com.wise.common.environment;

import com.wise.common.environment.WiseEnvironment;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
org.springframework.boot.env.EnvironmentPostProcessor=com.wise.common.environment.impl.WiseEnvironmentEnvironmentPostProcessor
org.springframework.boot.env.EnvironmentPostProcessor=com.wise.common.environment.WiseEnvironmentEnvironmentPostProcessor
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,29 @@ void applicationIsConfigured() {

@Test
void defaultsCanBeSet() {
WiseEnvironment.setDefaultProperty("mykey", "robot");
WiseEnvironment.setDefaultProperty("mySource", "mykey", "robot");

WiseEnvironment.setDefaultProperty(WiseEnvironment.TEST, "mykey", "cat");
WiseEnvironment.setDefaultProperty("mySource", WiseEnvironment.TEST, "mykey", "cat");
assertThat(environment.getProperty("mykey"), equalTo("cat"));
assertThat(WiseEnvironment.getDefaultPropertyContainer("mykey").getOrigin().getEnvironment(), equalTo(WiseEnvironment.TEST));

WiseEnvironment.setDefaultProperty(WiseEnvironment.INTEGRATION_TEST, "mykey", "dog");
WiseEnvironment.setDefaultProperty("mySource", WiseEnvironment.INTEGRATION_TEST, "mykey", "dog");
assertThat(environment.getProperty("mykey"), equalTo("dog"));

assertThat(WiseEnvironment.getDefaultPropertyContainer("mykey").getOrigin().getEnvironment(), equalTo(WiseEnvironment.INTEGRATION_TEST));

WiseEnvironment.setDefaultProperties(dsl -> dsl
.source("mySource")
.environment(WiseEnvironment.UNIT_TEST)
.keyPrefix("prefix.")
.set("myotherkey", "horse")
.environment(WiseEnvironment.TEST)
.set("myotherkey", "mouse")
.keyPrefix(null)
.set("onemorekey", "moose")
);
assertThat(environment.getProperty("prefix.myotherkey"), equalTo("mouse"));
assertThat(environment.getProperty("onemorekey"), equalTo("moose"));

}
}

0 comments on commit e6ad48d

Please sign in to comment.