简体   繁体   中英

Unable to retrieve credentials from user-provided in vcap_services in spring boot

My spring boot application is in PCF, since PCF doesnt have option to change properties file in run time, I was trying to put the values in PCF VCAP_SERVICES- user-provided credentials.

I tried using @ConfigurationProperties as per tutorial provided by pivotal and i got null exception.

@Data
@Configuration
@ConfigurationProperties("vcap.services.app-properties.credentials")
public class RsTest {
private String username;
private String password;
//getter and setter
};

and my controller looks like

@RestController
public class RestApiController {
@Autowired
RsTest rsTest;

public void test() {
logger.info("RSTest: "+rsTest.getUsername());
return ResponseEntity.ok().body("some value");
}

I'm expecting the credential in RsTest object. But having error Servlet.service() for servlet [dispatcherServlet] in context with path [/myservice] threw exception 2019-08-20T17:32:43.728-04:00 [APP/PROC/WEB/0] [OUT] java.lang.NullPointerException: null

Well, what you have should in theory work. It is a fragile approach to parsing config from VCAP_SERVICES though, and that's my guess as why you're having issues. The prefix for @ConfigurationProperties must be exactly correct for Spring to look up the value, and the prefix will depend on the name of the service you bind.

Spring Boot will map services bound to your app in the format: vcap.services.<service name>.credentials.<credential-key> . For details, see the docs here .

If you do not have the correct service instance name, then it will fail to bind to your config properties object.

Here's an example:

  1. I have a service named scheduler .
  2. It produces the following VCAP_SERVICES env variable:

     { "scheduler-for-pcf": [ { "binding_name": null, "credentials": { "api_endpoint": "https://scheduler.run.pivotal.io" }, "instance_name": "scheduler", "label": "scheduler-for-pcf", "name": "scheduler", "plan": "standard", "provider": null, "syslog_drain_url": null, "tags": [ "scheduler" ], "volume_mounts": [] } ] } 
  3. I can use the following class to read it's credentials.

     @Configuration @ConfigurationProperties(prefix = "vcap.services.scheduler.credentials") public class SchedulerConfig { private String api_endpoint; public String getApiEndpoint() { return api_endpoint; } public void setApiEndpoint(String api_endpoint) { this.api_endpoint = api_endpoint; } } 

If I changed the service name to fred , then the prefix would need to change to vcap.services.fred.credentials .


Having said all that, you should look at using java-cfenv instead. It's more flexible and is the recommended way to read VCAP_SERVICES in your Java apps (note - this replaces Spring Cloud Connectors).

For more details, read this blog post

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM