Spring Propertysource Using Yaml Stack Overflow
Using a ConfigMap PropertySource Kubernetes provides a resource named ConfigMap to externalize the parameters to pass to your application in the form of key-value pairs or embedded application.properties or application.yaml files. The Spring Cloud Kubernetes Config project makes Kubernetes ConfigMap instances available during application startup and triggers hot reloading of beans or Spring context when changes are detected on observed ConfigMap instances. Everything that follows is explained mainly referring to examples using ConfigMaps, but the same stands for Secrets, i.e.: every feature is supported for both.
The default behavior is to create a Fabric8ConfigMapPropertySource (or a KubernetesClientConfigMapPropertySource ) based on a Kubernetes ConfigMap that has metadata.name of either: - value of spring.cloud.kubernetes.config.name - value of your Spring application (as defined by spring.application.name property) - the String literal "application" However, more advanced configuration is possible where you can use multiple ConfigMap instances. The spring.cloud.kubernetes.config.sources list makes this possible.
For example, you could define the following ConfigMap instances: spring: application: name: cloud-k8s-app cloud: kubernetes: config: name: default-name namespace: default-namespace sources: # Spring Cloud Kubernetes looks up a ConfigMap named c1 in namespace default-namespace - name: c1 # Spring Cloud Kubernetes looks up a ConfigMap named default-name in whatever namespace n2 - namespace: n2 # Spring Cloud Kubernetes looks up a ConfigMap named c3 in namespace n3 - namespace: n3 name: c3 In the preceding example, if spring.cloud.kubernetes.config.namespace had not been set, the ConfigMap named c1 would be looked up in the namespace that the application runs.
See Namespace resolution to get a better understanding of how the namespace of the application is resolved. Any matching ConfigMap that is found is processed as follows: - Apply individual configuration properties. - Apply as yaml (orproperties ) the content of any property that is named by the value ofspring.application.name (if it’s not present, byapplication.yaml/properties ) - Apply as a properties file the content of the above name + each active profile. An example should make a lot more sense.
Let’s suppose that spring.application.name=my-app and that we have a single active profile called k8s . For a configuration as below: kind: ConfigMap apiVersion: v1 metadata: name: my-app data: my-app.yaml: |- ... my-app-k8s.yaml: |- .. my-app-dev.yaml: |- .. not-my-app.yaml: |- ..
someProp: someValue This is what we will end-up loading: - my-app.yaml treated as a file - my-app-k8s.yaml treated as a file - my-app-dev.yaml ignored, sincedev is not an active profile - not-my-app.yaml ignored, since it does not matchspring.application.name - someProp: someValue plain property The order of loading properties is a as follows: - first load all properties from my-app.yaml - then all from profile-based sources: my-app-k8s.yaml - then all plain properties someProp: someValue This means that profile based sources take precedence over non-profile based sources (just like in a vanilla Spring app); and plain properties take precedence over both profile and non-profile based sources.
Here is an example: kind: ConfigMap apiVersion: v1 metadata: name: my-app data: my-app-k8s.yaml: |- key1=valueA key2=valueB my-app.yaml: |- key1=valueC key2=valueA key1: valueD After processing such a ConfigMap, this is what you will get in the properties: key1=valueD , key2=valueB . The single exception to the aforementioned flow is when the ConfigMap contains a single key that indicates the file is a YAML or properties file.
In that case, the name of the key does NOT have to be application.yaml or application.properties (it can be anything) and the value of the property is treated correctly. This features facilitates the use case where the ConfigMap was created by using something like the following: kubectl create configmap game-config --from-file=/path/to/app-config.yaml Assume that we have a Spring Boot application named demo that uses the following properties to read its thread pool configuration.
pool.size.core - pool.size.maximum This can be externalized to config map in yaml format as follows: kind: ConfigMap apiVersion: v1 metadata: name: demo data: pool.size.core: 1 pool.size.max: 16 Individual properties work fine for most cases. However, sometimes, embedded yaml is more convenient.
In this case, we use a single property named application.yaml to embed our yaml , as follows: kind: ConfigMap apiVersion: v1 metadata: name: demo data: application.yaml: |- pool: size: core: 1 max:16 The following example also works: kind: ConfigMap apiVersion: v1 metadata: name: demo data: custom-name.yaml: |- pool: size: core: 1 max:16 You can also define the search to happen based on labels, for example: spring: application: name: labeled-configmap-with-prefix cloud: kubernetes: config: enabled: true useNameAsPrefix: true namespace: spring-k8s sources: - labels: letter: a This will search for every configmap in namespace spring-k8s that has labels {letter : a} .
The important thing to notice here is that unlike reading a configmap by name, this can result in multiple config maps read. As usual, the same feature is supported for secrets. You can also configure Spring Boot applications differently depending on active profiles that are merged together when the ConfigMap is read.
You can provide different property values for different profiles by using an application.properties or application.yaml property, specifying profile-specific values, each in their own document (indicated by the --- sequence), as follows: kind: ConfigMap apiVersion: v1 metadata: name: demo data: application.yml: |- greeting: message: Say Hello to the World farewell: message: Say Goodbye --- spring: profiles: development greeting: message: Say Hello to the Developers farewell: message: Say Goodbye to the Developers --- spring: profiles: production greeting: message: Say Hello to the Ops In the preceding case, the configuration loaded into your Spring Application with the development profile is as follows: greeting: message: Say Hello to the Developers farewell: message: Say Goodbye to the Developers However, if the production profile is active, the configuration becomes: greeting: message: Say Hello to the Ops farewell: message: Say Goodbye If both profiles are active, the property that appears last within the ConfigMap overwrites any preceding values.
Another option is to create a different config map per profile and spring boot will automatically fetch it based on active profiles kind: ConfigMap apiVersion: v1 metadata: name: demo data: application.yml: |- greeting: message: Say Hello to the World farewell: message: Say Goodbye kind: ConfigMap apiVersion: v1 metadata: name: demo-development data: application.yml: |- spring: profiles: development greeting: message: Say Hello to the Developers farewell: message: Say Goodbye to the Developers kind: ConfigMap apiVersion: v1 metadata: name: demo-production data: application.yml: |- spring: profiles: production greeting: message: Say Hello to the Ops farewell: message: Say Goodbye To tell Spring Boot which profile should be enabled see the Spring Boot documentation.
One option for activating a specific profile when deploying to Kubernetes is to launch your Spring Boot application with an environment variable that you can define in the PodSpec at the container specification.
Deployment resource file, as follows: apiVersion: apps/v1 kind: Deployment metadata: name: deployment-name labels: app: deployment-name spec: replicas: 1 selector: matchLabels: app: deployment-name template: metadata: labels: app: deployment-name spec: containers: - name: container-name image: your-image env: - name: SPRING_PROFILES_ACTIVE value: "development" You could run into a situation where there are multiple configs maps that have the same property names.
For example: kind: ConfigMap apiVersion: v1 metadata: name: config-map-one data: application.yml: |- greeting: message: Say Hello from one and kind: ConfigMap apiVersion: v1 metadata: name: config-map-two data: application.yml: |- greeting: message: Say Hello from two Depending on the order in which you place these in bootstrap.yaml|properties , you might end up with an un-expected result (the last config map wins). For example: spring: application: name: cloud-k8s-app cloud: kubernetes: config: namespace: default-namespace sources: - name: config-map-two - name: config-map-one will result in property greetings.message being Say Hello from one .
There is a way to change this default configuration by specifying useNameAsPrefix . For example: spring: application: name: with-prefix cloud: kubernetes: config: useNameAsPrefix: true namespace: default-namespace sources: - name: config-map-one useNameAsPrefix: false - name: config-map-two Such a configuration will result in two properties being generated: - greetings.message equal toSay Hello from one . - config-map-two.greetings.message equal toSay Hello from two Notice that spring.cloud.kubernetes.config.useNameAsPrefix has a lower priority than spring.cloud.kubernetes.config.sources.useNameAsPrefix .
This allows you to set a "default" strategy for all sources, at the same time allowing to override only a few. If using the config map name is not an option, you can specify a different strategy, called : explicitPrefix . Since this is an explicit prefix that you select, it can only be supplied to the sources level. At the same time it has a higher priority than useNameAsPrefix .
Let’s suppose we have a third config map with these entries: kind: ConfigMap apiVersion: v1 metadata: name: config-map-three data: application.yml: |- greeting: message: Say Hello from three A configuration like the one below: spring: application: name: with-prefix cloud: kubernetes: config: useNameAsPrefix: true namespace: default-namespace sources: - name: config-map-one useNameAsPrefix: false - name: config-map-two explicitPrefix: two - name: config-map-three will result in three properties being generated: - greetings.message equal toSay Hello from one . - two.greetings.message equal toSay Hello from two . - config-map-three.greetings.message equal toSay Hello from three .
The same way you configure a prefix for configmaps, you can do it for secrets also; both for secrets that are based on name and the ones based on labels. For example: spring: application: name: prefix-based-secrets cloud: kubernetes: secrets: enabled: true useNameAsPrefix: true namespace: spring-k8s sources: - labels: letter: a useNameAsPrefix: false - labels: letter: b explicitPrefix: two - labels: letter: c - labels: letter: d useNameAsPrefix: true - name: my-secret The same processing rules apply when generating property source as for config maps.
The only difference is that potentially, looking up secrets by labels can mean that we find more than one source. In such a case, prefix (if specified via useNameAsPrefix ) will be the name of the secret found for those particular labels. One more thing to bear in mind is that we support prefix per secret.
The easiest way to explain this is via an example: spring: application: name: prefix-based-secrets cloud: kubernetes: secrets: enabled: true useNameAsPrefix: true namespace: spring-k8s sources: - labels: color: blue useNameAsPrefix: true Suppose that a query matching such a label will return two secrets as a result: secretA and secretB . Both of these secrets have the same property name: color=sea-blue and color=ocean-blue .
Because useNamesAsPrefix=true , there will be two property sources loaded: - secretA.color=sea-blue - secretB.color=ocean-blue By default, besides reading the config map that is specified in the sources configuration, Spring will also try to read all properties from "profile aware" sources. The easiest way to explain this is via an example.
Let’s suppose your application enables a profile called "dev" and you have a configuration like the one below: spring: application: name: spring-k8s cloud: kubernetes: config: namespace: default-namespace sources: - name: config-map-one Besides reading the config-map-one , Spring will also try to read config-map-one-dev ; in this particular order. Each active profile generates such a profile aware configmap.
You can disable this "profile based sources" and then config-map-one-dev will not be attempted: spring: application: name: spring-k8s cloud: kubernetes: config: includeProfileSpecificSources: false namespace: default-namespace sources: - name: config-map-one includeProfileSpecificSources: false Notice that just like before, there are two levels where you can specify this property: for all config maps or for individual ones; the latter having a higher priority. In some cases, your application may be unable to load some of your ConfigMaps using the Kubernetes API.
If you want your application to fail the start-up process in such cases, you can set spring.cloud.kubernetes.config.fail-fast=true to make the application start-up fail with an Exception. You can also make your application retry loading ConfigMap property sources on a failure. First, you need to set spring.cloud.kubernetes.config.fail-fast=true . Then you need to add spring-retry and spring-boot-starter-aspectj to your classpath. You can configure retry properties such as the maximum number of attempts, backoff options like initial interval, multiplier, max interval by setting the spring.cloud.kubernetes.config.retry.* properties.
People Also Asked
- Spring@PropertySourceusingYAML-StackOverflow
- PropertySourcewithYAMLFiles inSpringBoot | Baeldung
- Use@PropertySourcewithYAMLfiles
- Usinga ConfigMapPropertySource::SpringCloud Kubernetes
- SpringBoot: How to Split application.yml into MultipleYAMLFiles...
- Why i cannot load property pojousingyamlinspringboot
- Topyamlfile examplespringboot Outlet Managing... | mcphilspr.com
- Springboot application yml example - w2n.jp
Spring@PropertySourceusingYAML-StackOverflow?
Let’s suppose that spring.application.name=my-app and that we have a single active profile called k8s . For a configuration as below: kind: ConfigMap apiVersion: v1 metadata: name: my-app data: my-app.yaml: |- ... my-app-k8s.yaml: |- .. my-app-dev.yaml: |- .. not-my-app.yaml: |- ..
PropertySourcewithYAMLFiles inSpringBoot | Baeldung?
pool.size.core - pool.size.maximum This can be externalized to config map in yaml format as follows: kind: ConfigMap apiVersion: v1 metadata: name: demo data: pool.size.core: 1 pool.size.max: 16 Individual properties work fine for most cases. However, sometimes, embedded yaml is more convenient.
Use@PropertySourcewithYAMLfiles?
This allows you to set a "default" strategy for all sources, at the same time allowing to override only a few. If using the config map name is not an option, you can specify a different strategy, called : explicitPrefix . Since this is an explicit prefix that you select, it can only be supplied to the sources level. At the same time it has a higher priority than useNameAsPrefix .
Usinga ConfigMapPropertySource::SpringCloud Kubernetes?
The default behavior is to create a Fabric8ConfigMapPropertySource (or a KubernetesClientConfigMapPropertySource ) based on a Kubernetes ConfigMap that has metadata.name of either: - value of spring.cloud.kubernetes.config.name - value of your Spring application (as defined by spring.application.name property) - the String literal "application" However, more advanced configuration is possible wher...
SpringBoot: How to Split application.yml into MultipleYAMLFiles...?
You can provide different property values for different profiles by using an application.properties or application.yaml property, specifying profile-specific values, each in their own document (indicated by the --- sequence), as follows: kind: ConfigMap apiVersion: v1 metadata: name: demo data: application.yml: |- greeting: message: Say Hello to the World farewell: message: Say Goodbye --- spring:...