1. Preface
attendee-service is configured to automatically create a database schema on startup. You can verify this by inspecting the source code of the attendee-service project.
Study the file src/main/resources/application.yml, and note how it contains the setting generate-ddl:
spring:
application:
name: attendee-service
jpa:
generate-ddl: true
This setting ensures that when the application starts, the schema will be auto generated from the JPA domain definition.
In this lab, we’ll turn off this feature, and instead learn how to run a "one-off" task that will create the needed schema for us explicitly, as a separate step.
2. Setup
-
If necessary, get a copy of the source code for
attendee-service(clone or download) -
Edit the
application.ymlfile and setgenerate-ddlto false. Rebuild the application jar file with:mvn clean package -
Do whatever’s necessary to delete your existing attendee-service application.
-
Delete the mysql database you’d originally created for the attendee-service application using the command
cf delete-service -
Now, install the
mysqlcf cli plugin from the cloudfoundry plugins web site. This will add the command 'mysql' to your cf cli. -
Recreate your attendees database, perhaps like this:
cf create-service cleardb spark attendee-dbValidate that the service was created by invoking the
cf servicescommand. -
Push attendee service once more. Assuming you have a manifest file for
attendee-servicethat looks similar to this:--- applications: - name: attendee-service path: target/attendee-service-0.0.1-SNAPSHOT.jar memory: 512M random-route: true services: - attendee-dbInvoke your
cf pushcommand from within theattendee-servicebase directory:cf push -
Now, invoke the
cf mysqlcommand, which should produce output similar to this:MySQL databases bound to an app: attendee-db -
Let’s check that the database has no tables at this time:
cf mysql attendee-dbthen:
mysql> show tables;And ensure that the output shows that no tables exist at this time.
In fact, let’s go further:
-
Tail the logs for
attendee-servicecf logs attendee-service -
In a browser, visit the
attendees/endpoint and verify that you get an error, and verify that the logs contain an error message complaining that the attendees table does not exit.
3. Run a "one-off" task to generate the schema
Familiarize yourself with Cloud Foundry tasks by reviewing the documentation.
It turns out that our spring boot application already has the knowledge for creating our schema. That knowledge is embedded in the spring data jpa libraries. The idea is simple:
-
we’ll run a spring-boot app not as a web service, but as a task by turning off the spring-boot property
spring.main.web-environment -
next, for this run, we’ll turn on the
spring.jpa.generate-ddlproperty -
we’ll specify a start command for our task that leverages everything that’s already inside our droplet: the jdk and our spring boot application
Here’s the command we want to run:
cf run-task attendee-service '.java-buildpack/open_jdk_jre/bin/java \
-Dspring.jpa.generate-ddl=true \
-Dspring.profiles.active=cloud \
-Dspring.main.web-environment=false \
-cp . org.springframework.boot.loader.JarLauncher'
You’ll see output similar to this:
Creating task for app attendee-service in org eitan-org / space eitan-space as esuez@pivotal.io... OK Task has been submitted successfully for execution. task name: fb9e9533 task id: 1
Run the 'cf tasks' command to check on the status of our task:
cf tasks attendee-service
The output should resemble this:
id name state start time command
1 fb9e9533 SUCCEEDED Thu, 11 May 2017 02:45:15 UTC .java-buildpack/open_jdk_jre/bin/java \
-Dspring.jpa.generate-ddl=true \
-Dspring.profiles.active=cloud \
-Dspring.main.web-environment=false \
-cp . org.springframework.boot.loader.JarLauncher
Note that the state is SUCCEEDED.
Let’s now verify that our table has been created:
cf mysql attendee-db
and:
mysql> show tables;
..should show:
+------------------------------+ | Tables_in_ad_12f26b7197bb693 | +------------------------------+ | attendee | +------------------------------+ 1 row in set (0.03 sec)
Now, attempt to revisit the attendees endpoint once more, and you’ll see that the call succeeds.
Congratulations, you’ve just run a one-off task inside cloudfoundry!
Acknowledgements to Liu Dapeng and his published example.