Spring Cloudの使い方を調べていると、よい記事がみつかりました。
これを参考にして、リポジトリにspring-cloud-sample のサンプルを作成していきます。Javaアプリを実行可能なJARファイルにできると、DockerコンテナにはJVMがあればデプロイ可能になります。
spring-cloud-sample CloudFoundryのhello-spring-cloud を参考にして、DataSourceのクラス名と接続URLを表示する簡単なプログラムを作成しました。
@Profile("cloud")
アノテーションを指定しているので、CloudFoundryにデプロイした時にだけこのDataSourceのBeanは作成されます。
~/spring-cloud-sample/src/main/java/helloconfig/CloudConfiguration.java package helloconfig;import javax.sql.DataSource;import org.springframework.cloud.config.java.AbstractCloudConfig;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Profile;import org.springframework.context.annotation.Bean;@Configuration @Profile("cloud") public class CloudConfiguration extends AbstractCloudConfig { @Bean public DataSource dataSource () { return connectionFactory().dataSource(); } }
ローカルで実行するときはapplication.propertiesで指定したDataSourceが使用されます。
~/spring-cloud-sample/src/main/resources/application.properties spring.datasource.platform: h2
bundle.gradle dependenciesに、org.springframework.cloud:spring-cloud-cloudfoundry-connector
を追加しました。spring-cloud-cloudfoundry-connector の中で、VCAP_SERVICES
環境変数のJSONをJacksonを使いアンマーシャルして、MySQLへの接続情報をセットしてくれます。
~/spring-cloud-sample/build.gradle buildscript { ext { springBootVersion = '1.1.9.RELEASE' springloadedVersion = '1.2.1.RELEASE' springCloudVersion = '1.1.0.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" ) classpath("org.springframework:springloaded:${springloadedVersion}" ) } } apply plugin: 'java' apply plugin: 'spring-boot' jar { baseName = 'helloconfig' version = '0.0.1-SNAPSHOT' } sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile("org.springframework.boot:spring-boot-starter-thymeleaf" ) compile("org.springframework.boot:spring-boot-starter-data-jpa" ) compile("org.springframework.cloud:spring-cloud-spring-service-connector:${springCloudVersion}" ) compile("org.springframework.cloud:spring-cloud-cloudfoundry-connector:${springCloudVersion}" ) compile("com.h2database:h2" ) testCompile("org.springframework.boot:spring-boot-starter-test" ) } task wrapper(type: Wrapper) { gradleVersion = '2.2.1' }
profileをcloudに指定 CloudFoundryにデプロイした時は、Spring Auto-reconfiguration Framework 、java-buildpack-auto-reconfiguration の中で、environment.addActiveProfile(CLOUD_PROFILE);
をしてくれるので動的にprofileが”cloud”になります。
package org.cloudfoundry.reconfiguration.spring;public final class CloudProfileApplicationContextInitializer implements ApplicationContextInitializer <ConfigurableApplicationContext >, Ordered { private static final String CLOUD_PROFILE = "cloud" ; ... @Override public void initialize (ConfigurableApplicationContext applicationContext) { if (this .cloudUtils.isInCloud()) { addCloudProfile(applicationContext); } else { this .logger.warning("Not running in a cloud. Skipping 'cloud' profile activation." ); } } private void addCloudProfile (ConfigurableApplicationContext applicationContext) { ConfigurableEnvironment environment = applicationContext.getEnvironment(); if (hasCloudProfile(environment)) { this .logger.fine("'cloud' already in list of active profiles" ); } else { this .logger.info("Adding 'cloud' to list of active profiles" ); environment.addActiveProfile(CLOUD_PROFILE); } }
gradlewを使って新しい環境でアプリを実行する このリポジトリにはgradlewを作成して追加しています。dockerfile/java を使った新しいコンテナ上で、すぐにGradleの環境を構築してアプリを実行することができます。
$ docker run -it --rm dockerfile/java:oracle-java8 bash $ git clone https://github.com/masato/spring-cloud-sample $ cd spring-cloud-sample $ ./gradlew ... Welcome to Gradle 2.2.1. To run a build, run gradlew <task> ... To see a list of available tasks, run gradlew tasks To see a list of command-line options, run gradlew --help BUILD SUCCESSFUL Total time: 24.178 secs
ローカルで実行する bootRunを実行します。
Dockerホストから、コンテナのアプリへcurlを使い接続します。
$ curl $(docker inspect --format="{{ .NetworkSettings.IPAddress }}" $CONTAINER_ID ):8080 <!DOCTYPE html> <html> <head> <title>Cloud Services</title> </head> <body> <h2>Cloud Services</h2> <table class="table table-striped" > <thead> <tr> <th>Service Connector Type</th> <th>Connection address</th> </tr> </thead> <tbody> <tr> <td><strong>org.apache.tomcat.jdbc.pool.DataSource</strong></td> <td><bad url> h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</td> </tr> </tbody> </table> </body> </html>