Earlier this year VMware released CloudFoundry, an open-source PAAS solution, with initial support for several services such as MongoDB, MySQL, and Redis. Lately it has added PostgreSQL and RabbitMQ to the list of cloud services that applications can depend on, as well as offering a Micro edition of the cloud that can run on a single workstation.
PostgreSQL is an interesting addition since it is a full featured traditional database with a different audience than MySQL or MongoDB users. To accommodate PostgreSQL, cloudfoundry does not use a vanilla version but instead a customized one based on vFabric as explained in the official blog post.
The same post gives an example of using PostgreSQL in a Java project built with Spring Roo. Here we illustrate an alternative approach where the Java application is a Spring based WAR
utilizing JPA.
Assume that your application has a Spring context setup as below:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="myJpaManager" /> <property name="dataSource" ref="dataSource"/> </bean> <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"> <property name="driverClassName" value="org.postgresql.Driver" /> <property name="url" value="jdbc:postgresql://localhost/postgres" /> <property name="username" value="postgres" /> <property name="password" value="postgres" /> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven transaction-manager="transactionManager" /> <context:annotation-config />
and a META-INF/persistence.xml
like this
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="myJpaManager" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> <property name="hibernate.hbm2ddl.auto" value="update" /> </properties> </persistence-unit> </persistence>
This application can be uploaded to CloudFoundry completely unchanged thanks to the auto-configuration feature of CloudFoundry.
PostgreSQL (as well as MySQL and the rest of supported services) takes advantage of the auto-configuration feature offered by Cloudfoundry. Under certain conditions a local Java Application that uses PostgreSQL can be uploaded to CloudFoundry with zero code changes.
Auto-configuration employs the Spring Core container and takes places when both of the following are true:
- There may exactly be only one service of a given service type. For example, you may bind only one relational database service (MySQL or PostgreSQL) to an application.
- There may exactly be only one bean of the matching type. For example, you may have only one DataSource bean in the application context.
If these requirements hold then Cloudfoundry will automatically intercept your local datasource and use the Cloudfoundry service instead of what is set in the Spring context.
The only thing left to do is to answer positively when vmc asks for service binding when the application is uploaded to the cloud.
For more complex applications, Spring 3.1 is expected to add a special cloud namespace and runtime profile support.