Cloud Foundry for Spring Developers |
|

By now, many of you have probably seen the Cloud Foundry webinar and Rod's blog from earlier today. I'd like to provide a quick follow-up that features a "hello-spring" sample application deployed in the cloud. Thanks to Cloud Foundry, there's practically no learning curve at all.
Before we get started, let's consider three goals that have driven Spring from day one:
- focus on simplicity and productivity to make developers lives easier
- support innovative technologies in a consistent way
- ensure portability of applications across deployment environments
Then, consider those same three goals in relation to Cloud Foundry:
- Simplicity and Productivity: Deploying a Spring application to the cloud is as simple as dragging and dropping within SpringSource Tool Suite, and even when building an application to run in the cloud, developers can take advantage of the productivity gains enabled by Roo and Grails exactly as they normally would.
- Consistent Innovation: Projects like Spring Social and Spring Data embrace innovative technologies such as Twitter and non-relational data stores that are increasingly popular for cloud-based applications, and they do so in ways that are consistent with the existing Spring platform. Cloud Foundry provides services to support such applications. RabbitMQ will be available as a cloud service soon, so the same applies to applications that rely on RabbitMQ for messaging via Spring AMQP and Spring Integration.
- Portability: The cloud is first and foremost a new deployment environment, and yet it's easy to create an application that can run in and out of the cloud without even swapping configuration files.
With those goals in mind, we've designed a sample application that provides an introduction to Cloud Foundry for Spring developers. This is the first of many sample applications that will be featured on this blog over the following days and weeks. It demonstrates how a single configuration can support both local testing and cloud deployment. It also demonstrates services available in Cloud Foundry: MySQL, Redis, and MongoDB. Let's quickly walk through the actual deployment and then work backwards to the configuration.
With a Cloud Foundry account, you can deploy (or “push”) applications to the cloud. Those applications can use services by binding to them. When you use the vmc command line tool or the STS plugin, you can either bind to an existing service or create a new one. Let's look at how to do this with the command line tool, vmc. Here's the output of the 'vmc push' command:
Would you like to deploy from the current directory? [Yn]: y Application Deployed URL: 'hello-spring.cloudfoundry.com'? Detected a Java SpringSource Spring Application, is this correct? [Yn]: y Memory Reservation [Default:512M] (64M, 128M, 256M, 512M, 1G or 2G) 256 Creating Application: OK Would you like to bind any services to 'hello-spring'? [yN]: y Would you like to use an existing provisioned service [yN]? n The following system services are available:: 1. redis 2. mongodb 3. mysql Please select one you wish to provision: 3 Specify the name of the service [mysql-63854]: hello-db Creating Service: OK Binding Service: OK Uploading Application: Checking for available resources: OK Processing resources: OK Packing application: OK Uploading (42K): OK Push Status: OK
The vmc output shows the individual steps, but the same task can be accomplished by dragging and dropping to a Cloud Foundry Server instance within SpringSource Tool Suite as shown here:
Now that we've seen the deployment, let's take a look at the configuration. It's surprisingly simple, since you don't even need to configure explicit credentials and connection strings. Instead, you can retrieve a reference to this DataSource from the cloud itself using the CloudFoundry “cloud” namespace. Let's look at how we might configure a bean, DataSourceCustomerService, to reference the CloudFoundry provisioned database service:
<cloud:data-source id="db"/>
<bean class="example.AccountRepository">
<property name="dataSource" ref="db"/>
</bean>
The first element will create a bean of type java.sql.DataSource, and the second will be injected with its that reference to satisfy its dependency.
That's pretty much all you need to know in order to deploy a new application into the cloud and provision services. However, we also want to test the application locally. Thankfully, the forthcoming Spring 3.1 release offers some assistance here via Spring profiles. The “profiles” feature in Spring 3.1 – explained very clearly in this recent blog by Chris Beams – enables you to "switch on" certain beans at runtime.
This can be quite useful when you want to associate beans with particular environments. Similar functionality is possible using Spring's property placeholder resolution mechanism to vary the definition of objects based on external properties. But this is different: suppose for example that you want to use the <cloud:data-source/> element in the cloud, a regular DriverManagerDataSource defined as a <bean> on localhost and a DataSource retrieved through JNDI in integration testing via <jee:jndi-lookup/>. Spring profiles makes it easy to associate each of these beans with a profile, so that – while all three are defined in the configuration – only one is active at any time based on the environment.
Spring provides a few pre-packaged strategies for enabling profiles. One is to use command line system properties. However, if you need to dynamically set the active profiles based on information that is known only at runtime, then consider using an ApplicationContextInitializer implementation, as described in this other post by Chris Beams.
Let's look at the hello-spring application's configuration and how it takes profiles into account:
<beans>
<beans profile="default">
<jdbc:embedded-database id="dataSource"/>
</beans>
<beans profile="cloud">
<cloud:data-source id="dataSource"/>
</beans>
</beans>
The nested <beans> elements and their "profile" attributes are the only new Spring 3.1 features in use here. The nested beans element lets us specify that any beans contained therein should be enabled only if the designated profile is active.
With those simple steps, we can now build and test our logic locally and then deploy the exact same application to the cloud without changing anything. The cloud namespace has support for other services, as well. If we add MongoDB and Redis support, the configuration would look like this:
<beans profile="default">
<jdbc:embedded-database id="dataSource"/>
<bean id="mongo" class="com.mongodb.Mongo"/>
<bean id="redis" class="org.springframework.data.keyvalue.redis.connection.jedis.JedisConnectionFactory"/>
</beans>
<beans profile="cloud">
<cloud:data-source id="dataSource"/>
<cloud:mongo id="mongo"/>
<cloud:redis-connection-factory id="redis"/>
</beans>
The hello-spring example shows all of this and more, and it can be cloned from this repository. The most important characteristic of the application is that it can be dropped onto either a local server, such as the tc Server instance available within STS, or to the new Cloud Foundry server.
Here's a screenshot of the hello-spring application deployed locally:
And here's the exact same application running in the cloud. Notice how the URLs and connection strings are different:
That's all for now, but watch this space. We have many more sample applications (watch this repo) and blogs planned in the days and weeks ahead!
Similar Posts
- Using Cloud Foundry Services with Spring: Part 4 – Spring Profiles
- Micro Cloud Foundry for Spring Developers
- Using Cloud Foundry Services with Spring: Part 2 – Auto-reconfiguration
- One-step deployment with Grails and Cloud Foundry
- Using Cloud Foundry Services with Spring: Part 3 – the <cloud> namespace








Neale Upstone says:
Added on April 12th, 2011 at 6:46 pmNow this looks fun.
Bernd says:
Added on April 20th, 2011 at 8:57 amHi,
I just forked the git repo and tried to import the samples into the IDE. Most of the fail to build in STS with various reasons. It should work out of the box, should it?
Mark Fisher (blog author) says:
Added on May 2nd, 2011 at 2:59 pm@Bernd, sorry for the delay. There are some issues with Spring 3.1 M1 compatibility in STS, and those should be addressed in 3.1 M2. That said, I did build the sample successfully in STS myself. I have a couple errors in the log, but it does build. Would you mind posting in the forum? http://forum.springsource.org
Thanks,
Mark
Ram says:
Added on May 11th, 2011 at 1:20 amI am using Spring STS for developing Spring MVC Project.Also using Cloud Foundry. Can you provide any sample project or coding to create database, create table,update records in CloudFoundry Mysql using Spring JDBCRTemplate.
How to connect Cloud foundry Mysql database and access that database…plz help me…
Daniel Chapman says:
Added on May 19th, 2011 at 1:17 pmHi,
This sounded great to me with all the talk of open-source, however it looks like in order to host your own cloud – you need to buy a lot of underlying software from Vmware that this open source runs on top of. This seems a little misleading to me – it's like open source with a Vmware lock-in. Am I in the minority thinking that large companies who wish to take advantage of Paas will want to use their own private data centers? We're continually looking to reduce cost through use of free open source, but Cloud Foundry seems like an incomplete solution by setting up requirements for paid-software.
Dan C.
Ramnivas Laddad says:
Added on May 19th, 2011 at 1:28 pmDaniel,
You don't need to buy anything in order to run Cloud Coundry in your data center (or even your laptop). For example, take a look at http://www.ewanleith.com/blog/128/try-cloudfoundry-on-an-aws-micro-instance, where the author describes how to run Cloud Foundry on AWS without paying anything to VMware. Similarly, you can run Cloud Foundry in your data center with/without virtualization layer (and with/without VMware's virtualization layer, if you choose to go for a virtualized infrastructure). See for example, http://matschaffer.com/2011/04/cloudfoundry-virtualbox that shows how to use VirtualBox to run Cloud Foundry.
We truly believe in offering Open PaaS. I hope this convinces you of that.
-Ramnivas
Stephan oudmaijer says:
Added on June 15th, 2011 at 2:48 amHi Mark,
great article, Cloud Foundry is really cool, I like it. A few questions, is there a maven plugin in the planning for deploying to Cloud Foundry? And Cloud Foundry classic had a web based console, what about that? Will it also be available for the new Cloud Foundry?
Maybe you can elaborate on how to setup a cloud:data-source using the Spring Java Config.
Anyway, great work!
Cheers,
Stephan
Jaroslav says:
Added on August 1st, 2011 at 10:11 amHi Mark,
just tried to deploy the hello-spring example from the ~/SpringSource/cloudfoundry-samples repository. Deployment to the cloud went smoothly, when tried to deploy locally, the tc server refused to instantiate the JedisConnectionFactory (class not found). I have found the JedisConnectionFactory in a different package (org.springframework.data.redis.connection.jedis instead of org.springframework.data.keyvalue.redis.connection.jedis). When changed, the service started correctly. Is this some kind of my misconfiguration or the packaging has been changed in the meantime?
Regards, Jaroslav
Mark Fisher (blog author) says:
Added on August 1st, 2011 at 10:16 amJaroslav,
Thanks for pointing that out. Yes, the 'keyvalue' package was removed. I just updated the sample's configuration accordingly.
-Mark