Reputation: 2115
I need to define service connection properties which will be used to configure RestTemplate
s used to make REST endpoint calls to Spring Boot services.
Note: In the future a service discovery mechanism will likely be involved, but I have been instructed NOT to pursue that avenue for the time being.
Service connection properties:
Possible configuration (YAML):
services-config:
global:
scheme: http|https
connectionTimeout: <timeout ms>
requestTimeout: <timeout ms>
socketTimeout: <timeout ms>
defaultKeepAlive: <timeout ms>
defaultMaxConnPerRoute: <count>
maxTotalConnections: <count>
services:
- id: <ID> [?]
name: <name> [?]
host: localhost|<host>
port: <port>
- id: <ID> [?]
name: <name> [?]
host: localhost|<host>
port: <port>
...
The intent is to place this information into an application.yml file so that it can be accessed within the Spring application.
Is there a way to pull this information in YAML format into a Java object hierarchy like the following:
class : ServicesConfig
global : GlobalConnectionProperties
services : map<String, ServiceConnectionProperties>
class : GlobalConnectionProperties
scheme : String (maybe enum instead)
connectionTimeout : int
requestTimeout : int
socketTimeout : int
defaultKeepAlive : int
defaultMaxConnPerRoute : int
maxTotalConnections : int
class : ServiceConnectionProperties
id : String
name : String
host : String
port : int
UPDATE:
Attempted the following and achieved partial success:
ServiceConfiguration.java
@Configuration
public class ServiceConfiguration {
private ServicesConfig servicesConfig;
@Autowired
public ServiceConfiguration(ServicesConfig servicesConfig) {
this.servicesConfig = servicesConfig;
System.out.println(servicesConfig);
}
}
ServicesConfig.java:
@ConfigurationProperties(value = "services-config")
@EnableConfigurationProperties(
value = {GlobalConnectionProperties.class, ServiceConnectionProperties.class})
public class ServicesConfig {
private GlobalConnectionProperties globalProps;
private Map<String, ServiceConnectionProperties> services;
public GlobalConnectionProperties getGlobalProps() {
return globalProps;
}
public void setGlobalProps(GlobalConnectionProperties globalProps) {
this.globalProps = globalProps;
}
public Map<String, ServiceConnectionProperties> getServices() {
return services;
}
public void setServices(Map<String, ServiceConnectionProperties> services) {
this.services = services;
}
@Override
public String toString() {
return "ServicesConfig [globalProps=" + globalProps + ", services=" + services + "]";
}
}
application.yml:
services-config:
global:
scheme: http
connectionTimeout: 30000
requestTimeout: 30000
socketTimeout: 60000
defaultKeepAlive: 20000
defaultMaxConnPerRoute: 10
maxTotalConnections: 200
services:
- id: foo
name: foo service
host: 192.168.56.101
port: 8090
- id: bar
name: bar service
host: 192.168.56.102
port: 9010
The GlobalConnectionProperties and ServiceConnectionProperties classes have been omitted as they just contain properties, getter/setter methods and toString().
When I run a service, the following appears on the console:
ServicesConfig [globalProps=null, services={0=ServiceConnectionProperties [id=foo, name=foo service, host=192.168.56.101, port=8090], 1=ServiceConnectionProperties [id=bar, name=bar service, host=192.168.56.102, port=9010]}]
I'm actually surprised that the list items were parsed and inserted into the map. I'd like the "id" to be the key instead of a default integer. The odd thing is that the "global" properties have not made it into the map.
What do I need to correct to get the global object items read in?
Is there a way to key the map entries by the item "id" property?
Upvotes: 0
Views: 2360
Reputation: 29129
What do I need to correct to get the global object items read in?
Binding of properties follows Java Bean conventions so in ServicesConfig
you need to rename the field and getters/setters from globalProps
to global
.
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-typesafe-configuration-properties as linked in the comment has more details.
Is there a way to key the map entries by the item "id" property?
For the map entries your yaml syntax is incorrect. See the syntax using :
and ?
at https://bitbucket.org/asomov/snakeyaml/wiki/Documentation#markdown-header-type-safe-collections.
Your map would be
services:
? foo
: { id: foo,
name: foo service,
host: 192.168.56.101,
port: 8090 }
? bar
: { id: bar,
name: bar service,
host: 192.168.56.102,
port: 9010}
Upvotes: 2