Skip to content

Reading VCAP_SERVICES in client side or nginx for proxying

Sabith edited this page Jan 12, 2016 · 2 revisions

Hi Folks

As per the new architecture, the developer has the control over how they talk to services,

Example : Seed app talking to Asset server , So the VCAP_SERVICES Looks something like this

"VCAP_SERVICES": {
  "predix-asset_ga": [
   {
    "credentials": {
     "uri": "http://predix-asset-ga.predix.com"
    },
    "label": "predix-asset_ga",
    "name": "predix_seed_asset_ga",
    "plan": "Basic_ga",
    "tags": []
   }
  ]
 }

At the end of this exercise, the users should be able to talk to the asset service.

Proxy using nginx.

For this the user has to have a location directive in their nginx configuration, something like this

    location /api/asset { 
         proxy_pass "<%= ENV["vcap_service_predix_seed_asset_ga_uri"] %>”; 
     }

The vcap_service_predix_seed_asset_ga_uri will be replaced by the url http://predix-asset-ga.predix.com

The format looks something like this vcap_service+service_name+credentials_key

The code that does this can be found at : https://github.com/muymoo/staticfile-buildpack/blob/61a59ac54e54fd3843747394e9324c5f7c411bb6/bin/get_env

PR: https://github.com/muymoo/staticfile-buildpack/pull/4

As of now , only alphanumeric character and underscores are allowed in the service names.

This is recommended for Auth-Code flow type of Authorization

Read on the client side.

For this the developer will have to have a location directive on nginx that can serve the URI’s as a JSON and then read the JSON using JS

    location routes.json {    # Could be replaced with any route of developer's choice
        default_type 'application/json';
            return '{"asset-url": "<%= ENV["vcap_service_predix_seed_asset_ga_uri"] %>"}';
        }

Here the developer, will have to make a AJAX request to routes.json and then get a hold of the asset-url, The idea being the same as the first one , but this gets the uri to the client side.

This is recommended for Implicit Grant flow type of Authorization. (Talking to Asset through CORS)

What to use instead of cf-routes.js ?

We understand that most of the team were relying on the /cf-routes.js so as to get the VCAP_SERVICES uri's. So, how does this work with the new build pack ?

Here is a my take on how to.

  1. Add the following configuration in nginx.conf

     location /cf-routes {
         default_type 'application/json';
         return 200 '<%= ENV["VCAP_SERVICES"] %>';
     }
    
  2. in app.js, Add routes.json to requirejs dependency

     define([
      'json!../cf-routes', 
      'jquery',
      'angular'
     ], function(VCAP_SERVICES, $, angular){
    
             var predixApp = angular.module('predixApp', ['app.routes','app.interceptors']);
             
             ...
    
             var routes = {};
             for (var serviceId in VCAP_SERVICES) {
                 var service = VCAP_SERVICES[serviceId];
                 for (var instanceIndex in service) {
                     var instance = service[instanceIndex];
                     if(! instance.credentials.uri){
                         continue;
                     }
                     if(instance.credentials.uri.match(/^http/)){
                         routes[instance.name] = instance.credentials.uri;
                     }else{
                         routes[instance.name] = location.protocol + '//' + instance.credentials.uri;
                     }
                 }
             }
    
             predixApp.constant('VCAP_SERVICES', routes);
    
             ....
       });
    
  3. For local development, add routes.json with the following content

{
        "View Service Free": [
            {
                "credentials": {
                    "uri": "dev-dashboard-server.predix.com"
                },
                "label": "View Service Free",
                "name": "viewPersistenceService",
                "plan": "Free View Service",
                "syslog_drain_url": "",
                "tags": []
            }
        ],
        "predix-asset": [
            {
                "credentials": {
                    "uri": "predix-asset-mvp2-seed-app.predix.com"
                },
                "label": "predix-asset",
                "name": "predixAssetExp2",
                "plan": "Basic",
                "tags": []
            }
        ]
    }

This code is a made up code, but the basic idea is something like this, expose the VCAP_SERVICE as a route and read the value with requireJS dependency

I hope you get the picture, Please feel free to get back incase I confused you or if you feel I should shed more lights in some particular area.