Neo4Art moves to Cloud Foundry at SpringOne 2GX 2014

I’m really proud to write this post about the oversea trip for Neo4Art. Last week in fact Neo4Art was presented at SpringOne 2GX conference in Dallas as live-demo during Michael Hunger and my session “Artistic Spring Data Neo4j 3.x with Spring Boot and Van Gogh“.

 

Artistic Spring Data Neo4j 3.s with Spring Boot and Van Gogh

 

SpringOne 2GX is “a one-of-a-kind conference for application developers, solution architects, web operations and IT teams who develop business applications, create multi-device aware web applications, design cloud architectures, and manage high performance infrastructure …“, for everyone “… using the hugely popular open source Spring IO projects, Groovy & Grails, Cloud Foundry, Hadoop and Tomcat technologies” and people that are “building and running mission-critical business applications, designing the next killer cloud or big data application, SpringOne 2GX will keep you up to date with the latest enterprise open source technology“.

 

springone2gx-projected

 

1. Intro

Before landing in Dallas my studies about Neo4j culminated with the implementation of a search engine for Van Gogh’s artworks with Spring Data Neo4j as the solution to implement persistence tier, while presentation tier was implemented as a bit more classical Spring MVC application plus MapQuest.

Search engine queries were made available in the form of a Neo4j Server Extensions, thus developed as REST services (i.e. Jersey Resources):

  • Get Museums Within Distance:

http://{neo4j_server}:{neo4j_port}/neo4art/museums/lon/-0.1283/lat/51.5086/distanceInKm/10.0
  • Get Artworks By Museum:

http://{neo4j_server}:{neo4j_port}/neo4art/artworks/museum/1051

You can read more here, but for our talk at the SpringOne 2GX conference we wanted to enjoy with something more!

  • First of all, we wanted to introduce Spring-Boot to highlight how powerful it is in accelerating and simplifying the configuration and the creation of production-ready Spring-based application. We wanted to demonstrate how to configure Spring Data Neo4j with Spring Boot, instead of recurring to more classical XML file and @Configuration classes as well;
  • Then, since we had Vikram Rana and Charles Wu – Cloud Foundry team’s engineers – right there, we wanted to take advantage of that and move Neo4Art to their cloud.

2. Simplify your life with Spring-Boot

As you can read here: “Spring Boot favors convention over configuration and is designed to get you up and running as quickly as possible …“, and here: “Spring Boot offers a fast way to build applications. It looks at your classpath and at beans you have configured, makes reasonable assumptions about what you’re missing, and adds it. With Spring Boot you can focus more on business features and less on infrastructure“.

spring-boot-project-logo

When we decide to adopt Spring Boot and Spring Data Neo4j it means for us to take the following 5 simple steps:

  • Adding Spring Boot depencencies
  • Configuring Spring Boot
  • Adding Spring Data Neo4j depencencies [only for the embedded version]
  • Configuring Spring Data Neo4j [only for the embedded version]
  • Running application

2.1 Spring Boot Dependencies

First, we inherit defaults from Spring Boot parent project:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.6.RELEASE</version>
</parent>

then we declare dependencies to one or more “Starter POMs”. In our example we only need support for web development, so we include spring-boot-starter-web, that allows us to develop full-stack web application, including Tomcat and spring-webmvc.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

2.2 Spring Boot Configuration

Applications that relies on Spring Boot require a single Java file. This class contains the all the configurations we need, and it implements the main method, that we can run from command line to start our application.

In our example (see full version on Github):

@EnableAutoConfiguration
@ComponentScan(basePackages = {"it.inserpio.neo4art.service.impl","it.inserpio.neo4art.controller"})
@Import(MyNeo4jConfiguration.class)
public class ArtworkApplication {
    public static void main(String[] args) throws IOException {
        SpringApplication.run(ArtworkApplication.class, args);
    }
}

The @EnableAutoConfiguration tells Spring Boot how we want our application to be configured. Spring Boot analyses the jar dependencies that we have added and since spring-boot-starter-web is among our dependencies, the @EnableAutoConfiguration will assume that we are developing a web application and setup Spring by adding Tomcat and Spring MVC.

The main method delegates to Spring Boot’s SpringApplication class by calling run. SpringApplication will bootstrap our application, starting Spring which will in turn start the auto-configured Tomcat web server.

@Import includes another configuration file. In our example we include the Spring Data Neo4j configuration file.

2.3 Spring Data Neo4j Dependencies [only for the embedded version]

When we decide to use an embedded local Neo4j graph database we need to specify only two Spring Data Neo4j dependency:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j</artifactId>
    <version>${spring.data.neo4j.version}</version>
</dependency>

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-neo4j-rest</artifactId>
    <version>${spring.data.neo4j.version}</version>
</dependency>

A third one is necessary just when we need to execute geo-spatial queries (in our example we execute queries like “find museums within distance”):

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-spatial</artifactId>
    <version>${neo4j.spatial.version}</version>
</dependency>

2.4 Spring Data Neo4j Configuration [only for the embedded version]

Spring Data Neo4j can be configured extending the class Neo4jConfiguration, so we inherit the setBasePackage method that allows us to specify which packages contain our node entity classes.

In our example (see full version on Github):

@Configuration
@EnableNeo4jRepositories(basePackages = "it.inserpio.neo4art.repository")
@EnableTransactionManagement
public class MyNeo4jConfiguration extends Neo4jConfiguration {
    public static final String PATH = System.getProperty("user.home") + "/neo4art/graph.db";

    public MyNeo4jConfiguration() {
        setBasePackage("it.inserpio.neo4art.domain");
    }

    @Bean
    public GraphDatabaseService graphDatabaseService() {
        return new GraphDatabaseFactory().newEmbeddedDatabase(PATH);
    }
}

Packages containing repository classes can be specified using the @EnableNeo4jRepositories annotation.

Finally, we create a GraphDatabaService bean, which is actually our embedded graph database instance.

2.5 Running our Spring Boot application

Since spring-boot-started-web added a Tomcat embedded instance, it’s no more necessary to deploy our war with some tools – or even worse manually :-/

All we have to do is running this command from a shell:

$ mvn spring-boot:run

3. Adopting Cloud Foundry

Moving Neo4Art to Cloud Foundry has been really easy!

cloud-foundry

Here you can access the Pivotal Web Services documentation.

3.1 Sign-Up

Go to Cloud Foundry, select “Pivotal Web Services” and provide your account data.

3.2 Create an organisation

After signing-up, you have to create an organisation:

Cloud Foundry - Create Organization

3.3 Install the command line interface

The command line tool cf is the primary tool for deploying and managing your applications.

Here you can find the CLI documentation: http://docs.run.pivotal.io/devguide/installcf/install-go-cli.html

and this is the download page: https://github.com/cloudfoundry/cli/releases.

For my MAC:

3.4 Deploying Neo4art on Cloud Foundry

To be able to deploy your application through the command line tool it’s necessary to log in first. This is the command:

$ cf login [-a API_URL] [-u USERNAME] [-p PASSWORD] [-o ORG] [-s SPACE]

In our example:

$ cf login -a neo4art

Here you can find the documentation: http://docs.run.pivotal.io/devguide/deploy-apps/deploy-app.html

This step targets the Cloud Foundry public API endpoint `api.run.pivotal.io` and establishes your connection to Pivotal Web Services.

Cloud Foundry can deploy with an application Manifest, but you can provide your binary packed file as well. After running mvn clean package to build your war, all you have to do is running the command cf push providing two parameters: the first one is the application name and the second one is the war file:

cf push neo4art -p target/neo4art.war

Once the deployment phase is completed, you should see something similar on the Pivotal Web Services Console:

pws-console-01 pws-console-02 pws-console-04

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.5 Cloud Foundry User-provided Services

User-provided service instances allow you to represent external assets like databases, messaging services, and key-value stores in Cloud Foundry.

To create a services we have to use the following command:

$ cf cups SERVICE_INSTANCE -p '{"username":"my_username","password":"my_password"}'

In our example we want to bind our neo4j graph database instance hosted on GrapheneDB:

$ cf cups graphenedb-neo4art-sdn301 -p '{"url":"http://neo4artsdn301.sb02.stations.graphenedb.com:24789/db/data/", "usr":"neo4art-sdn301", "pwd":"***********"}'

Creating user provided service *`graphenedb-neo4art-sdn301`* in org *`LARUS\* / space \*development*` as \*lorenzo.speranzoni@larus-ba.it*`...
*OK*

Now, we can check that our service is defined and configured on PWS by running the command:

$ cf services
Getting services in org LARUS / space development as lorenzo.speranzoni@larus-ba.it...
OK

name                        service         plan   bound apps 
graphenedb-neo4art-sdn301   user-provided          neo4art

Now we have to binding the service we have just created to our app:

$ cf bind-service neo4art graphenedb-neo4art-sdn301

Binding service *`graphenedb-neo4art-sdn301`* to app *`neo4art`* in org *`LARUS\* / space \*development*` as *`lorenzo.speranzoni@larus-ba.it`*...
OK

Here is what we see in the Pivotal Web Services Console:

pws-console-03 pws-console-05 pws-console-06 pws-console-07

 

 

 

 

 

 

 

 

 

 

 

 

 

Now that our service is created and bound to the application, we need to configure the application to dynamically fetch the credentials for your service.

These credentials are stored in the VCAP_SERVICES environment variable:

$ cf env neo4art

Getting env variables for app neo4art in org LARUS / space development as lorenzo.speranzoni@larus-ba.it...
OK
System-Provided:
{
  "VCAP_SERVICES": {
    "user-provided": [
      {
        "credentials": {
          "pwd": "***********",
          "url": "http://neo4artsdn301.sb02.stations.graphenedb.com:24789/db/data/",
          "usr": "neo4art-sdn301"
        },
        "label": "user-provided",
        "name": "graphenedb-neo4art-sdn301",
        "syslog_drain_url": "",
        "tags": []
      }
    ]
  }
}

There are generally two methods for these consuming credentials:

  • Auto-configuration: Some buildpacks create a service connection for you by creating additional environment variables, updating config files, or passing system parameters to the JVM.
  • Manual: Parse the JSON yourself. Helper libraries are available for some frameworks.

When developing a Spring application you can define a @Configuration class like:

@Configuration
public class CloudConfig extends AbstractCloudConfig {

    @Bean
    public Search search() {
       return connectionFactory().service("search-service"), Search.class);
    }
}

In our example (see full version on Github):

@Configuration
public class Neo4jConnectionService extends AbstractCloudConfig {

    @Bean
    public Neo4jServiceInfo neo4jServiceInfo() {
        Neo4jServiceInfoCreator neo4jServiceInfoCreator = new Neo4jServiceInfoCreator();
        return neo4jServiceInfoCreator.createServiceInfo(
            CloudFoundryServiceManager.getService("graphenedb-neo4art-sdn301"));
    }
}

4. Neo4j as a Service on GrapheneDB

Once again my graph database is hosted on GrapheneDB, a cloud hosting platform for Neo4j that “offers a variety of plans to go with your application’s lifecycle, including free sandbox instances to get you started“.

I’ve already written a couple of posts about using GrapheneDB to host your Neo4j instances in the cloud and about installing a server extension on it. If you’re interest you can read more here:

Of course you can read full GrapheneDB documentation here or more in detail:

 

graphenedb

5. Conclusion

Big thanks to Michael Hunger, Adam Herzog, Kevin Van GundyAlberto Perdomo, Scott Frederick, Ramnivas Laddad, Vikram Rana, Charles Wu, GrapheneDB, PivotalCloud Foundry and Neo4j for their precious help.

Here you can access Neo4Art deployed on Cloud Foundry + GrapheneDB: http://neo4art.cfapps.io/artworksRadar

 

springone2gx

Advertisements

One thought on “Neo4Art moves to Cloud Foundry at SpringOne 2GX 2014

  1. Pingback: Neo4j at SpringOne 2GX 2014 - Neo4j Graph Database

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s