Q:

Accessing VCAP properties on PCF Spring Boot app

I have a simple Spring Boot app running on PCF. I am wondering if there is a better way to access VCAP environment variables from PCF. Specifically, I am trying to access service credentials for a RabbitMQ service instance running on PCF and bound to my application.
At the moment, I access the credentials using System.getenv:
JSONObject vcapServices = new JSONObject(System.getenv("VCAP_SERVICES"));
JSONArray rabbitmq = (JSONArray) vcapServices.get("p-rabbitmq");
JSONObject serviceInfo = (JSONObject) rabbitmq.get(0);
JSONObject credentials = (JSONObject) serviceInfo.get("credentials");

hostname = credentials.getString("hostname");
virtualHost = credentials.getString("vhost");
username = credentials.getString("username");
password = credentials.getString("password");

I was trying to get it working with the @Value annotation to try to access the VCAP environment variables like this:
@Value("${vcap.services.p-rabbitmq.credentials.hostname}")
private String hostname;

but I haven't been able to grab the values yet.
Is there any way I can access VCAP variables via the @Value annotation? Or is there a better way other than System.getenv to get these credentials from PCF once I deploy my application?

A:

Is there any way I can access VCAP variables via the @Value annotation?

Yes, I think you need to change your format slightly. It's vcap.services.<service-instance-name>.credentials.hostname. You have the name of the service provider itself, not the name of your service instance. I can't see that name in the example above, but I've found the Javadoc to be helpful. It lists the following example.
VCAP_SERVICES: {
    "rds-mysql-1.0": [
        {
            "credentials": {
                "host": "mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com",
                "hostname": "mysql-service-public.clqg2e2w3ecf.us-east-1.rds.amazonaws.com",
                "name": "d04fb13d27d964c62b267bbba1cffb9da",
                "password": "pxLsGVpsC9A5S",
                "port": 3306,
                "user": "urpRuqTf8Cpe6",
                "username": "urpRuqTf8Cpe6"
            },
            "label": "rds-mysql-1.0",
            "name": "mysql",
            "plan": "10mb"
        }
    ]
}

In this example, the service provider name is "rds-mysql-1.0", which would be the same as "p-rabbitmq" in your example. It then has a service instance name of "mysql" & that is what you'd use in your property placeholder.
Ex: vcap.services.mysql.credentials.host
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/cloud/CloudFoundryVcapEnvironmentPostProcessor.html
Having explained all that, it can still be a fair bit of work to wire up all of your properties. Especially if you're utilizing multiple services or in your case, you're using RabbitMQ which has a lot of info that is passed through VCAP_SERVICES.
Another option to consider is Spring Cloud Connectors. This is a library that will basically handle all of this for you. You ask for a DataSource or ConnectionFactory and it makes sure one is wired into your application.
Ex:
@Bean
public RabbitConnectionFactory rabbitFactory() {
    return connectionFactory().rabbitConnectionFactory();
}

See Getting Started if you're interested in checking this out.

