Get ahead
VMware offers training and certification to turbo-charge your progress.
Learn moreSpring 3.1 adds significant new support for environments. This new Environment API makes it easy to expose properties to an application or conditionally load a fragment of configuration.
In an earlier post in this series, Ramnivas showed how Cloud Foundry can automatically connect to a database without manual configuration. When you need more control over this process, e.g. connecting to multiple databases, the cloud namespace condenses the configuration of a DataSource
into just a single line of XML. The cloud namespace is powerful, but it is only supported for applications running in Cloud Foundry. Using the cloud namespace means coupling that portion of configuration to Cloud Foundry. When not deployed to Cloud Foundry, this configuration should be disabled. Out of container testing is a fundamental tenet of Spring’s philosophy, so it would be unacceptable if an application had to be deployed in order to run an integration test. Spring Profiles solves this problem.
A Profile in Spring is a fragment of configuration that is only activated when a certain condition is true. Many application platforms have had a concept of development, test, and production configurations. While profiles can be used in this way, they are also much more flexible. There is no predefined set of profiles, except a “default
” profile that is activated when no other profiles are defined. A profile can be used to swap configurations when running in a different environment or to enable an optional feature in your application. It’s up to you how you want to use it.
cloud
” profile is automatically enabled. This allows for a pre-defined, convenient location for Cloud Foundry specific application configuration. All specific usages of the cloud namespace should occur within the cloud profile block to allow the application to run outside of Cloud Foundry environments.
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongoDbFactory" />
</bean>
<beans profile="default">
<mongo:db-factory id="mongoDbFactory" dbname="pwdtest" host="127.0.0.1" port="27017" username="test_user" password="efgh" />
</beans>
<beans profile="cloud">
<cloud:mongo-db-factory id="mongoDbFactory" />
</beans>
This sample configuration shows Spring's MongoTemplate
being populated from two alternatively configured connection factories. When running on Cloud Foundry, the connection factory is automatically configured. When not running on Cloud Foundry, the connection factory is manually configured with the connection settings to a locally running MongoDB instance.
However, it is still possible to send email from your Cloud Foundry application. Service providers, such as SendGrid, can send email on your behalf via HTTP web services. When the application is running in your own datacenter, you may want to use the corporate SMTP server, and then use SendGrid when running on CloudFoundry.com. Here is an example of how to create a service bean to connect to SendGrid in the cloud profile.
<beans profile="cloud">
<bean name="mailSender" class="example.SendGridMailSender">
<property name="apiUser" value="[email protected]" />
<property name="apiKey" value="secureSecret" />
</bean>
</beans>
<beans profile="cloud">
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://${cloud.services.mysql.connection.host}:${cloud.services.mysql.connection.port}/${cloud.services.mysql.connection.name}" />
<property name="user" value="${cloud.services.mysql.connection.username}" />
<property name="password" value="${cloud.services.mysql.connection.password}" />
</bean>
</beans>
Service properties generally take the form “cloud.services.{service-name}.connection.{property}
”. The specific connection properties that are available depend on the type of service.
For convenience, if there is a single service of a given type bound to the application, an alias will be created based on the service type instead of the service name. For a MySQL service, the properties will take the form “cloud.services.mysql.connection.{property}
”.