Merge property file into application.properties - java

I have two properties files. Let's say a.properties and b.properties. these file values has been stored in maps created, let say aMap and bMap.
#PropertySource(value={ "classpath:a.properties", "classpath:b.properties"})
Class propFile{
Private Map<String, String> aMap;
Private Map<String, String> bMap;
}
I have to merge these property file into application.properties such that it works same way. Please provide me solution for this.

You will be able to retrieve your properties by annotating your properties class with #Configuration and #ConfigurationProperties:
#Configuration
#ConfigurationProperties(prefix="maps")
public class ConfigProperties {
private Map<String, String> a;
private Map<String, String> b;
// getters and setters
}
The corresponding application.yml would look as follows:
maps:
a:
key:
test1
b:
key:
test2
Or alternatively with an application.properties file:
maps.a.key=test1
maps.b.key=test2

Related

How to get child properties from spring config

I have the following configuration:
external:
shop-service:
url: localhost:8080
timeout: 5000
pet-service:
url: localhost:8081
timeout: 10000
user-service:
url: localhost:8082
timeout: 15000
I want to create some config library that will read these properties in every my service. In every service I can have different clients with different values of properties, but all of them have the same structure.
Any ways how I can get a map that will contain client name as a key and object that has url and timeout values, if I know only external property at the beginning and don't know exact client names?
You can create a configuration class which maps your properties into a map.
#Getter
#Configuration
#ConfigurationProperties
public class Properties {
private Map<String, String[]> external = new HashMap<>();
}
In my opinion, you should avoid using String array as value type. Instead of, you should create a POJO to map the url and timeout properties.
#Getter
#Configuration
#ConfigurationProperties
public class Properties {
private Map<String, Data> external = new HashMap<>();
#Getter
#Setter
#ToString
public static class Data {
private long timeout;
private String url;
}
}
Note: the Properties class must have a getter for the map, and the Data properties must have a getter and setter for each attribute.
this is my solution
private static final String BASE_PROPERTY = "clients.";
private static final String DELIMITER = ".";
private final org.springframework.core.env.Environment environment;
public Set<String> getClientNames() {
return Arrays
.stream(((EnumerablePropertySource<?>) ((ConfigurableEnvironment) environment)
.getPropertySources()
.stream()
.filter(OriginTrackedMapPropertySource.class::isInstance)
.findFirst()
.orElseThrow(RuntimeException::new)).getPropertyNames())
.filter(currentValue -> StringUtils.startsWith(currentValue, BASE_PROPERTY))
.map(key -> StringUtils.substringBetween(key, DELIMITER, DELIMITER))
.filter(Objects::nonNull)
.collect(Collectors.toSet());
}

Getting subset of application.properties by prefix

I have (partly) this application.properties in my Spring Boot app:
spring.main.banner-mode = off
app.set.a = 100
app.set.b = abc
app.set.c
# ...
I want to get injected a Properties object with all keys/values with prefix "app.". Something directly like this:
#Value(value="${app.*}")
private Properties appProperties; // this obviously won´t work
I have not tried with Properties. But this is how you do with a Map.
application.yml:
test:
my-map:
key1: value1
key2: value2
Java:
#Service
#ConfigurationProperties(prefix="test")
public class MyService {
private Map<String, String> myMap = new HashMap<>(); // add getter
}

Spring bind application properties Map<MyEnum, List<CustomObject>>

I'm trying to bind application properties to a Map<MyEnum, List<CustomObject>> in Spring.
I'm aware of following bindings for maps:
foo.keyValueMap.EnumKey=value
foo.keyListValueMap.EnumKey=value1,value2
which respectively creates a Map<EnumKey, String> keyValueMap and Map<EnumKey, List<String>> keyListValueMap.
What I try to accomplish is as the titles says, a map Map<MyEnum, List<CustomObject>>, whereCustomObject having multiple properties including a Set.
class CustomObject {
private Set<String> set;
private String property;
// ...
}

Inject all keys and Values from property file as Map in Spring

Can someone provide some idea to inject all dynamic keys and values from property file and pass it as Map to DBConstants class using Setter Injection with Collection.
Keys are not known in advance and can vary.
// Example Property File that stores all db related details
// db.properties
db.username.admin=root
db.password.admin=password12
db.username.user=admin
db.password.user=password13
DBConstants contains map dbConstants for which all keys and values need to be injected.
Please provide bean definition to inject all keys and values to Map dbConstants.
public class DBConstants {
private Map<String,String> dbConstants;
public Map<String, String> getDbConstants() {
return dbConstants;
}
public void setDbConstants(Map<String, String> dbConstants) {
this.dbConstants = dbConstants;
}
}
You can create PropertiesFactoryBean with your properties file and then inject it with #Resource annotation where you want to use it as a map.
#Bean(name = "myProperties")
public static PropertiesFactoryBean mapper() {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource("prop_file_name.properties"));
return bean;
}
Usage:
#Resource(name = "myProperties")
private Map<String, String> myProperties;
you can use #Value.
Properties file:
dbConstants={key1:'value1',key2:'value2'}
Java code:
#Value("#{${dbConstants}}")
private Map<String,String> dbConstants;
you have to give spaces its like
hash.key = {indoor: 'reading', outdoor: 'fishing'}
Read map like below as i mentioned.
#Value("#{${hash.key}}")
private Map<String, String> hobbies;

JPA persistence.xml

Is there a way to make the data on the persistence.xml dynamic?
I was thinking of adding a database name property on my properties file, then the tables are created, if not existing.
Is this possible?
I'm using EclipseLink(JPA2.0) and MySQL.
If you use JPA in standalone environment, you can pass additional properties to Persistence.createEntityManagerFactory().
In application server environments you can use datasource obtained from JNDI.
If you are using spring, you can use the spring property-placeholder-configurer mechanism to do so. Just extend your EclipseLink vendor adapter:
public class ExtendedJpaVendorAdapter extends XJpaVendorAdapter {
private Map<String, Object> vendorProperties;
#Override
public Map<String, Object> getJpaPropertyMap() {
Map<String, Object> properties = super.getJpaPropertyMap();
properties.putAll(vendorProperties);
return properties;
}
public Map<String, Object> getVendorProperties() {
return vendorProperties;
}
public void setVendorProperties(Map<String, Object> vendorProperties) {
this.vendorProperties = vendorProperties;
}
}
And then you can configure these in the spring xml file.

Categories

Resources