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

March 15, 2012 Thomas Risberg

featured-cf-genericThe 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

About the Author

Biography

Previous
Same Pivotal, Increased Velocity
Same Pivotal, Increased Velocity

Looks like the word is out. We'll have more news on Tuesday but we want you to know we're excited about the...

Next
Centering a View within a ScrollView
Centering a View within a ScrollView

We have a View that we want centered on the screen, but that must scroll when there isn't enough room to sh...