Cloud Foundry Blog

Multi-Language, Multi-Framework, what about Multi-Cloud?

Previously, developers had to put a lot of energy into preserving choice across operating systems and minimizing hard dependencies on specific operating systems.  In the cloud era, there is a similar challenge to preserve choice across clouds and minimize dependencies on specific clouds.

Most PaaS solutions today force you to write your application to that specific PaaS and that is where your app will stay, much like writing to an OS.  It sits on a public cloud somewhere and cannot be moved without recoding and dependency swaps.  In extreme cases, you as a developer are still directly tied to the constraints of the infrastructure.

Limiting yourself to a single cloud instance restricts your flexibility now and in the future. You may want to move from private to public cloud, or vice versa.  You may want to change from one public cloud provider to another or maybe you are dissatisfied with the pricing or reliability from a particular provider.  Geographic market expansion or compliance needs may push you to new clouds.  Building and deploying applications to clouds that have a proprietary deployment and/or technology stack will impede your cloud flexibility.  You want to preserve your “Multi-Cloud” ability.

Cloud Foundry gives you the ability to make your application Multi-Cloud by allowing you to write your application once and deploy it to any Cloud Foundry instance, be it public or private or even on to Micro Clouds.

The Cloud Foundry eco-system has grown a great deal in the last 9 months.  There are now multiple public clouds based on Cloud Foundry and several private cloud deployment options that rely on Cloud Foundry.  In addition, we also offer Micro Cloud Foundry (Cloud Foundry in a VM).  All of these options have the ability to take the same Java, Ruby, or other code and deploy an application without modification.

How does Cloud Foundry achieve Multi-Cloud Application Portability?

There are several technologies at work to make Multi-Cloud a reality.

DEAs – The Dynamic Execution Agents operate as independent entities that carry out requests made by the Cloud Controller.  By being independent, DEAs provide a place for the Application to run without the application being aware of where it is executing (like in a traditional OS).
Service Gateways – Provide a common/uniform way of exposing Services (Databases, Message Queues, Stores, etc.) to the Applications running on the DEAs.  By presenting services in a common and uniform way to a running application, it becomes more easily portable.
Environmental Variables – The last portion to make applications portable is to provide credentials for services in a standard way to all application runtimes.  In all Cloud Foundry implementations, this is done by injecting a JSON document as an environment variable that lists all bound services and their credentials to the Application.  Once a developer has written their code to leverage this (either by parsing the JSON themselves or by leveraging a framework feature such as Spring 3.1 Profiles, the application can be run on any instance of Cloud Foundry without modification to any of the code.

Below is a 5 Minute video showing a Multi-Cloud Deployment to 5 different Cloud Foundry based Clouds

Multi-Cloud using Cloud Foundry – The Demo

(For the fully detailed 13 minute version, click here)

Steve Herrod, VMware’s Chief Technology Officer further discusses the advantages of the Multi Cloud approach to PaaS in the following blog post.

Watch a short flash video – “Multi-Cloud and Proud

-The Cloud Foundry Team

Don’t have a Cloud Foundry account yet?  Sign up for free today

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

node.js and Cloud Foundry

Cloud Foundry is a sponsor and participant in this week’s Node Summit in San Francisco, so it is a good time to recap some of our work with node.js.

We’re finalizing node.js 0.6.7 support, which will be committed to the Cloud Foundry GitHub repository.  Cloud Foundry.com will begin to support node.js 0.6.7 as a runtime framework in the next week or two.  Because of the rapid pace of innovation around node, we are adding node.js 0.6.7 as an additional runtime, letting you select which version of node you want to run with your application.  This lets Cloud Foundry support multiple node.js versions simultaneously, which is important as it allows applications written against the node.js 0.4.12 version to co-exist with applications developed on node.js 0.6.7.

This work represents the first fruits of our partnership with Joyent, who is the Cloud Foundry Community Lead for node.js.  Going forward, we will have a joint open source engineering model with Joyent that lets the Cloud Foundry, node.js, and Redis teams all work together to deliver a highly optimized PaaS solution across those components.

The next few months should be big for node.js and the community around it.  Modern applications are becoming more demanding, diverse, and complex.  We see node.js as a great fit in addressing many of the problems posed by this.  A few examples of the efforts going into leveraging node.js with Cloud Foundry are covered in the links below.

- The Cloud Foundry Team

Don’t have a Cloud Foundry account yet?  Sign up for free today

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Java Reporting Engine is Now Available on Cloud Foundry via JasperReports

The popular Java reporting engine from JasperSoft is now available as a Cloud Foundry package. With two simple commands developers can make JasperReports Server available on Cloud Foundry and build powerful reports querying  Cloud Foundry data services.  Deploying  JasperReport server using the Cloud Foundry command line tool (‘VMC’) is as simple as ‘vmc push’ and  ‘vmc bind-service’.

Cloud Foundry is a strategic platform for many users . As more applications get deployed to Cloud Foundry open PaaS, more developers will find the need to perform reporting and analysis (Business Intelligence) on the data that they are gathering. You could write your own reporting features… but that’s a lot of work, and it’s generally not your core strength. It makes sense to focus on improving your own application, and then embed analysis and reporting features.

With that in mind, we wanted to make JasperReports Server available on Cloud Foundry. It’s a logical extension for the most widely used Business Intelligence solution to move into the PaaS world.

The accompanying video shows how to configure and install JasperReports Server on Cloud Foundry.  We will review the steps in the details of the sections below.

By default, JasperReports Server (JRS) requires a JNDI connection to a database to hold its metadata repository. Normally it’s defined like this in applicationContext-webapp.xml:

<!-- define datasource for repository -->
<bean id="dataSource">
<property name="jndiName" value="java:comp/env/${metadata.hibernate.dataSource.jndiName}"/>
</bean>

While JNDI is not supported on Cloud Foundry, the standard Spring DataSource is available. So the change was relatively simple:

<!-- define datasource for repository -->
<cloud:properties id="cloudProperties"/>

<bean id="dataSource"
destroy-method="close">
<property name="driverClassName" value="${db.driverClassName}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>

There are a few additional details around creating and referencing a new file called data-services.properties which contains the values for connecting to the repository database. We had to reference this file in applicationContext-webapp.xml:

<!-- pull in properties -->
<bean id="propertyConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/hibernate.properties</value>
<value>/WEB-INF/data-services.properties&lt;/value><!-- Added for CloudFoundry support -->
</list>
</property>
<property name="properties" ref="cloudProperties"/><!-- Added for CloudFoundry support -->
<property name="localOverride" value="true"/><!-- Added for CloudFoundry support -->
</bean>

The file data-services.properties contains a mix of static default values and values that are populated dynamically by Cloud Foundry. For example, a developer is free to modify the name of the JasperReports Server repository database, but by default we assume it will be called “jrs-repo”. On the other hand, the connection information is dynamically generated when the application is deployed. Here are a few lines from the file:

serviceName=jrs-repo
db.name=${cloud.services.${serviceName}.connection.name}
db.url=jdbc:${serviceType}://${db.host}:${db.port}/${db.name}
db.username=${cloud.services.${serviceName}.connection.username}

After making this modification to get connected to the database, we needed to populate it. When using JasperReports Server in a standard on-premises situation, we would run a script that creates and populates the database. When deploying to Cloud Foundry we don’t have quite the same options. “Caldecott”, a new feature that allows developers to open a tunnel to any Cloud Foundry data service via a local port, is beginning to change this. But to fit into the PaaS world seamlessly, it makes more sense to have our application “bootstrap” the repository. Rather than assuming that the repository is already appropriately populated, we instead test on startup. If the required repository tables don’t exist, then we create them. This was the most significant change we made to our application, but it’s a feature that would make life easier for customers deploying on-premises as well. We plan to migrate this feature into our core product.

With these two changes in place, we were able to push the application up to Cloud Foundry and have it automatically configure itself and start working. But there was still one important piece to add.

The most common data source that a user needs for BI is a SQL data source. A connection to the database is normally created either by adding a JNDI data source or by defining a JDBC data source directly in the JasperReports Server user interface. But JNDI is not available, and you cannot define a JDBC data source if you don’t know your username and password. (It’s possible to determine your username and password for a database on Cloud Foundry… but part of the benefit is that you shouldn’t need to worry about it.)

We needed a custom SQL data source that is Cloud Foundry-aware. This required a new class that extends the JasperReports class BaseJdbcDataSource which adds support for Cloud Foundry’s RdbmsServiceInfo to get database connection information.

Likewise, Jaspersoft already has a connector for MongoDB, but this needed to be extended to include Cloud Foundry’s MongoServiceInfo class and provide for a Cloud Foundry-aware MongoDB data source. With these two additional .jar files and corresponding applicationContext files, we were then ready to deploy JasperReports Server to Cloud Foundry.

The following excerpt is from deploying JasperReports server to the Cloud Foundry and then binding an existing database to it so that we can begin creating reports and performing analysis. Typically an application will use either MySQL or PostgreSQL or MongoDB, but for our tests we used all three at once.

>vmc push
Would you like to deploy from the current directory? [Yn]: Y
...
Would you like to bind any services to 'jrs-community-421'? [yN]: y
The following system services are available:
1. mongodb
2. mysql
3. postgresql
4. rabbitmq
5. redis
Please select one you wish to provision: 2
Specify the name of the service [mysql-a8ec3]: jrs-repo
Creating Service: OK
...
Push Status: OK

vmc bind-service postgresql-data jaspersoft-421
vmc bind-service mongodb-data jaspersoft-421

By taking advantage of the ‘bind-service’ command end users avoid any additional configuration when attaching data sources for reporting e.g.: manually entering the IP address of the datastore, entering the name of the database, managing credentials, selecting a port number, constructing the target URL, or defining the JNDI source.

Cloud Foundry’s simple ’bind-service’ semantics transforms the eight step process above into one simple command.

Additional Information:

We are excited about the power of the Cloud Foundry ecosystem and the ease with which one can now use BI in the cloud. We are eager to hear feedback from the Cloud Foundry community as folks start using Jaspersoft to analyze and report on data.

A Guest Blog Post by Matthew Dahlman, Jaspersoft

Don’t have a Cloud Foundry account yet? Sign up for free today

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email

Simplified Application Deployment With Cloud Foundry “Manifest”

Posted by Alex Suraci

Today, we added a new feature to Cloud Foundry command line tool (‘VMC’) that makes it easier to automate application deployments. The new feature, called “manifests”,  describe applications in human-editable manifest documents. Manifest documents can describe anything from a simple “Hello World” app to complex multi-app hierarchies with inter-application dependencies and service binding information.  The manifests feature not only adds ease-of-use to VMC, it also ensures consistency and reproducibility of application deployments in Cloud Foundry.

Overview

The manifests feature uses a YAML document, aptly named manifest.yml. You will typically place this manifest document in your app’s root directory, though you can specify a different location by telling VMC which to use with the -m flag. The manifest can be created by hand, automatically created after a vmc push, or explicitly with vmc manifest. With this manifest document, VMC will simply read the input values from the file rather than prompt you for each configuration.  Not only can you automate vmc push with manifests, you can also bypass interactive inputs for a large portion of VMC’s commands to make using the command-line tool more efficient and user-friendly. For example, you can leave the app name out when issuing a vmc update command, and VMC will retrieve the app name from an existing manifest document.

Here’s the full list of commands that can take advantage of the manifest document:

  • vmc push: Now allows you to specify multiple services. Pushes with information from the manifest. If no manifest is found, it will ask if you want to create one after the interaction is finished.
  • vmc stats, vmc update, vmc start, vmc stop: If no application name is given, it operates on the application(s) described by the manifest.
  • vmc update: Syncs changes from the root of the application if a manifest is present.
  • vmc start: Starts the applications in a multi-app deployment in the proper order (taking dependencies into account).
  • vmc stop: Stops multi-app deployments by shutting down each app in the reverse of the order in which they were started.
  • vmc restart: See vmc stop and vmc start.
  • vmc delete: Delete the application

Note: For multi-app hierarchies, these will operate only on the sub-app you’re in, rather than always operating on every app in the hierarchy. To operate on every app, invoke the command from the root of the hierarchy.

Getting Started

First, install or update your Cloud Foundry command line tool (‘VMC’) to the latest preview version using the following command:

gem install vmc --pre

You can verify that you got the right version using:

vmc -v

which should show the version to be 0.3.16.beta.1 or higher.

The easiest way to get going is to get a manifest document generated from basic application info. If you haven’t pushed your app yet, you can start with vmc push as usual, which will now ask if you want to save the configurations as a manifest document:

hello-sinatra(master*) % vmc push
Would you like to deploy from the current directory? [Yn]:
Application Name: hello-sinatra
Application Deployed URL [${name}.${target-base}]: ${name}-suraci.${target-base}
Detected a Sinatra Application, is this correct? [Yn]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [128M]:
How many instances? [1]:
Would you like to bind any services to 'hello-sinatra'? [yN]: y
The following system services are available
1: mongodb
2: mysql
3: postgresql
4: rabbitmq
5: redis
Please select the one you wish to provision: 2
Specify the name of the service [mysql-2cccd]:
Would you like to bind another service? [yN]:
Would you like to save this configuration? [yN]: y
Manifest written to manifest.yml.
Creating Application: OK
Creating Service [mysql-2cccd]: OK
Binding Service [mysql-2cccd]: OK
Uploading Application:
  Checking for available resources: OK
  Packing application: OK
  Uploading (1K): OK
Push Status: OK
Staging Application 'hello-sinatra': OK
Starting Application 'hello-sinatra': OK

As you can see, just before pushing, we were able to save the deployment configurations as manifest.yml in the same directory. Let’s take a peek into this file:

hello-sinatra(master*) % cat manifest.yml
---
applications:
  .:
    name: hello-sinatra
    instances: 1
    framework:
      name: sinatra
      info:
        exec: ruby main.rb
        description: Sinatra Application
        mem: 128M
    url: ${name}-suraci.${target-base}
    services:
      mysql-2cccd:
        type: :mysql
    mem: 128M

The manifest document has captured all of the configuration that we entered above for the application push into a description of the application deployment. Once you have a manifest.yml file, you can modify it however you would like, as it’s meant to be human-editable. The structure of the document is freeform, so if you want to define arbitrary values and use them throughout your document, you can.

Now if we try pushing again, vmc push will use this to automate everything:

hello-sinatra(master*) % vmc delete hello-sinatra
Provisioned service [mysql-2cccd] detected, would you like to delete it? [yN]: y
Deleting application [hello-sinatra]: OK
Deleting service [mysql-2cccd]: OK

hello-sinatra(master*) % vmc push
Would you like to deploy from the current directory? [Yn]:
Pushing application 'hello-sinatra'...
Creating Application: OK
Creating Service [mysql-2cccd]: OK
Binding Service [mysql-2cccd]: OK
Uploading Application:
  Checking for available resources: OK
  Packing application: OK
  Uploading (1K): OK
Push Status: OK
Staging Application 'hello-sinatra': OK
Starting Application 'hello-sinatra': OK

You can also use vmc manifest to create a manifest without pushing. vmc manifest will let you create more complex manifests describing multiple applications in a single hierarchy.

Now that you have a manifest document, you don’t really have to do anything else if you don’t want to get fancy. It’ll passively improve VMC’s user interface experience for the commands listed above: vmc push will be interaction-free, making deployment much easier, and many other commands will be efficient to invoke.

Getting Fancy

Child Manifests

A manifest document can inherit properties from a parent manifest like so:

inherit: path/to/parent.yml

This slurps in everything from the parent document ensuring that properties defined in the child manifest are deep-merged with the parent. The symbols are resolved after this merge has taken place, so any properties you set in the child manifest may be used in properties set in the parent.

This allows you to provide the basic information, such as service bindings and framework information, in a “base” manifest, which can be “filled in” via a child manifest. For example:

  • Having various child manifests for different deployment modes (e.g. debug, local, public) that extend base application information provided by a “base” manifest.
  • Packaging the basic configuration along with your app, which users can extend with their own manifest to override your settings or fill in the blanks for their own deployment.

Symbol Resolution

There are currently two special symbols:

  • target-base: The base URL of your target. For example, targeting api.cloudfoundry.com means a target-base value of cloudfoundry.com.
  • random-word: A random string of characters. This is useful for ensuring your URLs are unique.

Otherwise, symbol resolution simulates lexical scoping, so you can define arbitrary properties, which can be overridden by child manifests or in a nested hash.

For example, the following parent:

applications:
  ./foo:
    name: bar
    url: ${name}.${target-base}

…combined with this child manifest:

applications:
  ./foo:
    name: baz

…and with a target of api.cloudfoundry.com, will result in a url of baz.cloudfoundry.com when using the child manifest, and bar.cloudfoundry.com when using the parent.

Multi-App Manifests

Manifests also present a way to deploy multiple applications through a single push command.  Let’s say you have a modular application comprised of several independent parts, for example, a publisher and a subscriber. You’ll want the subscriber to be started before the publisher, so it doesn’t miss anything that was published. It’s best to have these two applications defined as parts of a whole, where you can specify this dependency. This is done with multi-app manifest documents.

Our publisher app will publish messages every second, with the message starting at 0 and increasing for every iteration. The subscriber will simply collect the messages it receives in the order they came in, and display them to the user.

To start with, you may want to arrange your applications like so:

./big-app
./big-app/publisher
./big-app/subscriber

This will make using the manifest document more natural.

Switch to the big-app directory and use vmc manifest to create your manifest document:

~ % cd ./big-app
big-app % vmc manifest
Configure for which application? [.]: ./publisher
Application Name: publisher
Application Deployed URL [${name}.${target-base}]: publisher-${random-word}.${target-base}
Detected a Sinatra Application, is this correct? [Yn]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [128M]:
How many instances? [1]:
Would you like to bind any services to 'publisher'? [yN]: y
The following system services are available
1: mongodb
2: mysql
3: postgresql
4: rabbitmq
5: redis
Please select the one you wish to provision: 5
Specify the name of the service [redis-47da2]: redis
Would you like to bind another service? [yN]:
Configure for another application? [yN]: y
Application path?: ./subscriber
Application Name: subscriber
Application Deployed URL [${name}.${target-base}]: subscriber-${random-word}.${target-base}
Detected a Sinatra Application, is this correct? [Yn]:
Memory reservation (128M, 256M, 512M, 1G, 2G) [128M]:
How many instances? [1]:
Would you like to bind any services to 'subscriber'? [yN]: y
The following system services are available
1: mongodb
2: mysql
3: postgresql
4: rabbitmq
5: redis
Please select the one you wish to provision: 5
Specify the name of the service [redis-a1278]: redis
Would you like to bind another service? [yN]:
Manifest written to manifest.yml.

In this single interactive session we’ve configured a manifest that defines two Sinatra apps, using a single Redis service. We’re using URLs with a bit of randomness (provided by the special random-word symbol) to ensure uniqueness.

There’s one thing missing, though. We didn’t specify any dependencies between the apps. If we were to start it now, we could lose some data if the publisher starts before the subscriber:

big-app % vmc push
Would you like to deploy from the current directory? [Yn]:
Pushing application 'publisher'...
# ...
Starting Application 'publisher': OK
Pushing application 'subscriber'...
# ...
Starting Application 'subscriber': OK

big-app % curl subscriber-bf872.cloudfoundry.com
Received: ["5", "6", "7", "8", "9"]

As you can see, we’ve lost some data here.  In the time between the publisher starting and then the subscriber starting, the subscriber has missed four messages.

This can be fixed by editing the manifest.yml document to indicate that the publisher depends on the subscriber being started:

---
applications:
./publisher:
# ...
depends-on: ./subscriber
./subscriber:
# ...

Now let’s delete both apps and retry.

big-app % vmc delete publisher
Deleting application [publisher]: OK

big-app % vmc delete subscriber
Deleting application [subscriber]: OK

big-app % vmc push
Would you like to deploy from the current directory? [Yn]:
Pushing application 'subscriber'...
# ...
Starting Application 'subscriber': OK
Pushing application 'publisher'...
# ...
Starting Application 'publisher': OK

As you can see, now the subscriber starts before the publisher. So we shouldn’t have any data loss this time.

big-app % curl subscriber-bf872.cloudfoundry.com
Received: ["1", "2", "3", "4", "5", "6", "7"]

Hooray!

Wrapping Up

The manifests feature is intentionally open-ended and flexible, providing the structure for you to define your deployments however you like. Kick the tires a bit and let us know how you think we should enhance this feature. Feel free to direct any suggestions or feedback to the support forums!

Alex Suraci, Cloud Foundry Engineering

Don’t have a Cloud Foundry account yet? Signup for free today

Facebook Twitter Linkedin Digg Delicious Reddit Stumbleupon Email