Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!
NoSQL Zone is brought to you in partnership with:

Eric is a former teacher and future time traveler who has returned to the present to work at DZone - the coolest site on earth. He likes reading and curating about NoSQL and Cloud development, and is always excited to see something new, shiny, and distracting. In his free time, Eric likes knowing more about movies than you do, and looking forward to when the unified Chinese-American Corpocracy will develop the technology needed for transport to the year 2056. Eric is a DZone Zone Leader and has posted 149 posts at DZone. You can read more from them at their website. View Full User Profile

Spring onto Heroku

01.31.2012
Email
Views: 5413
  • submit to reddit
This article is part of the DZone NoSQL Resource Portal, which is brought to you in collaboration with Neo Technology and DataStax. Visit the NoSQL Resource Portal for additional tutorials, videos, opinions, and other resources on this topic.
Deploying your application into the cloud is a great way to scale from "wouldn't it be cool if.." to giving interviews to Forbes, Fast Company, and Jimmy Fallon. Heroku makes it super easy to provision everything you need, including a Neo4j Add-on. With a few simple adjustments, your Spring Data Neo4j application is ready to take that first step into the cloud.
Let's walk through the process, assuming this scenario:

  • you have an account on Heroku, and have installed the heroku tool
  • git is your friend 
  • you've developed a killer Spring MVC application 
  • and of course you're using Spring Data Neo4j 

Ready? OK, first let's look at your application.

The content of this article was originally posted on Andreas Kollegger's Neo4j Blog

Create a Self-Hosted Web Application


Usually, a Spring MVC application is bundled into a war and deployed to an application server like Tomcat. But Heroku can host any kind of Java application; it just needs to know what to launch. So, we'll transform the war into a self-hosted servlet using an embedded Jetty server, then add a start-up script to launch it.
First, add the dependencies for Jetty to the pom.xml:

<dependency>
  <groupid>org.eclipse.jetty</groupid>
  <artifactid>jetty-webapp</artifactid>
  <version>7.4.4.v20110707</version>
</dependency>
<dependency>
  <groupid>org.mortbay.jetty</groupid>
  <artifactid>jsp-2.1-glassfish</artifactid>
  <version>2.1.v20100127</version>
</dependency>
Then change the scope of the servlet-api artifact from provided to compile. This library is normally provided at runtime by the application container. Since we're self-hosting, it needs to be included directly. Make sure the servlet-api dependency looks like this:

<dependency>
  <groupid>javax.servlet</groupid>
  <artifactid>servlet-api</artifactid>
  <version>2.5</version>
  <scope>compile</scope>
</dependency>
We could provide a complicated command-line to Heroku to launch the app. Instead, we'll simplify the command-line by using the appassembler-maven-plugin to create a launch script. Add the plugin to your pom's build/plugins section:

<plugin>
  <groupid>org.codehaus.mojo</groupid>
  <artifactid>appassembler-maven-plugin</artifactid>
  <version>1.1.1</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals><goal>assemble</goal></goals>
      <configuration>
        <assembledirectory>target</assembledirectory>
        <extrajvmarguments>-Xmx512m</extrajvmarguments>
        <programs>
          <program>
            <mainclass>Main</mainclass>
            <name>webapp</name>
          </program>
        </programs>
      </configuration>
    </execution>
  </executions>
</plugin>
Finally, switch the packaging from war to jar. That's it for the pom. Now that the application is ready to be self-hosted, create a simple Main to bootstrap Jetty and host the servlet. The pom snippet above assumes a src/main/java/Main.java that looks like:

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;
public class Main {
  public static void main(String[] args) throws Exception {
    String webappDirLocation = "src/main/webapp/";
    String webPort = System.getenv("PORT");
    if(webPort == null || webPort.isEmpty()) {
      webPort = "8080";
    }
    Server server = new Server(Integer.valueOf(webPort));
    WebAppContext root = new WebAppContext();
    root.setContextPath("/");
    root.setDescriptor(webappDirLocation+"/WEB-INF/web.xml");
    root.setResourceBase(webappDirLocation);
    root.setParentLoaderPriority(true);
    server.setHandler(root);
    server.start();
    server.join();
  }
}
Notice the use of environment variable PORT for discovering which port to use. Heroku and the Neo4j Add-on use a number of environment variables to configure the application.
Next, we'll modify the Spring application context to use the Neo4j variables for specifying the connection to Neo4j itself.
For example, if you have src/main/resources/META-INF/spring/applicationContext-graph.xml, then modify it to look like this:

<neo4j:config graphdatabaseservice="graphDatabaseService">
  <bean class="org.springframework.data.neo4j.rest.SpringRestGraphDatabase" id="graphDatabaseService">
    <constructor-arg index="0" value="${NEO4J_REST_URL}">
    <constructor-arg index="1" value="${NEO4J_LOGIN}">
    <constructor-arg index="2" value="${NEO4J_PASSWORD}">
</constructor-arg></constructor-arg></constructor-arg></bean>
</neo4j:config>
Before provisioning at Heroku, test the application locally. First make sure you've got Neo4j server running at http://localhost:7474, using default configuration. Then set the following environment variables (here, assuming bash):
export NEO4J_REST_URL=http://localhost:7474/db/data
export NEO4J_LOGIN=""
export NEO4J_PASSWORD=""
Now you can launch the app by running sh target/bin/webapp. If all went well, your application will be available just as if it were in a Tomcat container.


Deploy to Heroku


With a self-hosted application ready, deploying to Heroku needs a few more steps. First, create a Procfile at the top-level of the project, which will contain a single line identifying the command line which launches the application. The contents of the Procfile should contain one line:
sh target/bin/webapp
Then use git to magically deploy to Heroku:

# Initialize a local git repository, adding all the project files
git init
git add .
git commit -m "initial commit"
# Provision a Heroku stack, add the Neo4j Add-on and deploy the appication
 
heroku create --stack cedar
heroku addons:add neo4j
git push heroku master
Note that the heroku stack must be "cedar" to support running Java. Check that the process is running by using heroku ps, which should show a "web.1" process in the "up" state.
Success! Your application is now live in the cloud.
To see the Neo4j graph you just created through Heroku, use heroku config to reveal the NEO4J_URL environment variable, which will take you to Neo4j's Webadmin.


Summary


All that typing really comes down to three steps:

  1. make your application self-hosting
  2. access Heroku environment variables for configuration
  3. deploy to the cloud
Now go upgrade your application and join us in the cloud. It's always sunny up here.


Source:  http://blog.neo4j.org/2012/01/spring-onto-heroku.html



(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Neo Technology and DataStax are leading the charge for the NoSQL movement.  You can learn more about the Neo4j Graph Database in the project discussion forums and try out the new Spring Data Neo4j, which enables POJO-based development.  You can also see how Apache Cassandra, a ColumnFamily data store, is pushing the boundaries of persistence with cloud capabilities and deployments at SocialFlow and Netflix.

Comments

Afandi Merathi replied on Fri, 2012/03/16 - 11:30am

I would like to participate in the Neo4j Challenge... I think it is very cool and I might have four (4) Neo4j/Spring Data apps ready for deploying.

I followed the steps on Gensen and it seems that participants must go through the heroku billing process. Which I think it is an unnecessary requirement for community members that would like to contribute with source code to the Neo4j cause.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.