https://github.com/cloudfoundry-samples/spring-music
1. First lets create our user defined service for Oracle , here we just use a simple URI which the Spring Cloud library knows how to use.
c:\pivotal\spring-music-oracle>cf create-service user-provided
Name?> oracle11gr2
What credential parameters should applications use to connect to this service instance?
(e.g. hostname, port, password)> uri
uri> oracle://scott:tiger@192.168.110.209:1521/XE
Creating service oracle11gr2... OK
c:\pivotal\spring-music-oracle>
The spring cloud project is here.
https://github.com/spring-projects/spring-cloud
2. Now with a previously created WAR file lets push the spring music app to PCF and bind to our oracle service as shown below.
c:\pivotal\spring-music-oracle>cf push --path=spring-music-oracle.war
Name> spring-music-oracle
Instances> 1
1: 128M
2: 256M
3: 512M
4: 1G
Memory Limit> 3
Creating spring-music-oracle... OK
1: spring-music-oracle
2: none
Subdomain> spring-music-oracle
1: system.com
2: none
Domain> system.com
Binding spring-music-oracle.system.com to spring-music-oracle... OK
Create services for application?> n
Bind other services to application?> y
1: mysql-dev
2: rmq
3: user-provided-705bf
4: oracle11gr2
Which service?> 4
Binding oracle11gr2 to spring-music-oracle... OK
Bind another service?> n
Save configuration?> n
Uploading spring-music-oracle... OK
Preparing to start spring-music-oracle... OK
-----> Downloaded app package (22M)
-----> Downloading OpenJDK 1.7.0_51 from http://download.pivotal.io.s3.amazonaws.com/openjdk/lucid/x86_64/openjdk-1.7.0_
51.tar.gz (1m 52s)
Expanding JRE to .java (2.4s)
-----> Downloading Spring Auto-reconfiguration 0.8.4 from http://download.pivotal.io.s3.amazonaws.com/auto-reconfigurati
on/auto-reconfiguration-0.8.4.jar (4.3s)
Modifying /WEB-INF/web.xml for Auto Reconfiguration
-----> Downloading Tomcat 7.0.50 from http://download.pivotal.io.s3.amazonaws.com/tomcat/tomcat-7.0.50.tar.gz (27.9s)
Expanding Tomcat to .tomcat (0.3s)
-----> Downloading Buildpack Tomcat Support 1.1.1 from http://download.pivotal.io.s3.amazonaws.com/tomcat-buildpack-supp
ort/tomcat-buildpack-support-1.1.1.jar (0.2s)
-----> Uploading droplet (63M)
Checking status of app 'spring-music-oracle'...
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
0 of 1 instances running (1 starting)
1 of 1 instances running (1 running)
Push successful! App 'spring-music-oracle' available at spring-music-oracle.system.com
c:\pivotal\spring-music-oracle>
3. Here are some screenshots showing it deployed , invoking the application, and data within the Oracle 11g r2 schema.
The code to make this happen for Oracle is as follows, we do this to make use of the spring cloud code to bind to the user defined service "oracle11gr2" we created above. The spring cloud Library enables cloud applications to connect to services. The classes below show how we enable our oracle service for the spring music application.
OracleServiceInfo.java
package org.cloudfoundry.samples.music.cloud; import org.springframework.cloud.service.ServiceInfo.ServiceLabel; import org.springframework.cloud.service.common.RelationalServiceInfo; @ServiceLabel("oracle") public class OracleServiceInfo extends RelationalServiceInfo { public OracleServiceInfo(String id, String url) { super(id, url, "oracle"); } @Override public String getJdbcUrl() { return String.format("jdbc:%s:thin:%s/%s@%s:%d/%s", "oracle", super.getUserName(), super.getPassword(), super.getHost(), super.getPort(), super.getPath()); } }
OracleDataSourceCreator.java
package org.cloudfoundry.samples.music.cloud; import org.cloudfoundry.samples.music.cloud.OracleServiceInfo; import org.springframework.cloud.service.relational.DataSourceCreator; public class OracleDataSourceCreator extends DataSourceCreator<OracleServiceInfo> { private static final String[] DRIVERS = new String[]{"oracle.jdbc.OracleDriver"}; private static final String VALIDATION_QUERY = "SELECT 'Y' from dual"; public OracleDataSourceCreator() { super("spring-cloud.oracle.driver", DRIVERS, VALIDATION_QUERY); } }
UserProvidedOracleServiceInfoCreator.java
package org.cloudfoundry.samples.music.cloud; import org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator; import java.util.Map; public class UserProvidedOracleServiceInfoCreator extends CloudFoundryServiceInfoCreator<OracleServiceInfo> { public UserProvidedOracleServiceInfoCreator() { super("user-provided"); } @Override @SuppressWarnings("unchecked") public boolean accept(Map<String, Object> serviceData) { String label = (String) serviceData.get("label"); if (label.equals(getTag())) { Map<String, Object> credentials = (Map<String, Object>) serviceData.get("credentials"); String uri = (String) credentials.get("uri"); if (uri != null && uri.startsWith("oracle:")) { return true; } } return false; } @Override @SuppressWarnings("unchecked") public OracleServiceInfo createServiceInfo(Map<String, Object> serviceData) { String id = (String) serviceData.get("name"); Map<String, Object> credentials = (Map<String, Object>) serviceData.get("credentials"); String uri = credentials.get("uri").toString(); return new OracleServiceInfo(id, uri); } }
OracleRepositoryConfig.java
package org.cloudfoundry.samples.music.config.data; import org.hibernate.dialect.MySQL5Dialect; import org.hibernate.dialect.Oracle10gDialect; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @Configuration @Profile("oracle") @EnableJpaRepositories("org.cloudfoundry.samples.music.repositories.jpa") public class OracleRepositoryConfig extends AbstractJpaRepositoryConfig { protected String getHibernateDialect() { return Oracle10gDialect.class.getName(); } }
RelationalCloudDataSourceConfig.java
package org.cloudfoundry.samples.music.config.data; import org.springframework.cloud.config.java.AbstractCloudConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import javax.sql.DataSource; @Configuration @Profile({"mysql-cloud", "postgres-cloud", "oracle-cloud"}) public class RelationalCloudDataSourceConfig extends AbstractCloudConfig { @Bean public DataSource dataSource() { return connectionFactory().dataSource(); } }
src/main/resources/META-INF/servicesorg.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator
org.cloudfoundry.samples.music.cloud.UserProvidedMysqlServiceInfoCreator
org.cloudfoundry.samples.music.cloud.UserProvidedOracleServiceInfoCreator
src/main/resources/META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator
org.springframework.cloud.service.relational.MysqlDataSourceCreator
org.cloudfoundry.samples.music.cloud.OracleDataSourceCreator
org.springframework.cloud.service.relational.PostgresqlDataSourceCreator
org.springframework.cloud.service.keyval.RedisConnectionFactoryCreator
org.springframework.cloud.service.document.MongoDbFactoryCreator
org.springframework.cloud.service.messaging.RabbitConnectionFactoryCreator
org.springframework.cloud.service.smtp.MailSenderCreator
Finally you need to ensure that ojdbc6.jar is shipped with the WAR file within "WEB-INF/lib" which is the Oracle JDBC driver to enable the application to connect to oracle.
More Information on Pivotal CF
http://www.gopivotal.com/products/cloud-foundry