How to freaking deploy on CloudBees, CloudFoundry, Heroku, Windows Azure, OpenShift, Elastic Beanstalk and Google AppEngine

Introduction

The following are the installation notes/instructions that correspond with our article in Infoworld entitled "Which Freaking PaaS Should I Use?". This is what you can do to reproduce the steps we used to deploy the Granny's Addressbook war file. You can find the source code to the Granny's Addressbook Spring application on Github. Granny's Addressbook was created using the Spring Tool Suite (STS) SpringMVC project template.

BTW if you need help with your PaaS migration, maybe you should contact us at sales@osintegrators.com. We'd love to help. Follow us on Twitter @osintegrators and like Open Software Integrators on Facebook or add Open Software Integrators on Google+!

CloudBees

1. http://www.cloudbees.com/
2. Sign up and log-in.
3. Subscribe to the free service.

4. Create new application, provide the name of the name of the application.

5. Upload the WAR file

6. Once uploaded the page should refresh and your app is online.
7. Subscribe to the database service by clicking ‘Manage’ under Databases on the left.

8. Chose the free option.

9. Create new database by clicking ‘Add new database’ under database on the left.

10. Follow the Database configuration tips to use PaaS database. Insert the following XML snippets into your application configuration files.

      a. Create a cloudbees-web.xml in the WEB-INF folder
      WEB-INF/cloudbees-web.xml

      <resource name="jdbc/springgrannymvcdb" auth="Container" type="javax.sql.DataSource">
          <param name="username" value="springGranny" />
          <param name="password" value="password123#" />
          <param name="url" value="jdbc:cloudbees://springgrannymvcdb" />
      </resource>
      

      b. Update the web.xml
      WEB-INF/web.xml

      <resource-ref>
          <res-ref-name>jdbc/springgrannymvcdbjavax.sql.DataSourceContainer

11. Update persistence.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
        <persistence-unit name="application" transaction-type="RESOURCE_LOCAL">
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
            <jta-data-source>java:/DefaultDS</jta-data-source>
            <properties>
                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
                <property name="hibernate.hbm2ddl.auto" value="create-drop" />
                <property name="hbm2ddl.auto" value="create-drop"/>
           </properties>
        </persistence-unit>
    </persistence>
    
    

12. Update app-context.xml

      <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
          <property name="dataSource" ref="dataSource" />
          <property name="jpaVendorAdapter" >
          <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
          <property name="generateDdl" value="true" />
          <property name="database" value="MYSQL" />
      </bean> 
      <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
          <property name="driverClassName" value="com.cloudbees.jdbc.Driver" />
          <property name="url" value="jdbc:cloudbees://springgrannymvcdb" />
          <property name="username" value="springGranny" />
          <property name="password" value="password123#" />
      </bean>
      

13. Build the WAR and redeploy as in step 5

Cloud Foundry

1. http://www.cloudfoundry.com/
2. Sign-up for free account.
3. Getting started instructions here - http://docs.cloudfoundry.com/getting-started.html

4. Add Cloud Foundry extension to STS - http://docs.cloudfoundry.com/tools/STS/configuring-STS.html#installing-t...
5. Define a new Server - http://docs.cloudfoundry.com/tools/STS/deploying-CF-Eclipse.html#define-...
6. Define MySQL service and bind it to the application - http://docs.cloudfoundry.com/tools/STS/deploying-CF-Eclipse.html#define-...

    a. Auto-reconfiguration occurs if Cloud Foundry detects a javax.sql.DataSource bean. The following snippet of a Spring application context file shows an example of defining this type of bean which Cloud Foundry will in turn detect and potentially auto-reconfigure:

<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
    <property name="driverClassName" value="org.h2.Driver" /> 
    <property name="url" value="jdbc:h2:mem:" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

The relational database that Cloud Foundry actually uses depends on the service instance you explicitly bind to your application when you deploy it: MySQL or vFabric Postgres. Cloud Foundry creates either a commons DBCP or Tomcat datasource.Cloud Foundry will internally generate values for the following properties: driverClassName, url, username, password, validationQuery.

7. Update and restart the Server.

Heroku

1. http://www.heroku.com/
2. Sign -up
3. Install heroku toolbelt - https://toolbelt.heroku.com/
4. Log in to heroku - $ heroku login
5. From the root of the code base run the following commands to create a git repo

    $ git init
    $ echo target > .gitignore
    $ git add .
    $ git commit -m init

6. Add Jetty Runner - Jetty Runner lets you easily execute your web app as a standard Java application (without having to deploy it to a container). It’s a simple jar that you can copy down from the central Maven repository to the target directory as part of you build. We’ll use the maven-dependency-plugin to do this by adding the following plugin configuration at the end of the plugins section of pom.xml:

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-dependency-plugin</artifactId>
   <version>2.3</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals><goal>copy</goal></goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>org.mortbay.jetty</groupId>
                        <artifactId>jetty-runner</artifactId>
                        <version>7.4.5.v20110725</version>
                        <destFileName>jetty-runner.jar</destFileName>
                    </artifactItem>
                    </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

7. Declare process types using Procfile - You declare how you want your application executed in Procfile in the project root. Create this file with a single line:

    web: java $JAVA_OPTS -jar target/dependency/jetty-runner.jar --port $PORT target/*.war

8. Add and commit the changes.

    $ git add .
    $ git commit -m “Ready to deploy”

9. Log in to heroku

Click on the app and test the depolyment by clicking Open application

10. Make application point to Heroku’s Postgres DB. Click on the database link under Add-ons and log in using the same username and password

11. Click on the gear next to connection settings and choose JDBC properties

12. Update app-context.xml with those values and redeploy

*****************OR******************

1. Follow steps 10 thru 12 about and create a WAR that points to Heroku’s PaaS DB.
2. Install the Heroku plugin for eclipse. Follow the instructions here https://devcenter.heroku.com/articles/getting-started-with-heroku-eclipse

    a. Perform steps all the way through ‘Create App from template’.
    b. Chose ‘Spring MVC & Tomcat application’

3. Deploy the WAR file using instructions here https://devcenter.heroku.com/articles/war-deployment#eclipse

Openshift

UPDATE Max found an easier way based on the method below or using JBDS

1. Sign up
2. Install the required packages: Ruby 1.8.7 or newer, rubygems, and git
3. Install the gem: $ sudo gem install rhc
4. Run $ rhc setup, use e-mail and password to login
+++++You can continue to use command line but I switched to the web console. ++++++
5. Click on My Apps tab in upper right corner.
6. Since you don’t already have an application you will be asked to create one. Under web cartridges pick - JBoss Application Server 7.1
7. Chose a name of the application and namespace. Continue.
8. You will be given instructions on how to access your code. In our case run

    git clone ssh://fb364383b68d41c1bf306a5759f4816a@granny-osintegrators.rhcloud.com/~/git/granny.git/
    cd granny/

9. The README file in the granny folder has very useful instructions on how to deploy the war file. Since that is what we want. Run

    git rm -r src/ pom.xml
    cp target/example.war deployments/

10. Standard git commands follow

    git add .
    git commit -m ‘whatever’
    git push

11. Test http://-.rhcloud.com/
12. Changes to make it work with OpenShift’s PostgreSQL

    a. Back to web console - Go to your application. Click Add cartridge. Pick your choice of relational DBMS. We used PostgreSQL.
    b. The name of database, username, password etc. will be chosen for you. SAVE this information. I found no way of retrieving this at a later point.
    c. Standard changes to app-context.xml, persistence.xml, pom.xml

      1. app-context.xml

      <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
          <property name="dataSource" ref="dataSource" />
          <property name="jpaVendorAdapter">
              <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
          <property name="generateDdl" value="true" />
          <property name="database" value="POSTGRESQL" />
      </bean>
             
      <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
          <property name="driverClassName" value="org.postgresql.Driver" />
          <property name="url" value="jdbc:postgresql://127.4.192.1:5432/granny" />
          <property name="username" value="admin" />
          <property name="password" value="pCpy-xQbbFHi" />
      </bean>
      

      2. persistence.xml

      <persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
         version="1.0">
          <persistence-unit name="application" transaction-type="RESOURCE_LOCAL">
              <provider>org.hibernate.ejb.HibernatePersistence</provider>
              <jta-data-source<java:jboss/datasources/ExampleDS>/jta-data-source>
              <class>com.osintegrators.example.Address</class>
              <properties>
                  <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
                  <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
                  <property name="hbm2ddl.auto" value="create-drop"/>
              </properties>
          </persistence-unit>
      </persistence>
      

      3. pom.xml - add the postgres dependency

      <dependency>
          <groupId>postgresql</groupId>
          <artifactId>postgresql</artifactId>
          <version>8.4-702.jdbc4</version>
      </dependency>
      

    d. Redeploy

      git rm deployments/example.war.dodeploy deployments/example.war

      cp target/example.war deployments/
      git add .
      git commit -m ‘whatever’
      git push

AWS Elastic Beanstalk

1. Sign up and log in to the AWS management console - https://console.aws.amazon.com/elasticbeanstalk/home
2. Choose upload your own application.

3. Name the application, optional description and container type.

4. Name your environment

5. Configure your environment. I chose default values.

6. Review your details and click finish

7. Wait several minutes as the EC2 instance is added to the load balancers

8. Wait for the “green light” and test the application.

9. Log in to RDS console - https://console.aws.amazon.com/rds/home, click ‘Launch a DB Instance’

10. Chose MySql

11. Database instance details

12. Additional configuration details

13. Choose management options

14. Review information and click launch
15. Wait for instance to start.
16. pom.xml - mysql dependency

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
    </dependency>
    

17. persistence.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
       version="1.0">
        <persistence-unit name="application" transaction-type="RESOURCE_LOCAL">
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
            <jta-data-source>java:/DefaultDS</jta-data-source>
            <properties>
                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
                <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
                <property name="hbm2ddl.auto" value="create-drop"/>
            </properties>
        </persistence-unit>
    </persistence>
    

18. app-context.xml

    <bean id="entityManagerFactory"
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter"/
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="generateDdl" value="true" />
        <property name="database" value="MYSQL" />
    </bean>
           
    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://grannydb.cabwwabovy0a.us-east-1.rds.amazonaws.com:3306/grannydb" />
        <property name="username" value="granny" />
        <property name="password" value="password123#" />
    </bean>
    

    So far the setup has been fairly straightforward. However connection to Amazon RDS (MySQL) times out. Cursory research shows other people who have encountered this and it appears that the solution lies in adding IPs to a security group (https://forums.aws.amazon.com/thread.jspa?messageID=247971). Also there isn’t any customer support beyond the available online documentation for basic users - http://aws.amazon.com/premiumsupport/

    Windows Azure

    1. Sign up and log in - https://manage.windowsazure.com
    2. Called me on my phone and asked if I needed assistance with what I doing (that was nice of them)

    3. On Linux, tried installing the Azure plugin. Plugin install’s fine. When you try to use it will ask you to install the SDK and directs you to an .exe file. This would work fine on Windows, not sure what to do on Linux. I have downloaded the SDK but I’m not sure how to point eclipse/STS to it.
    4. A discussion here suggests for existing apps you’re better deploying whatever you need on a virtual machine. If you were starting from scratch might as well start on the Windows platform - http://stackoverflow.com/questions/9627887/is-it-possible-to-develop-for...
    Figured a partially PaaSy way to do this on Windows “The Windows Azure Plugin for Eclipse with Java is not designed to work on Linux, because it has to rely on the packaging tools that ship as part of the Windows Azure SDK for .NET, which are Windows-only today” so Windows it is!!
    1. Perform the prerequistes here - http://msdn.microsoft.com/en-us/library/windowsazure/hh690944(VS.103).aspx
    1. Install your favorite application Server. I installed Apache tomcat.
    2. Build the WAR file and copy it to your Tomcat’s webapp folder
    3. Test locally http://localhost:8080/
    4. Start eclipse. Click the Azure icon in your toolbar. I’m assuming you’ve successfully installed the Azure plugin.
    Do step 6 under ‘To create a Hello World application’ - http://msdn.microsoft.com/en-us/library/windowsazure/hh690944(VS.103).aspx
    5. Follow the instruction under ‘To deploy your application to Windows Azure’
    6. Wait for it to complete publishing and deploying.
    7. Test you app at http://.cloudapp.net/
    The PaaSy part
    8. Create SQL Server instance
    1. Log in https://manage.windowsazure.com/
    2. Click SQL DATABASES on the left -> Click Add on the bottom of the portal. Ente you database info

    3. Enter credentials

    4. Once the Server is up, click on it and click ‘Show connection strings’ on the right. Using the info under JDBC make the following changes and then build you WAR and replace it Tomcat’s webapps folder

    1. persistance.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
       version="1.0">
        <persistence-unit name="application" transaction-type="RESOURCE_LOCAL">
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <jta-data-source>java:/DefaultDS</jta-data-source>
          <properties>
             <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/>
             <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
             <property name="hbm2ddl.auto" value="create-drop"/>
          </properties>
       </persistence-unit>
    </persistence>
    

    2. app-context.xml

    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
          <property name="dataSource" ref="dataSource" />
          <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
              <property name="generateDdl" value="true" />
              <property name="database" value="SQL_SERVER" />
            </bean>
          </property>
        </bean>
       
        <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
            <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
            <property name="url" value="jdbc:sqlserver://mpe2l9e2bg.database.windows.net:1433;database=grannydb" />
            <property name="username" value="granny" />
            <property name="password" value="password123#" />
        </bean>
    </beans>
    

    3. pom.xml - Add dependency

             <dependency>
                 <groupId>com.microsoft.sqlserver</groupId>
                 <artifactId>sqljdbc4</artifactId>
                 <version>4.0</version>
             </dependency>
    

    Google App Engine

    From https://developers.google.com/appengine/docs/java/gettingstarted/creating
    “App Engine Java applications use the Java Servlet standard for interacting with the web server environment. An application's files, including compiled classes, JARs, static files and configuration files, are arranged in a directory structure using the WAR standard layout for Java web applications. You can use any development process you like to develop web servlets and produce a WAR directory. (WAR archive files are not yet supported by the SDK.)”

    1. Log in to appengine.google.com with your google account.
    2. Create a new application and remember the application id.
    3. Install the Google App engine plugin for Eclipse - https://developers.google.com/appengine/docs/java/tools/eclipse
    4. Restart eclipse. You’re see the google icon in the toolbar. Click it and select New Web Application project.
    5. Then followed instructions from here - http://www.mkyong.com/google-app-engine/google-app-engine-spring-3-mvc-r... Basically replicate your WAR folder structure.
    6. Test it using the link provided. It should be http://.appspot.com
    7. Logs are available to you through the console. Main -> Logs That’s as far as I could get
    8. Something else you could try - http://www.javacodegeeks.com/2011/12/spring-mvc-and-rest-at-google-app.html

    Thanks!

    Wow you made it all the way to the bottom! If you're considering a Cloud migration, maybe you need help? If so, please contact sales@osintegrators.com. For other inquiries about this article or general PR inquiries contact info@osintegrators.com.

    Haven't had enough Cloud, Big Data and NoSQL? Later in the week we have something even more special! Stay tuned :-)

    Going to SpringOne?

    Our president, Andrew C. Oliver will be at SpringOne next week. He'd love to meet you. Contact us at info@osintegrators.com and we'll set up an appointment.