0

I have configured spring boot application to take properties from my environment but strangely I am facing an error while starting my application. I have added the properties in my ~/.bash_profile and also did source ~/.bash_profile after adding them to the profile.

This is how my bootstrap.properties look like:

spring.application.name=gamification
spring.cloud.vault.enabled=${VAULT_ENABLE:true}
spring.cloud.vault.fail-fast=false
spring.cloud.vault.token=${VAULT_TOKEN}
spring.cloud.vault.scheme=${VAULT_SCHEME}
spring.cloud.vault.host=${VAULT_HOST}
spring.cloud.vault.port=${VAULT_PORT:8200}

I am getting this error:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.vault.config.VaultReactiveBootstrapConfiguration]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Scheme must be http or https
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:216) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:310) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    ... 30 common frames omitted
Caused by: java.lang.IllegalArgumentException: Scheme must be http or https
    at org.springframework.util.Assert.isTrue(Assert.java:118) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    at org.springframework.vault.client.VaultEndpoint.setScheme(VaultEndpoint.java:167) ~[spring-vault-core-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.cloud.vault.config.VaultConfigurationUtil.createVaultEndpoint(VaultConfigurationUtil.java:91) ~[spring-cloud-vault-config-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at org.springframework.cloud.vault.config.VaultReactiveBootstrapConfiguration.<init>(VaultReactiveBootstrapConfiguration.java:110) ~[spring-cloud-vault-config-2.2.2.RELEASE.jar:2.2.2.RELEASE]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_231]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_231]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_231]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_231]
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:203) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
    ... 32 common frames omitted

I added a debug point in Vault Endpoint and found this: Here as you can see, the VAULT_HOST is being taken as VAULT_HOST instead of the value of that environment variable, and same with the VAULT_SCHEME

Here as you can see, the VAULT_HOST is being taken as VAULT_HOST instead of the value of that environment variable, and same with the VAULT_SCHEME

[EDIT] Adding bash_profile vault configuration:

export VAULT_ENABLE=true
export VAULT_SCHEME=http
export VAULT_HOST=vault-1.dev.lokal
export VAULT_PORT=8200
export VAULT_TOKEN=5F97X

[EDIT #2]

Tried out the solution suggested by @Gopinath I am getting environment as null when trying to autowire it I am getting environment as null when trying to autowire it

Karan Mehta
  • 53
  • 1
  • 15

2 Answers2

0

The root cause of the problem can be found form this error message:

org.springframework.core.convert.ConverterNotFoundException: 

No converter found capable of converting 
from type [java.lang.String] 
to type [org.springframework.cloud.vault.config.VaultProperties$Config]

The above message indicates that the VaultProperties object could not be initialized using the string parameter supplied.

Here is the link to documentation and instructions on configuring VaultProperties:

https://spring.io/guides/gs/vault-config/

Some more information to help understand vault:

References:

Spring Cloud Vault: https://cloud.spring.io/spring-cloud-vault/ Hashicorp Vault: https://www.vaultproject.io

What is a Vault?

A vault is a secure storage space meant for storing secret information. Hashicorp Vault is one tool that offers vault functionality for cloud applications.

What is Spring Boot Vault?

Spring Boot applications commonly require secret information for those to work. Some examples of secret information are:

  1. Database password
  2. Private key
  3. API key

Usually, the input parameters are passed to Spring boot application through the "application.properties" file or "bootstrap.properties" file. The use of such properties file poses a security risk, if secret data is directly mentioned in the file.

Spring Boot Vault addresses this risk. It pulls secret information from vault and supplies to the application at the start-up time.

The .properties file will only tell the application the names of parameters that it can expect from Vault. The actual values of the parameters will be taken from vault.

How to setup Vault?

Step 1: Install and launch HashiCorp Vault from https://www.vaultproject.io/downloads.html:

Step 2: After installing Vault, test whether it works, by launching it in a console window.

> vault server --dev --dev-root-token-id="spring-boot-vault-demo"

==> Vault server configuration:
    Api Address: http://127.0.0.1:8200
                         Cgo: disabled
             Cluster Address: https://127.0.0.1:8201
                  Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
                   Log Level: info
                       Mlock: supported: false, enabled: false
               Recovery Mode: false
                     Storage: inmem
                     Version: Vault v1.4.1

    WARNING! dev mode is enabled! 
    .....

    You may need to set the following environment variable:

    PowerShell:
        $env:VAULT_ADDR="http://127.0.0.1:8200"
    cmd.exe:
        set VAULT_ADDR=http://127.0.0.1:8200

    The unseal key and root token are displayed below in case you want to
    seal/unseal the Vault or re-authenticate.

    Unseal Key: +Dihvgj/oRN2zo6/97ZqpWt086/CFRZEPkuauDu4uQo=
    Root Token: spring-boot-vault-demo

Step 3: Store some secret data in the vault, by running these commands in a separate command window:

> set VAULT_ADDR=http://127.0.0.1:8200

> set VAULT_TOKEN=spring-boot-vault-demo

> vault kv put secret/spring-boot-vault-demo password=££££$$$$%%%%
    Key              Value
    ---              -----
    created_time     2020-05-02T09:59:41.2233332Z
    deletion_time    n/a
    destroyed        false
    version          1
Gopinath
  • 4,066
  • 1
  • 14
  • 16
  • I have added my bash_profile to provide more insight into the issue. Can't seem to find out why is the ConverterNotFoundException being thrown firsthand. – Karan Mehta May 01 '20 at 21:31
  • 1
    I corrected that error, it was because VAULT_CONFIG is something that is expected by a class as an Object of VaultProperties$Config. The error has been updated @Gopinath – Karan Mehta May 01 '20 at 22:38
  • Hi Karan, Can you try reading the variable by using the Environment object? I updated the answer with this information. – Gopinath May 01 '20 at 23:53
  • I am getting an NPE when trying to print it out to the console @Gopinath because the environment itself is coming as null. – Karan Mehta May 02 '20 at 00:04
  • Based on the above error, it appears that the problem is with the environment variables or with the vault service. Can you check if the vault service is running and that the port number (default = 8200) is not blocked? This reference example can help verify the settings: https://spring.io/guides/gs/vault-config/ – Gopinath May 02 '20 at 10:17
0

I did this: I made a shell script called setenv.sh and put this under it:

#!/bin/bash

launchctl setenv VAULT_ENABLE true
launchctl setenv VAULT_SCHEME http
launchctl setenv VAULT_HOST vault-1.dev.lokal
launchctl setenv VAULT_PORT 8200
launchctl setenv VAULT_TOKEN 5F97X

And then, before starting the application I ran the shell script with

sudo sh setenv.sh

And the application seems to work fine without any errors. Strangely if I do it with my previous approach of adding the env variables inside the .bash_profile, it doesn't work.

Karan Mehta
  • 53
  • 1
  • 15