Skip to content

Commit ebb9b6a

Browse files
committed
Refactor configs some
1 parent d3a8dc7 commit ebb9b6a

File tree

5 files changed

+124
-55
lines changed

5 files changed

+124
-55
lines changed

stubbornjava-common/src/main/java/com/stubbornjava/common/Configs.java

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.File;
44
import java.util.Map;
5+
import java.util.concurrent.atomic.AtomicReference;
56
import java.util.function.BiFunction;
67
import java.util.function.Supplier;
78

@@ -24,25 +25,42 @@ private Configs() { }
2425
* We could abstract out and delegate but its not worth it.
2526
* I am gambling on the fact that I will not switch out the config library.
2627
*/
27-
private static final Config system = ConfigFactory.systemProperties();
28-
private static final Config properties = new Builder().withSecureConf().envAwareApp().build();
2928

30-
public static Config system() {
31-
return system;
29+
// This config has all of the JVM system properties including any custom -D properties
30+
private static final Config systemProperties = ConfigFactory.systemProperties();
31+
32+
// This config has access to all of the environment variables
33+
private static final Config systemEnvironment = ConfigFactory.systemEnvironment();
34+
35+
// Always start with a blank config and add fallbacks
36+
private static final AtomicReference<Config> propertiesRef = new AtomicReference<>(null);
37+
38+
public static void initProperties(Config config) {
39+
boolean success = propertiesRef.compareAndSet(null, config);
40+
if (!success) {
41+
throw new RuntimeException("propertiesRef Config has already been initialized. This should only be called once.");
42+
}
3243
}
3344

3445
public static Config properties() {
35-
return properties;
46+
return propertiesRef.get();
3647
}
3748

38-
// This should return the current executing user path
39-
public static String getExecutionDirectory() {
40-
return system.getString("user.dir");
49+
public static Config systemProperties() {
50+
return systemProperties;
4151
}
4252

43-
public static Map<String, Object> asMap(Config config) {
44-
return Seq.seq(config.entrySet())
45-
.toMap(e -> e.getKey(), e -> e.getValue().unwrapped());
53+
public static Config systemEnvironment() {
54+
return systemEnvironment;
55+
}
56+
57+
public static Configs.Builder newBuilder() {
58+
return new Builder();
59+
}
60+
61+
// This should return the current executing user path
62+
public static String getExecutionDirectory() {
63+
return systemProperties.getString("user.dir");
4664
}
4765

4866
public static <T> T getOrDefault(Config config, String path, BiFunction<Config, String, T> extractor, T defaultValue) {
@@ -59,6 +77,11 @@ public static <T> T getOrDefault(Config config, String path, BiFunction<Config,
5977
return defaultSupplier.get();
6078
}
6179

80+
public static Map<String, Object> asMap(Config config) {
81+
return Seq.seq(config.entrySet())
82+
.toMap(e -> e.getKey(), e -> e.getValue().unwrapped());
83+
}
84+
6285
public static class Builder {
6386
private Config conf;
6487

@@ -72,6 +95,18 @@ public Builder withResource(String resource) {
7295
return this;
7396
}
7497

98+
public Builder withSystemProperties() {
99+
conf = returnOrFallback(systemProperties);
100+
log.info("Loaded system properties into config");
101+
return this;
102+
}
103+
104+
public Builder withSystemEnvironment() {
105+
conf = returnOrFallback(systemEnvironment);
106+
log.info("Loaded system environment into config");
107+
return this;
108+
}
109+
75110
public Builder withOptionalFile(String path) {
76111
File secureConfFile = new File(path);
77112
if (secureConfFile.exists()) {
@@ -83,14 +118,13 @@ public Builder withOptionalFile(String path) {
83118
return this;
84119
}
85120

86-
public Builder envAwareApp() {
87-
String env = system.hasPath("env") ? system.getString("env") : "local";
88-
String envFile = "application." + env + ".conf";
89-
return withResource(envFile).withResource("application.conf");
121+
public Builder withOptionalRelativeFile(String path) {
122+
return withOptionalFile(getExecutionDirectory() + path);
90123
}
91124

92-
public Builder withSecureConf() {
93-
return withOptionalFile(getExecutionDirectory() + "/secure.conf");
125+
public Builder withConfig(Config config) {
126+
conf = returnOrFallback(config);
127+
return this;
94128
}
95129

96130
public Config build() {
@@ -112,7 +146,9 @@ private Config returnOrFallback(Config config) {
112146
}
113147

114148
public static void main(String[] args) {
115-
Configs.properties();
149+
log.debug(ConfigFactory.load().root().render(ConfigRenderOptions.concise()));
150+
151+
//newBuilder().withSystemEnvironment().withSystemProperties().build();
116152
}
117153
}
118154
// {{end:config}}

stubbornjava-common/src/main/java/com/stubbornjava/common/Env.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55

66
public enum Env {
77
LOCAL("local")
8-
, DEV("dev")
9-
, PROD("prod")
8+
, DEV("development")
9+
, STAGING("staging")
10+
, PROD("production")
1011
;
1112

1213
private final String name;
@@ -23,8 +24,9 @@ public String getName() {
2324
private static final Env currentEnv;
2425
static {
2526
String env = "local";
26-
if (Configs.system().hasPath("env")) {
27-
env = Configs.system().getString("env");
27+
// This comes from -Denv={environment}
28+
if (Configs.systemProperties().hasPath("env")) {
29+
env = Configs.systemProperties().getString("env");
2830
}
2931
currentEnv = Env.valueOf(env.toUpperCase());
3032
log.info("Current Env: {}", currentEnv.getName());

stubbornjava-common/src/test/java/com/stubbornjava/common/ConfigsTest.java

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import static org.junit.Assert.assertEquals;
44

5-
import java.util.concurrent.TimeUnit;
6-
75
import org.junit.Test;
86

97
import com.typesafe.config.Config;
@@ -15,19 +13,16 @@ public void emptyConfigShouldFail() {
1513
new Configs.Builder().build();
1614
}
1715

16+
@Test
17+
public void emptyConfigShouldNotFail() {
18+
new Configs.Builder().build();
19+
}
20+
21+
@Test
1822
public void configShouldLoadResource() {
1923
Config conf = new Configs.Builder()
2024
.withResource("other.conf")
2125
.build();
2226
assertEquals("other", conf.getString("name"));
2327
}
24-
25-
public void configShouldLoadAppConfig() {
26-
Config conf = new Configs.Builder()
27-
.envAwareApp()
28-
.build();
29-
assertEquals("StubbornJava Common", conf.getString("app"));
30-
// 2 minutes is the override local config.
31-
assertEquals(2, conf.getDuration("someTimeout", TimeUnit.MINUTES));
32-
}
3328
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.stubbornjava.webapp;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import com.stubbornjava.common.Configs;
7+
import com.stubbornjava.common.Env;
8+
import com.stubbornjava.common.Json;
9+
import com.typesafe.config.Config;
10+
11+
public class StubbornJavaBootstrap {
12+
13+
private static final Logger logger = LoggerFactory.getLogger(StubbornJavaBootstrap.class);
14+
15+
public static Config getConfig() {
16+
Config config = Configs.newBuilder()
17+
.withOptionalRelativeFile("./secure.conf")
18+
.withResource("application." + Env.get().getName() + ".conf")
19+
.withResource("application.conf")
20+
.build();
21+
logger.debug(Json.serializer().toPrettyString(Configs.asMap(config)));
22+
return config;
23+
}
24+
25+
public static <T> void run(Runnable runnable) {
26+
try {
27+
Configs.initProperties(getConfig());
28+
runnable.run();
29+
} catch (Throwable ex) {
30+
logger.error("", ex);
31+
} finally {
32+
// Close pools and stuff
33+
}
34+
}
35+
}

stubbornjava-webapp/src/main/java/com/stubbornjava/webapp/StubbornJavaWebApp.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -62,43 +62,44 @@ private static HttpHandler wrapWithMiddleware(HttpHandler next) {
6262
// {{end:middleware}}
6363

6464
// These routes do not require any authentication
65-
private static final HttpHandler basicRoutes = new RoutingHandler()
66-
.get("/", timed("getHome", PageRoutes::home))
67-
.get("/ping", timed("ping", PageRoutes::ping))
65+
private static final HttpHandler getBasicRoutes() {
66+
return new RoutingHandler()
67+
.get("/", timed("getHome", PageRoutes::home))
68+
.get("/ping", timed("ping", PageRoutes::ping))
6869

69-
.get("/favicon.ico", timed("favicon", CustomHandlers.resource("images/", (int)TimeUnit.DAYS.toSeconds(30))))
70-
.get("robots.txt", timed("robots", PageRoutes::robots))
70+
.get("/favicon.ico", timed("favicon", CustomHandlers.resource("images/", (int)TimeUnit.DAYS.toSeconds(30))))
71+
.get("robots.txt", timed("robots", PageRoutes::robots))
7172

72-
.get("/posts/{slug}", timed("getPost", PostRoutes::getPost))
73+
.get("/posts/{slug}", timed("getPost", PostRoutes::getPost))
7374

74-
.get("/tags/{tag}/posts", timed("getRecentPostsWithTag", PostRoutes::recentPostsWithTag))
75+
.get("/tags/{tag}/posts", timed("getRecentPostsWithTag", PostRoutes::recentPostsWithTag))
7576

76-
.get("/java-libraries", timed("getJavaLibraries", JavaLibRoutes::listLibraries))
77-
.get("/java-libraries/{library}", timed("getLibrary", JavaLibRoutes::getLibrary))
78-
.get("/libraries/{library}/posts", timed("getLibraryRedirect", JavaLibRoutes::getLibraryRedirect))
77+
.get("/java-libraries", timed("getJavaLibraries", JavaLibRoutes::listLibraries))
78+
.get("/java-libraries/{library}", timed("getLibrary", JavaLibRoutes::getLibrary))
79+
.get("/libraries/{library}/posts", timed("getLibraryRedirect", JavaLibRoutes::getLibraryRedirect))
7980

80-
.get("/guides/{slug}", timed("getGuide", GuideRoutes::getGuide))
81+
.get("/guides/{slug}", timed("getGuide", GuideRoutes::getGuide))
8182

82-
.get("/best-selling-html-css-themes-and-website-templates", timed("popularThemes", ThemeRoutes::popularThemes))
83+
.get("/best-selling-html-css-themes-and-website-templates", timed("popularThemes", ThemeRoutes::popularThemes))
8384

84-
.get("/dev/metrics", timed("getMetrics", HelperRoutes::getMetrics))
85+
.get("/dev/metrics", timed("getMetrics", HelperRoutes::getMetrics))
8586

86-
// addAll allows you to combine more than one RoutingHandler together.
87-
.addAll(SitemapRoutes.router(StubbornJavaSitemapGenerator.getSitemap()))
87+
// addAll allows you to combine more than one RoutingHandler together.
88+
.addAll(SitemapRoutes.router(StubbornJavaSitemapGenerator.getSitemap()))
8889

89-
.setFallbackHandler(timed("notFound", PageRoutes::notFound))
90-
;
91-
92-
private static final HttpHandler staticRoutes = new PathHandler(basicRoutes)
93-
.addPrefixPath("/assets", timed("getAssets", CustomHandlers.resource("", (int)TimeUnit.DAYS.toSeconds(30))))
94-
;
90+
.setFallbackHandler(timed("notFound", PageRoutes::notFound));
91+
}
9592

9693
private static void startServer() {
94+
HttpHandler staticRoutes = new PathHandler(getBasicRoutes())
95+
.addPrefixPath("/assets", timed("getAssets", CustomHandlers.resource("", (int)TimeUnit.DAYS.toSeconds(30))));
9796
SimpleServer server = SimpleServer.simpleServer(wrapWithMiddleware(staticRoutes));
9897
server.start();
9998
}
10099

101100
public static void main(String[] args) {
102-
startServer();
101+
StubbornJavaBootstrap.run(() -> {
102+
startServer();
103+
});
103104
}
104105
}

0 commit comments

Comments
 (0)