From 9ab810aba15aa20cdd9be6e4c82875e8d3cad241 Mon Sep 17 00:00:00 2001 From: vizsoro Date: Mon, 27 Aug 2018 08:39:44 +0200 Subject: [PATCH] loading json props --- .../ConfigPropertiesDemoApplication.java | 8 ++- .../properties/CustomJsonProperties.java | 71 +++++++++++++++++++ .../baeldung/properties/JsonProperties.java | 64 +++++++++++++++++ .../JsonPropertyContextInitializer.java | 68 ++++++++++++++++++ .../properties/JsonPropertySourceFactory.java | 20 ++++++ .../src/main/resources/configprops.json | 10 +++ .../src/main/resources/configpropscustom.json | 9 +++ .../JsonPropertiesIntegrationTest.java | 59 +++++++++++++++ 8 files changed, 306 insertions(+), 3 deletions(-) create mode 100644 spring-boot/src/main/java/org/baeldung/properties/CustomJsonProperties.java create mode 100644 spring-boot/src/main/java/org/baeldung/properties/JsonProperties.java create mode 100644 spring-boot/src/main/java/org/baeldung/properties/JsonPropertyContextInitializer.java create mode 100644 spring-boot/src/main/java/org/baeldung/properties/JsonPropertySourceFactory.java create mode 100644 spring-boot/src/main/resources/configprops.json create mode 100644 spring-boot/src/main/resources/configpropscustom.json create mode 100644 spring-boot/src/test/java/org/baeldung/properties/JsonPropertiesIntegrationTest.java diff --git a/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java b/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java index cb0304fc41..7ca0ab4f60 100644 --- a/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java +++ b/spring-boot/src/main/java/org/baeldung/properties/ConfigPropertiesDemoApplication.java @@ -1,13 +1,15 @@ package org.baeldung.properties; -import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.ComponentScan; @EnableAutoConfiguration -@ComponentScan(basePackageClasses = ConfigProperties.class) +@ComponentScan(basePackageClasses = { ConfigProperties.class, JsonProperties.class, CustomJsonProperties.class }) public class ConfigPropertiesDemoApplication { public static void main(String[] args) { - SpringApplication.run(ConfigPropertiesDemoApplication.class); + new SpringApplicationBuilder(ConfigPropertiesDemoApplication.class).initializers(new JsonPropertyContextInitializer()) + .run(); } + } diff --git a/spring-boot/src/main/java/org/baeldung/properties/CustomJsonProperties.java b/spring-boot/src/main/java/org/baeldung/properties/CustomJsonProperties.java new file mode 100644 index 0000000000..9d5e8ce780 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/CustomJsonProperties.java @@ -0,0 +1,71 @@ +package org.baeldung.properties; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "custom") +public class CustomJsonProperties { + + private String host; + + private int port; + + private boolean resend; + + private Person sender; + + public static class Person { + + private String name; + private String address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public boolean isResend() { + return resend; + } + + public void setResend(boolean resend) { + this.resend = resend; + } + + public Person getSender() { + return sender; + } + + public void setSender(Person sender) { + this.sender = sender; + } +} diff --git a/spring-boot/src/main/java/org/baeldung/properties/JsonProperties.java b/spring-boot/src/main/java/org/baeldung/properties/JsonProperties.java new file mode 100644 index 0000000000..2e6e24036e --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/JsonProperties.java @@ -0,0 +1,64 @@ +package org.baeldung.properties; + +import java.util.LinkedHashMap; +import java.util.List; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource(value = "classpath:configprops.json", factory = JsonPropertySourceFactory.class) +@ConfigurationProperties +public class JsonProperties { + + private String host; + + private int port; + + private boolean resend; + + private List topics; + + private LinkedHashMap sender; + + public LinkedHashMap getSender() { + return sender; + } + + public void setSender(LinkedHashMap sender) { + this.sender = sender; + } + + public List getTopics() { + return topics; + } + + public void setTopics(List topics) { + this.topics = topics; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public boolean isResend() { + return resend; + } + + public void setResend(boolean resend) { + this.resend = resend; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } +} diff --git a/spring-boot/src/main/java/org/baeldung/properties/JsonPropertyContextInitializer.java b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertyContextInitializer.java new file mode 100644 index 0000000000..27abadb1e1 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertyContextInitializer.java @@ -0,0 +1,68 @@ +package org.baeldung.properties; + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.Resource; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonPropertyContextInitializer implements ApplicationContextInitializer { + + private final static String CUSTOM_PREFIX = "custom."; + + @Override + @SuppressWarnings("unchecked") + public void initialize(ConfigurableApplicationContext configurableApplicationContext) { + try { + Resource resource = configurableApplicationContext.getResource("classpath:configpropscustom.json"); + Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class); + Set set = readValue.entrySet(); + List propertySources = convertEntrySet(set, Optional.empty()); + for (PropertySource propertySource : propertySources) { + configurableApplicationContext.getEnvironment() + .getPropertySources() + .addFirst(propertySource); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static List convertEntrySet(Set entrySet, Optional parentKey) { + return entrySet.stream() + .map((Map.Entry e) -> convertToPropertySourceList(e, parentKey)) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + } + + private static List convertToPropertySourceList(Map.Entry e, Optional parentKey) { + String key = parentKey.map(s -> s + ".") + .orElse("") + (String) e.getKey(); + Object value = e.getValue(); + return covertToPropertySourceList(key, value); + } + + @SuppressWarnings("unchecked") + private static List covertToPropertySourceList(String key, Object value) { + if (value instanceof LinkedHashMap) { + LinkedHashMap map = (LinkedHashMap) value; + Set entrySet = map.entrySet(); + return convertEntrySet(entrySet, Optional.ofNullable(key)); + } + String finalKey = CUSTOM_PREFIX + key; + return Collections.singletonList(new MapPropertySource(finalKey, Collections.singletonMap(finalKey, value))); + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/java/org/baeldung/properties/JsonPropertySourceFactory.java b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertySourceFactory.java new file mode 100644 index 0000000000..7e5739fd41 --- /dev/null +++ b/spring-boot/src/main/java/org/baeldung/properties/JsonPropertySourceFactory.java @@ -0,0 +1,20 @@ +package org.baeldung.properties; + +import java.io.IOException; +import java.util.Map; + +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.io.support.EncodedResource; +import org.springframework.core.io.support.PropertySourceFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class JsonPropertySourceFactory implements PropertySourceFactory { + + @Override + public org.springframework.core.env.PropertySource createPropertySource(String name, EncodedResource resource) throws IOException { + Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class); + return new MapPropertySource("json-property", readValue); + } + +} \ No newline at end of file diff --git a/spring-boot/src/main/resources/configprops.json b/spring-boot/src/main/resources/configprops.json new file mode 100644 index 0000000000..1602663775 --- /dev/null +++ b/spring-boot/src/main/resources/configprops.json @@ -0,0 +1,10 @@ +{ + "host" : "mailer@mail.com", + "port" : 9090, + "resend" : true, + "topics" : ["spring", "boot"], + "sender" : { + "name": "sender", + "address": "street" + } +} diff --git a/spring-boot/src/main/resources/configpropscustom.json b/spring-boot/src/main/resources/configpropscustom.json new file mode 100644 index 0000000000..5449876be3 --- /dev/null +++ b/spring-boot/src/main/resources/configpropscustom.json @@ -0,0 +1,9 @@ +{ + "host" : "mailer.custom@mail.com", + "port" : 8081, + "resend" : true, + "sender" : { + "name": "sender.custom", + "address": "street.custom" + } +} diff --git a/spring-boot/src/test/java/org/baeldung/properties/JsonPropertiesIntegrationTest.java b/spring-boot/src/test/java/org/baeldung/properties/JsonPropertiesIntegrationTest.java new file mode 100644 index 0000000000..20a19e043a --- /dev/null +++ b/spring-boot/src/test/java/org/baeldung/properties/JsonPropertiesIntegrationTest.java @@ -0,0 +1,59 @@ +package org.baeldung.properties; + +import java.util.Arrays; + +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@ContextConfiguration(classes = ConfigPropertiesDemoApplication.class, initializers = JsonPropertyContextInitializer.class) +public class JsonPropertiesIntegrationTest { + + @Autowired + private JsonProperties jsonProperties; + + @Autowired + private CustomJsonProperties customJsonProperties; + + @Test + public void givenJsonPropertySource_whenPropertySourceFactoryUsed_thenLoadFlatValues() { + Assert.assertEquals("mailer@mail.com", jsonProperties.getHost()); + Assert.assertEquals(9090, jsonProperties.getPort()); + Assert.assertTrue(jsonProperties.isResend()); + } + + @Test + public void givenJsonPropertySource_whenPropertySourceFactoryUsed_thenLoadListValues() { + Assert.assertThat(jsonProperties.getTopics(), Matchers.is(Arrays.asList("spring", "boot"))); + } + + @Test + public void givenJsonPropertySource_whenPropertySourceFactoryUsed_thenNestedValuesLoadedAsMap() { + Assert.assertEquals("sender", jsonProperties.getSender() + .get("name")); + Assert.assertEquals("street", jsonProperties.getSender() + .get("address")); + } + + @Test + public void givenCustomJsonPropertySource_whenLoadedIntoEnvironment_thenFlatValuesPopulated() { + Assert.assertEquals("mailer.custom@mail.com", customJsonProperties.getHost()); + Assert.assertEquals(8081, customJsonProperties.getPort()); + Assert.assertTrue(customJsonProperties.isResend()); + } + + @Test + public void givenCustomJsonPropertySource_whenLoadedIntoEnvironment_thenValuesLoadedIntoClassObject() { + Assert.assertNotNull(customJsonProperties.getSender()); + Assert.assertEquals("sender.custom", customJsonProperties.getSender() + .getName()); + Assert.assertEquals("street.custom", customJsonProperties.getSender() + .getAddress()); + } + +}