The Cloud Foundry Blog

Using Cloud Foundry Services with Ruby: Part 2 – Run-time Support for Ruby Applications

The services offered in Cloud Foundry are necessary for writing any serious application. Our aim is to make it easy to configure and consume these services. In addition to the auto-reconfiguration described in the Using Cloud Foundry Services with Ruby: Part 1 – Auto-reconfiguration blog post we also have support for manual service property lookup as well as library calls to obtain a pre-configured connection object.

Library call to obtain client object

For each supported service type there are corresponding library calls to obtain a pre-configured client object. This makes it easy to use in your code since you don’t have to lookup connection properties, instead you can rely on the library to do the work for you. Here are some examples for the supported service types:

  • Relational database (PostgreSQL)
 require 'cfruntime/postgres' client = CFRuntime::PGClient.create_from_svc('postgres-test') ... 
  • Relational database (MySQL)
 require 'cfruntime/mysql' client = CFRuntime::Mysql2Client.create_from_svc('mysql-test') ... 
  • Document database (MongoDB)
 require 'cfruntime/mongodb' connection = CFRuntime::MongoClient.create_from_svc('mongo-test') db = connection.db ... 
  • Key-Value store (Redis)
 require 'cfruntime/redis' client = CFRuntime::RedisClient.create_from_svc('redis-test') ... 
  • AMQP Client
 require 'cfruntime/amqp' client = CFRuntime::AMQPClient.create_from_svc('rabbit-test') ... 
  • Carrot
 require 'cfruntime/carrot' client = CFRuntime::CarrotClient.create_from_svc('rabbit-test') ... 

These library calls all use the “create_from_svc” method where you need to specify the name of the service you are connecting to. If you only have a single service of a specific type bound to the app, then you can omit the service name and use the “create” method instead. You can also provide connection parameters that can be used for local testing. This can be done using a rescue clause since the cloud connection method throws an exception if a cloud service can’t be located. The following is an example of using the “create” method to connect to a single MongoDB service bound to the app with an added rescue clause to provide a localhost db connection for running locally.

 
require 'cfruntime/mongodb' 
... 
db = (CFRuntime::MongoClient.create.db rescue Mongo::Connection.new("localhost", 27017).db("db")) 
... 

The following table shows the available methods and parameters for each service type:

Service Type Returns Method Signatures Comment
PostgreSQL PGConn instance CFRuntime::PGClient.create([options]) options parameter is an optional hash of connection settings to be passed to the PostgreSQL client
CFRuntime::PGClient.create_from_svc (service_name, [options]) service_name is the name of a service bound to the app, options parameter is an optional hash of connection settings to be passed to the PostgreSQL client
MySQL Mysql2 Client instance CFRuntime::Mysql2Client.create([options]) options parameter is an optional hash of connection settings to be passed to the MySQL client
CFRuntime::Mysql2Client.create_from_svc (service_name, [options]) service_name is the name of a service bound to the app, options parameter is an optional hash of connection settings to be passed to the MySQL client
MongoDB Mongo Connection proxy* CFRuntime::MongoClient.create([options]) options parameter is an optional hash of connection settings to be passed to the Mongo client
CFRuntime::MongoClient.create_from_svc (service_name, [options]) service_name is the name of a service bound to the app, options parameter is an optional hash of connection settings to be passed to the Mongo client
Redis Redis instance CFRuntime::RedisClient.create([options]) options parameter is an optional hash of connection settings to be passed to the Redis client
CFRuntime::RedisClient.create_from_svc (service_name, [options]) service_name is the name of a service bound to the app, options parameter is an optional hash of connection settings to be passed to the Redis client
RabbitMQ AMQP Client instance CFRuntime::AMQPClient.create([options]) options parameter is an optional hash of connection settings to be passed to the AMQP client
CFRuntime::AMQPClient.create_from_svc (service_name, [options]) service_name is the name of a service bound to the app, options parameter is an optional hash of connection settings to be passed to the AMQP client
RabbitMQ Carrot instance CFRuntime::CarrotClient.create([options]) options parameter is an optional hash of connection settings to be passed to the Carrot client
CFRuntime::CarrotClient.create_from_svc (service_name, [options]) service_name is the name of a service bound to the app, options parameter is an optional hash of connection settings to be passed to the Carrot client
  • The proxy returned for the MongoDB Connection has a no-argument ‘db’ method to get access to the DB object for the database created for the CloudFoundry service.

Service configuration properties lookup

For applications where you want more control, we provide a service configuration properties look-up library. To use this, you can programmatically check whether you are running in a cloud environment, and then use the library to look up a service specific properties needed for manual connection configuration. What services are supported and what properties are exposed for these services? All services have the following properties provided in a hash:

  • :label
  • :version
  • :name
  • :username
  • :password
  • :host
  • :port Each supported service also provides the following properties:

  • Relational database (PostgreSQL, MySQL)

    • :database – the name of the database
  • Document database (MongoDB)
    • :db – the name of the database
  • Key-Value store (Redis)
    • no additional properties
  • Messaging (RabbitMQ)
    • :url – the connection URL Here is a brief MongoDB example:
 
require 'cfruntime/properties' 
if CFRuntime::CloudApp.running_in_cloud? 
  @service_props = CFRuntime::CloudApp.service_props('myservice') 
else 
  @service_props = {} 
  @service_props[:host] = 'localhost' 
  @service_props[:port] = 27017 
  @service_props[:db] = 'testdb' 
end 
db = Mongo::Connection.new(@service_props[:host], @service_props[:port]).db(@service_props[:db]) 
if CFRuntime::CloudApp.running_in_cloud? 
  db.authenticate(@service_props[:username], @service_props[:password]) 
end

Conclusion

In the previous blog post, you learned about Ruby auto-reconfiguration, and in this post we have covered manual configuration. We are pleased to offer these two new approaches to make it even easier to connect to Cloud Foundry services from your Ruby applications. Please feel free to send us any feedback via the Cloud Foundry Support Forums.

- Thomas Risberg The Cloud Foundry Team
Don’t have a Cloud Foundry account yet?  Sign up for free today

This entry was posted in CloudFoundry. Bookmark the permalink.

7 Responses to Using Cloud Foundry Services with Ruby: Part 2 – Run-time Support for Ruby Applications

  1. Pingback: Cloud Foundry Further Improves Support for Ruby Applications | Blog

  2. Why did you go with a class-based system like:

    CFRuntime::PGClient.create_from_svc (service_name, [options])

    Instead of something more rubyish like:

    CFRuntime.create_from_svc(:pg, service_name, [options])

    Having typed that out, I guess it should be a simple pull request to allow the alternate syntax.

    Where is the source?

  3. Ben Langfeld says:

    Why not just allow grabbing a service’s URI (eg mysql://user:password@host:port/database_name) from an environment variable? That does away with the entire contents of this post and makes my application nicely portable.

  4. Pingback: Deploying JRuby on Rails Applications on Cloud Foundry | Blog

  5. Pingback: Using JRuby for Rails Applications on Cloud Foundry | Blog

  6. Pingback: Cloud Foundry Improves Support For Background Processing | Blog

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>