Read multiple properties file in one go using Spring Boot? - spring

I went through the link: How to pass a Map<String, String> with application.properties and other related links multiple times, but still its not working.
I'm using Spring Boot and Spring REST example. Link Question: How to by default execute the latest version of endpoint in Spring Boot REST?.
I've created mapping something like this and simply read the mapping
get.customers={GET: '/app-data/customers', VERSION: 'v1'}
post.customers={POST: '/app-data/customers', VERSION: 'v1'}
get.customers.custId={GET: '/app-data/customers/{custId}', VERSION: 'v2'}
Code:
private String resolveLastVersion() {
// read from configuration or something
return "2";
}
Code:
#Component
#ConfigurationProperties
#PropertySource("classpath:restendpoint.properties")
public class PriorityProcessor {
private final Map<String, String> priorityMap = new HashMap<>();
public Map<String, String> getPriority() {
return priorityMap;
}
}
Code:

I suggest the following implementation:
#ConfigurationProperties(prefix="request")
public class ConfigurationProps {
private List<Mapping> mapping;
public List<Mapping> getMapping() {
return mapping;
}
public void setMapping(List<Mapping> mapping) {
this.mapping = mapping;
}
}
Class Mapping will denote the information about the single mapping:
public class Mapping {
private String method;
private String url;
private String version;
public Mapping(String method, String url, String version) {
this.method = method;
this.url = url;
this.version = version;
}
public Mapping() {
}
// getters setters here
}
On the Configuration or spring boot application class (the one with main method):
#EnableConfigurationProperties(ConfigurationProps.class)
In the properties file put:
request.mapping[0].method=get
request.mapping[0].url=/customers
request.mapping[0].version=1
request.mapping[1].method=post
request.mapping[1].url=/students
request.mapping[1].version=2
In Filter (I assume you followed my suggestion from the linked question):
#Component
#Order(1)
public class LatestVersionFilter implements Filter {
private List<Mapping> mappings;
public LatestVersionFilter(ConfigurationProps props) {
this.mappings = props.getMapping();
}
}

Related

Spring Boot 2.3.0 - MongoDB Library does not create indexes automatically

I've provided a sample project to elucidate this problem: https://github.com/nmarquesantos/spring-mongodb-reactive-indexes
According to the spring mongo db documentation (https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping-usage):
the #Indexed annotation tells the mapping framework to call createIndex(…) on that property of your document, making searches faster. Automatic index creation is only done for types annotated with #Document.
In my Player class, we can observe the both the #Document and #Indexed annotation:
#Document
public class Player {
#Id
private String id;
private String playerName;
#Indexed(name = "player_nickname_index", unique = true)
private String nickname;
public Player(String playerName, String nickname) {
this.id = UUID.randomUUID().toString();
this.playerName = playerName;
this.nickname = nickname;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}`
And in my application class, i'm inserting oneelement to check the database is populated successfully:
#PostConstruct
public void seedData() {
var player = new Player("Cristiano Ronaldo", "CR7");
playerRepository.save(player).subscribe();
}
If I check MongoDb after running my application, I can see the collection and the element created successfully.
The unique index for nickname is not created. I can only see an index created for the #Id attribute. Am I missing anything? Did I mis-interpret the documentation?
The Spring Data MongoDB version come with Spring Boot 2.3.0.RELEASE is 3.0.0.RELEASE. Since Spring Data MongoDB 3.0, the auto-index creation is disabled by default.
To enable auto-index creation, set spring.data.mongodb.auto-index-creation = true or if you have custom Mongo configuration, override the method autoIndexCreation
#Configuration
public class CustomMongoConfig extends AbstractMongoClientConfiguration {
#Override
public boolean autoIndexCreation() {
return true;
}
// your other configuration
}
I've faced this problem when upgrading the spring boot version to 2.3.x and overriding this method on the config class solved it (what #yejianfengblue said above)
#Override
public boolean autoIndexCreation() {
return true;
}

How to get spring boot property file value as Map<String,String>

In my project am having a requirement to retrieve a property file values in a map. This is how i wrote a code to retrieve property file value in a map. But values is not binding in the map. How can i achieve this.Is anything i missed?
specialist.properties
#Configuration
#ConfigurationProperties(prefix = "specialist")
#PropertySource("classpath:specialist.properties")
public class SpecialistProperties {
private Map<String,String> specialist=new HashMap<String,String>();
public Map<String, String> getSpecialist() {
return specialist;
}
public void setSpecialist(Map<String, String> specialist) {
this.specialist = specialist;
}
}
Controller class:
#RestController
public class MyappController {
#Autowired
private SpecialistProperties specialistProperties;
#GetMapping(value="/specialist")
public Map<String,String> getSpecialist()
{
return specialistProperties.getMap();
}
}
specialist.properties
specialist.name=Sam
specialist.availableDay=Wednesday
specialist.availableTime=5PM
You can set properties as shown below.
Make a file with name: application.properties with following code:
example.hello=Hello
example.user=Abhimanyu
example.howru=How are you?
example.mapProperty.key1=MapValue1
example.mapProperty.key2=MapValue2
example.listProperty[0]=ListValue1
example.listProperty[1]=ListValue2
OR:
Make a file with name: application.yml with the following code
example:
hello: Hello
user: Abhimanyu
howru: How are you?
mapProperty:
key1: MapValue1
key2: MapValue2
listProperty:
ListValue1
ListValue2
And you can verify/format your yaml file online by visiting https://jsonformatter.org/yaml-validator
For your reference refer following the link: http://jcombat.com/spring/how-to-read-properties-using-spring-boot-configurationproperties
I made a mistake by adding the #ConfigurationProperties(prefix="specialist"). No need of prefix="specialist". Because the map property value i have added as specialist, so there is no need of specialist in the ConfigurationProperties prefix. After the change it was worked good.
#Configuration
#ConfigurationProperties
#PropertySource("classpath:specialist.properties")
public class SpecialistProperties {
private Map<String,String> prop=new HashMap<String,String>();
public Map<String, String> getProp() {
return prop;
}
public void setProp(Map<String, String> prop) {
this.prop = prop;
}
}

How can I load propeties in a Map with SpringBoot?

I try to initialize a Map in my SpringBoot application but I am doing something wrong.
My config.properties:
myFieldMap.10000.fieldName=MyFieldName
myFieldMap.10000.fieldName2=MyFieldName2
myFieldMap.10001.fieldName=MyFieldName
myFieldMap.10001.fieldName2=MyFieldName2
myFieldMap.10002.fieldName=MyFieldName
myFieldMap.10003.fieldName2=MyFieldName2
...
(Isn't it possible to use some kind of bracket notation like myFieldMap[10001].fieldName for maps (I saw it used for lists).
I tried with my MyConfig.class:
#PropertySource("classpath:config.properties")
#Component
public class MyConfig {
private java.util.Map<Integer, MyMapping> theMappingsMap = new HashMap<Integer, MyMapping>();
public Map<String, MyMapping> getTheMappingsMap() {
return theMappingsMap;
}
public void setTheMappingsMap(Map<String, MyMapping> theMappingsMap) {
this.theMappingsMap= theMappingsMap;
}
public class MyMapping {
private String fieldName;
private String fieldName2;
public String getFieldName() {
return fieldName;
}
public String getFieldName2() {
return fieldName2;
}
public void setFieldName(final String fieldName) {
this.fieldName = fieldName;
}
public void setFieldName2(final String fieldName) {
this.fieldName2 = fieldName;
}
}
}
How do I have to adapt my code to let SpringBoot initialize my configuration (Map) with the definitions in the config.properties file?
You are missing #ConfigurationProperties annotation. Try this
#PropertySource("classpath:config.properties")
#Configuration
#ConfigurationProperties
public class MyConfig {
private java.util.Map<String, MyMapping> myFieldMap = new HashMap<>();
....
}
Another issue with your code is, if you want to make MyMapping class as an inner class of MyConfig, then you need to declare it as static. Or else you can make it as a separate class.

How to map configuration objects to java object

I have a spring boot application which is using a spring cloud config.
How can i map a configuration element with some java object.
My config is something like this:
clients:
- id : 1
name: client 1
groups : [a,b]
- id : 2
name: client 2
groups : [a]
And my java object is:
public class ClientInfo {
private String clientId;
private List<String> profiles;
public ClientInfo(String clientId, List<String> pips) {
this.clientId = clientId;
this.profiles = pips;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public List<String> getProfiles() {
return profiles;
}
public void setProfiles(List<String> profiles) {
this.profiles = profiles;
}
}
I want to map my configuration with List
Use below code to configure configuration properties in to java Object,
#Component
#EnableConfigurationProperties
#ConfigurationProperties(prefix = "clients")
public class ClientInfo {
private String id;
private String name;
private List<String> groups;
public String getId(){ return id;}
public String getName(){ return name;}
public List<String> getGroups(){ return groups;}
}
Check following for example http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
Inject this class in another class :
#Autowired
private ClientInfo clientInfo;
The above auto wiring will not work if the class is instantiated using "new operator".
Actually I found the reason why it was not working.
All that was needed is to have another class which contains a list of ClientInfo and have #EnableConfigurationProperties and #ConfigurationProperties annotations on it. This is because "clients" in my configuration is a list. After this change we can use #Autowired annotation to inject the configuration.

Trying to use properties file in spring boot

I have a locations.properties file which looks like this:
location.endpoint=testadres,andertestadres
location.test=teststring
I'm trying to read this config file with following class:
#Configuration
#PropertySource("classpath:locations.properties")
public class LocationProperties {
#Value("#{'${location.endpoint}'.split(',')}")
private List<String> locations;
#Value("${location.test}")
private String test;
public String getTest() {
return this.test;
}
public List<String> getLocations() {
return this.locations;
}
//To resolve ${} in #Value
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
return new PropertySourcesPlaceholderConfigurer();
}
}
But whenever I try to get the strings with getLocations() or getTest() I get null?
Just add .properties or .yml file to your /resources folder. Example
# simple.yml
demo:
connection:
username: sample
sample: My text
and add POJO class
#Component
#ConfigurationProperties(
prefix = "demo.connection",
locations = "classpath:sample.yml"
)
public class SampleSettings {
private String sample;
private String username;
..Getters and Setters mandatory

Resources