spring.profiles is not working as expected in spring boot - spring-boot

boot config *.yml file.
server.port: 2222
spring:
application:
name: x-service
data:
mongodb:
host: db.x
database: x
# userName: ${db.userName}
# password: ${db.password}
rabbitmq:
# port: ${queue.port}
host: queue.x
username: ${queue.userName}
password: ${queue.password}
listener:
max-concurrency: 1
prefetch: 1
acknowledge-mode: auto
auto-startup: true
dynamic: true
###########DEV##############
spring.profiles: dev
#queue.virtual.host: xuser
queue.userName: guest
queue.password: guest
queue.port: 5672
#db.userName:
#db.password:
falconUrl: http://x.y.com
##########DEFAULT###########
spring.profiles: qa
queue.virtual.host: xuser
queue.userName: xuser
queue.password: xpassword
queue.port: 3456
db.userName: xuser
db.password: xpassword
falconUrl: http://x.z.com
It gives me org.yaml.snakeyaml.parser.ParserException: while parsing MappingNode
in 'reader', line 1, column 1:
server.port: 2222
^
Duplicate key: spring.profiles
in 'reader', line 47, column 1:
error. If I comment properties of one of the profile.It works fine.
Can anyone please suggest what is wrong here?

The error message is actually quite specific and accurate: in the top-level mapping of your YAML file (the one starting with the key-value pair server.port and 2222 you have two identical keys (the scalar spring.profiles). And duplicate keys are not allowed in YAML, as the are required to be unique according to the specification.
The underlying problem is that if you want to change the configuration depending on the environment, you'll have to follow the documented specification, which states that:
A YAML file is actually a sequence of documents separated by --- lines, and each document is parsed separately to a flattened map.
If a YAML document contains a spring.profiles key, then the profiles value (comma-separated list of profiles) is fed into the Spring Environment.acceptsProfiles() and if any of those profiles is active that document is included in the final merge (otherwise not)
Your YAML file is a single implicit YAML document because it lacks the directive indicator --- that occurs at the beginning of an explicit YAML document. (the YAML directive ... that indicates end-of-document might not be supported properly supported by snake-yaml, at least it is not mentioned in the examples).
Your code should look like:
server.port: 2222
spring:
application:
name: x-service
data:
mongodb:
host: db.x
database: x
# userName: ${db.userName}
# password: ${db.password}
rabbitmq:
# port: ${queue.port}
host: queue.x
username: ${queue.userName}
password: ${queue.password}
listener:
max-concurrency: 1
prefetch: 1
acknowledge-mode: auto
auto-startup: true
dynamic: true
###########DEV##############
---
spring.profiles: dev
#queue.virtual.host: xuser
queue.userName: guest
queue.password: guest
queue.port: 5672
#db.userName:
#db.password:
falconUrl: http://x.y.com
##########DEFAULT###########
---
spring.profiles: qa
queue.virtual.host: xuser
queue.userName: xuser
queue.password: xpassword
queue.port: 3456
db.userName: xuser
db.password: xpassword
falconUrl: http://x.z.com
The statement in the documentation that "each document is parsed separately to a flattened map" is of course only true, if each of the documents has a mapping at the top level. That is what spring-boot expects, but you can as easily have a scalar or sequence at the top level of a document, and such documents are certainly not parsed by snake-yaml to a flattened map.

Related

After upgrading SpringBoot 2.5.3, replacing spring.datasource. Schema to spring.sql.init.schema-locations is failed

How do I use spring.sql.init.schema-locations
Spring-boot version 2.5.3 failed
my spring.sql.inti.schema-locations and spring.datasource.schema
spring:
sql:
init:
schema-locations: classpath:sql/create_table_h2.sql
main:
lazy-initialization: true # 开启懒加载,加快速度
banner-mode: off # 单元测试,禁用 Banner
# 数据源配置项
datasource:
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;DB_CLOSE_DELAY=-1 # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
driver-class-name: org.h2.Driver
username: sa
password:
druid:
async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
initial-size: 1 # 单元测试,配置为 1,提升启动速度
# schema: classpath:sql/create_table_h2.sql
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
host: 127.0.0.1 # 地址
port: 16379 # 端口(单元测试,使用 16379 端口)
database: 0 # 数据库索引
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
# 不支持多包, 如有需要可在注解配置 或 提升扫包等级
# 例如 com.**.**.mapper
mapperPackage: com.ruoyi.**.mapper
# 对应的 XML 文件位置
mapperLocations: classpath*:mapper/**/*Mapper.xml
# 实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.ruoyi.**.domain
spring-boot version 2.4.10 succeeded
spring.datasource.schema = classpath:sql/create_table_h2.sql
I think some other related factors may interfere with the project, or you can try to lower the version, which may be the best way. In projects with new features, I prefer to use spring-boot, which may be more Good way to upgrade.

YAML ERROR : mapping values are not allowed

I am trying to build a yaml file but I am getting mapping not allowed error.
name: n1
version: "testv1"
description: n1
icon: n1.png
roles: [postgres]
postgres:
   name: postgreSQL database
   image:
       name: "r/k/postgres/"
       version: "testv1"
       engine: docker
   compute:
       memory: 2G
       cpu:
           reserve: false
           cores: 2
   storage:
       - type: data1
         media: hdd
         path: /var/lib/postgresql/data/pgdata
size: 30G
count: 1
fixed: true
service_ports: [5432]
env:
POSTGRES_PASSWORD:
type: password
value: "postgres"
POSTGRES_DB: postgres
POSTGRES_USER: postgres
(): mapping values are not allowed in this context at line 21 column 14
I cant understand the error on line : size: 30G
Try adding double quotes to the following:
path: "/var/lib/postgresql/data/pgdata"
Also, indentation of keys in the map should be exactly same. Try seeing that the indentation is correct. So, for example, if you are using 3 spaces to indent a key, then every key should be indented with 3 spaces only.

Rule governing sequence of fields in a YAML

Checking the validity of a YAML using https://onlineyamltools.com/convert-yaml-to-json
The below YAML is correct
# Valid yaml (field "name" placed at LAST position)
match:
- uri:
prefix: "/mysvc1/"
route:
- destination:
host: myservice1
port:
number: 80
name: "svc1-routes"
However, if I move the field name to first position, the YAML becomes invalid. What is the reason?
# Invalid yaml (field "name" placed at FIRST position)
match:
name: "svc1-routes" # <---- ERROR ----
- uri:
prefix: "/mysvc1/"
route:
- destination:
host: myservice1
port:
number: 80
The error message:
Error: YAMLException: end of the stream or a document separator is expected at line 4, column 1:
- uri:
^
In contrary to your comment, name and match are on the same level because they share the same indentation. name is in no way nested in match (nor is route).
The list items, however, are nested in match since YAML understands the - as parts of the indentation, hence the list items are considered more indented than match and are thus nested in it.
Concerning your error:
name: "svc1-routes"
- uri:
In this part, the mapping key name is assigned the scalar value svc1-routes. Each mapping key may only have one value. On the next line, a sequence starts which is on a deeper indentation level (as explained above) but YAML can't put it anywhere because the key name already has a value. This is why it issues an error.
You can freely switch the mapping keys together with their nested values, e.g.:
route:
- destination:
host: myservice1
port:
number: 80
name: "svc1-routes"
match:
- uri:
prefix: "/mysvc1/"
This will load to the same structure as per YAML spec.

How to read YAML in list of Strings

I have a YAML file for my Spring app. It looks like this:
storages:
file:
local:
dir: file_storage
http:
local_host:
url: http:*************
client_id: *****
secret_id: ******t
ftp:
ftp_server:
path: ***********e
catalogues:
database:
local_database:
host: jdbc:postgresql://l*****st:5432/ea******
user: ***
password: ***
driver: org.postgresql.Driver
maximum_pool_size: 3
http:
local_rest:
url: http://localhost:1234/data
aliases:
default_file_storage: local
default_catalog: local_database
a9c8662e-f4bc-4e8e-882d-310bf8e86198: local_database
admin_catalog: local_database
admin_storage : local
And I need this data as strings in application.properties. I download my properties from external storage at S3 from amazon. These files can be application.properties format or .yml format
storages.file.local.dir=file_storage
storages.http. local_host.url=http:*************
storages.http. local_host.client_id=http:*************
storages.http. local_host.secret_id=http:*************
and so on.

Cloud Foundry yaml parse error

I'm getting an error on cf push when I try to push a yaml file for a memcached service broker:
#cf push
FAILED
Error reading manifest file:
yaml: [] mapping values are not allowed in this context at line 2, column 7
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:95 (0x2c0d87)
/usr/local/go/src/pkg/runtime/panic.c:248 (0x16276)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:144 (0x2c1609)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:161 (0x2c17e5)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:471 (0x2c3cd4)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:196 (0x2c1c6e)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:394 (0x2c336d)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:193 (0x2c1d38)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:171 (0x2c199e)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/cloudfoundry-incubator/candiedyaml/decode.go:137 (0x2c146d)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/manifest/manifest_disk_repository.go:82 (0xb13ef)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/manifest/manifest_disk_repository.go:50 (0xb0f72)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/manifest/manifest_disk_repository.go:33 (0xb0e13)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/manifest/manifest.go:1 (0xb300e)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/commands/application/push.go:377 (0x23e2c3)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/commands/application/push.go:356 (0x23e062)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/commands/application/push.go:120 (0x23ada2)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/command_runner/runner.go:50 (0xa70a9)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/command_runner/runner.go:1 (0xa73d4)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/tmp/cli_gopath/src/github.com/cloudfoundry/cli/cf/app/app.go:76 (0x8ecce)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/codegangsta/cli/command.go:101 (0xcb140)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/Godeps/_workspace/src/github.com/codegangsta/cli/app.go:125 (0xc9654)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/main/main.go:154 (0x3729)
/Users/pivotal/go-agent/pipelines/Mac-OSX-Testing/src/github.com/cloudfoundry/cli/main/main.go:91 (0x2eb9)
/usr/local/go/src/pkg/runtime/proc.c:220 (0x1804f)
/usr/local/go/src/pkg/runtime/proc.c:1394 (0x1a580)
So obviously someethign is wrong with my yaml file. But I don't know what. Here's what I have:
domain: cloudeast.mycompany.com
nats: secret
machines:
- 10.10.100.10
password: secret
port: 4222
user: nats
networks:
apps: default
management: default
memcache_broker:
broker_password: secret
memcache:
vip: 10.100.100.100:11211
servers:
- 10.100.100.101:11211
- 10.100.100.102:11211
plans:
small:
name: small
description: A small cache with no redundency
free: true
memcache_hazelcast:
heap_size: 512M
host:
src_api: https://memcache-hazelcast.cf-deployment.com
password: secret
memcache:
secret_key: secret
hazelcast:
max_cache_size: 268435456
machines:
zone1:
- 10.100.100.101
zone2:
- 10.100.100.102
plans:
small:
backup: 0
async_backup: 1
eviction_policy: LRU
max_idle_seconds: 86400
max_size_used_heap: 100
medium:
backup: 0
async_backup: 1
eviction_policy: LRU
max_idle_seconds: 86400
max_size_used_heap: 200
Could I get some help with why this yaml file isn't parsing correctly?
On the first line you have a scalar (domain) followed by a colon (:) followed by a scalar (cloudeast.mycompany.com), this means at the top, non indented, level you start a mapping and domain is a key scalar and cloudeast.mycompany.com a value scalar.
On the next line you should, once more, have a key scalar and it has to be indented at the same level as the previous line (or you finish the top-level mapping with an end of stream (...) or start a new document (---). You start an indented value that is a mapping and the parser doesn't know what you want to do with that.
One can only try and guess what you try to do. If cloudeast.mycompany.com is the name of the domain, you should make that a new indented scalar value (with key name), then the same indentation error occurs for the key machines. and following 3 keys, after that the file is OK:
domain:
name: cloudeast.mycompany.com # scalar key "name" added
nats: secret
machines: # this scalar key and next 3 dedented
- 10.10.100.10
password: secret
port: 4222
user: nats
# from here everything as it was
networks:
apps: default
management: default
memcache_broker:
broker_password: secret
memcache:
vip: 10.100.100.100:11211
servers:
- 10.100.100.101:11211
- 10.100.100.102:11211
plans:
small:
name: small
description: A small cache with no redundency
free: true
memcache_hazelcast:
heap_size: 512M
host:
src_api: https://memcache-hazelcast.cf-deployment.com
password: secret
memcache:
secret_key: secret
hazelcast:
max_cache_size: 268435456
machines:
zone1:
- 10.100.100.101
zone2:
- 10.100.100.102
plans:
small:
backup: 0
async_backup: 1
eviction_policy: LRU
max_idle_seconds: 86400
max_size_used_heap: 100
medium:
backup: 0
async_backup: 1
eviction_policy: LRU
max_idle_seconds: 86400
max_size_used_heap: 200
Of course you also leave out the cloudeaset.mycompany.com value. In both the cases the top level of the YAML file will be a mapping with a single key scalar: domain. The value for that key is again a mapping with keys like nats, networks, memcache_broker

Resources