How to make Magnolia CMS ready for the Cloud Foundry PaaS – Milestone 2 (Persisting Data)

Published on February 26, 2016 by Guest blogger



Thomas Ummenhofer is a Data Analyst and Software Engineer at YMC AG since 2013. As part of the Swiss retailer Migros' strategy to operate their software in a modern environment, he is bringing Magnolia to the cloud.
 

This is part of a project YMC is working on for Migros, Switzerland’s biggest retailer. Migros IT Services strive to operate their software in a modern, flexible, and scalable infrastructure.

In the previous article of this blog series, we deployed Magnolia CMS to the Cloud Foundry Platform as a Service. So far, this is only a proof of concept. To lift this setup to a production level and to benefit from further cloud advantages, a few more obstacles have to be solved. One of the biggest weaknesses is the lack of persistence: No locally stored content will survive rebooting.

Now the configuration of an external database in Magnolia is not really an issue, but hard-coding database credentials into packaged configuration files doesn’t sound very cloudy, does it? Way more flexibility could be obtained by injecting the database into the application: This would allow us to swap the database without touching the code. Furthermore, running multiple installations of the same application without packing additional repository configuration into the WAR-file is another advantage.

In this article I will explain a flexible and lean way to persist Magnolia content in an external database when working with Cloud Foundry.

 

Cloud Foundry Services

In Cloud Foundry, a database can be bound to an application as a service.

Pivotal Cloud Foundry comes with a service marketplace, where creating a new service instance and binding it to an application only takes three clicks in Pivotal’s web interface (or one command using Cloud Foundry’s CLI):

 

 

 

If there is no suitable database service for your requirements in the marketplace you may even add your own “user-provided” MySQL-service.

 

cf create-user-provided-service author_magnolia_db -p '{

"type":"mysql",

"host":"HOST",

"port":"3306",

"name":"DB",

"username":"USER",

"password":"PW"

}

 

The CLI can also bind it to an application:  cf bind-service mgnl-author author_magnolia_db or alternatively the service binding can be configured in the Cloud Foundry manifest.yml:

 

---

path: webapp/target/magnolia-app.war

timeout: 180

memory: 2G

instances: 1

 

env:

  magnoliaInstanceType: cfauthor

 

applications:

  - name: mgnl-author

services:

  - author_magnolia_db

 

 

Accessing Cloud Foundry Services in Magnolia

Cloud Foundry services are injected into the applications with the help of the environment variable VCAP_SERVICES. This variable contains all bonded services in a JSON string:

{

"app-autoscaler": [{

"...": "..."

}],

"user-provided": [{

"name": "author_magnolia_db",

"label": "user-provided",

"tags": [],

"credentials": {

"host": "HOST",

"name": "DB",

"password": "PW",

"port": "3306",

"type": "mysql",

"username": "USER"

},

"syslog_drain_url": ""

}],

"p-gemfire": [{

"...": "..."

}]

}

 

Programmatically it is now easy to access the credentials, but Magnolia uses an XML file for database configuration where parsing a JSON string is not possible.

Therefore a little extra effort is needed: Parse VCAP_SERVICES on start up, extract the credentials and write them into separate environment variables. Fortunately Magnolia has already taken care of this by providing the Cloud Foundry Integration Module. It stores the values using the schema  vcap.services.{service.label}.{instance.name}.credentials.{key}. In our example it results in the following variables:

 

vcap.services.user-provided.author_magnolia_db.credentials.host

vcap.services.user-provided.author_magnolia_db.credentials.name

vcap.services.user-provided.author_magnolia_db.credentials.password

vcap.services.user-provided.author_magnolia_db.credentials.port

vcap.services.user-provided.author_magnolia_db.credentials.type

vcap.services.user-provided.author_magnolia_db.credentials.username

 

They can be used in the <DataSource> definition in Magnolia’s repository configuration like this:

 

<DataSources>

<DataSource name="magnolia">

<param name="driver" value="com.mysql.jdbc.Driver"/>

<param name="url" value="jdbc:${vcap.services.user-provided.author_magnolia_db.credentials.type}://${vcap.services.user-provided.author_magnolia_db.credentials.host}:${vcap.services.user-provided.author_magnolia_db.credentials.port}/${vcap.services.user-provided.author_magnolia_db.credentials.name}"/>

<param name="user" value="${vcap.services.user-provided.author_magnolia_db.credentials.username}"/>

<param name="password" value="${vcap.services.user-provided.author_magnolia_db.credentials.password}"/>

<param name="databaseType" value="mysql"/>

<param name="validationQuery" value="select 1"/>

</DataSource>

</DataSources>

 

The disadvantage of this method is the necessity to hardcode values for {service.label} and {instance.name} into the repository configuration, making it less flexible.

To achieve our goal, we have modified Magnolia’s Cloud Foundry Module to map a service which ends with “magnolia_db” to vcap.services.autodetected.magnolia_db.credentials.{key}. This way, injecting whatever MySQL service is possible, as long as its name follows the pattern mentioned.

 

Conclusion

That’s it! On start up, Magnolia will connect the injected database and use it for persisting content. You only need one repository configuration for multiple Magnolia Cloud Foundry applications (e.g. one author and two public instances).

For dynamic horizontal scaling of the public instances, it would be great if we could reuse the same service for multiple instances. This is possible using a JCR Cluster, which will be covered in an upcoming article – stay tuned, we’ll announce it soon!

 

Thomas Ummenhofer, YMC AG

 

Thomas Ummenhofer is Data Analyst and Software Engineer at YMC AG since 2013. Besides his passion for analyzing large amounts of data, he also develops reliable and scalable software solutions. As part of the Swiss retailer Migros' strategy to operate their software in a modern environment, he is bringing Magnolia to the cloud.

 



Comments



{{item.userId}}   {{item.timestamp | timestampToDate}}

About the author Guest blogger

Magnolia has an amazing community of partners and clients, among them quite a few wordsmiths. From time to time, they put their expertise into blog posts and share them on this platform.


See all posts on Guest blogger

Demo site Contact us Free trial