Installing and Configuring RabbitMQ

rabbitmq logo

RabbitMQ and AMQP (Advanced Message Queuing Protocol) are gaining momentum in the market. One of the main reasons for that momentum is because, in enterprise development, the client is not always Java specific. With RabbitMQ, we can configure a scalable, fault-tolerant, open-source messaging solution for polyglot clients, click here to see a list of client language support.

Follow the steps below to install and configure RabbitMQ v1.7.x on a MAC with OSX Lion. Click here for installation instructions for Windows and other platforms.


1. Installing RabbitMQ

Mac OSX Lion Installation

Install HomeBrew

From the terminal prompt:

$ brew install rabbitmq

We do NOT need to install Erlang, however, if desired use Brew as follows:

$ brew install erlang

HomeBrew RabbitMQ Directories

  • Logs: /usr/local/var/log/rabbitmq
  • Config: /usr/local/etc/rabbitmq
  • Mnesia Database: /usr/local/var/lib/rabbitmq/mnesia
  • Erlang cookie: <homedir>/.erlang.cookie

Mnesia is a NoSql database that stores RabbitMQ configuration data – Mnesia Reference Manual.


2. Configuring RabbitMQ Server

When RabbitMQ is installed, not all of the configuration files exist.

Do not be concerned if the install does not contain the files mentioned, simply create the text files and use the contents provided below as a base.

In the rabbitmq-env.conf file, any variables referenced can be set using an environment variable with the prefix RABBITMQ_, for example NODE_PORT=5672 can be set as an environment variable export RABBITMQ_NODE_PORT=5672

N.B. the system name in the examples is “Technophiliac”. In configuring your system, simply change all references from “Technophiliac” to your system name.

RabbitMQ Environment Configuration File

Create or edit /usr/local/etc/rabbitmq/rabbitmq-env.conf

# ##############################
# RABBITMQ SERVER CONFIGURATION
#
# All of the parameters below can also
#   be set as environment variables
#   using the prefix "RABBIT_"
#   i.e.  export RABBITMQ_NODE_PORT=5672
## ##############################

# ##########################
# Defaults to the empty string
#   meaning bind to all network interfaces
# Change to bind to one network interface only
# ##########################
# NODE_IP_ADDRESS=
# NODE_PORT=5672

# ##########################
# Unix, Linux: `env hostname`
# MacOSX: `env hostname -s`
# The name of the current machine
# ##########################
# HOSTNAME=

# ##########################
# The name of the current machine
# ##########################
# COMPUTERNAME=

# ##########################
# This base directory contains sub-directories for
#   server's db and log files
# Alternatively, set MNESIA_BASE and LOG_BASE individually
# ##########################
# BASE=

# ##########################
# Mac/Unix: rabbit@$HOSTNAME
# The node name should be unique per erlang-node-and-machine combination
# To run multiple nodes, see the clustering guide
# ##########################
# NODENAME=

# ##########################
# Mac: /usr/local/etc/rabbitmq/rabbitmq
# If the configuration file is present it is used by the server
# The .config extension is automatically appended
# This file is also used to auto-configure RabbitMQ clusters
# Example:
#   Config file location and new filename bunnies.config
#   CONFIG_FILE=/usr/local/etc/rabbitmq/bunnies
# ##########################
CONFIG_FILE=/usr/local/etc/rabbitmq/rabbitmq

# ##########################
# Mac: /usr/local/var/lib/rabbitmq/mnesia
# The Mnesia database files directory
#
# MNESIA_DIR will be assembled as MNESIA_BASE/NODENAME
# ##########################
# MNESIA_BASE=
# MNESIA_DIR=

# ##########################
# Mac: /usr/local/var/log/rabbitmq
# Log files generated by the server will be placed in this directory.
# ##########################
# LOG_BASE=/usr/local/var/log/rabbitmq

# ##########################
# The plugins directory
# ##########################
PLUGINS_DIR=/usr/local/Cellar/rabbitmq/2.7.1/lib/rabbitmq/erlang/lib/rabbitmq-2.7.1/plugins

# ##########################
# Mac: /usr/local/etc/rabbitmq/enabled_plugins
# This file declares explicitly enabled plugins
# ##########################
ENABLED_PLUGINS_FILE=/usr/local/etc/rabbitmq/enabled_plugins

RabbitMQ Server Configuration File

Create or edit the file /usr/local/etc/rabbitmq/rabbitmq.config

[{auth_backends,[rabbit_auth_backend_internal]},
 {auth_mechanisms,['PLAIN','AMQPLAIN']},
 {backing_queue_module,rabbit_variable_queue},
 {cluster_nodes,[]},
 {collect_statistics,fine},
 {collect_statistics_interval,5000},
 {default_permissions,[<<".*">>,<<".*">>,<<".*">>]},
 {default_user,<<"guest">>},
 {default_user_tags,[administrator]},
 {default_vhost,<<"/">>},
 {delegate_count,16},
 {error_logger,{file,"/usr/local/var/log/rabbitmq/rabbit@Technophiliac.log"}},
 {frame_max,131072},
 {hipe_compile,false},
 {included_applications,[]},
 {msg_store_file_size_limit,16777216},
 {msg_store_index_module,rabbit_msg_store_ets_index},
 {queue_index_max_journal_entries,262144},
 {sasl_error_logger,{file,"/usr/local/var/log/rabbitmq/rabbit@Technophiliac-sasl.log"}},
 {server_properties,[]},
 {ssl_listeners,[]},
 {ssl_options,[]},
 {tcp_listen_options,
   [binary,
     {packet,raw},
     {reuseaddr,true},
     {backlog,128},
     {nodelay,true},
     {exit_on_close,false}]},
 {tcp_listeners,[5672]},
 {trace_vhosts,[<<"/">>]},
 {vm_memory_high_watermark,0.4}]


3. Configuring RabbitMQ Console Plugins

RabbitMQ Console Plugins File

Create or edit the text file /usr/local/etc/rabbitmq/enabled_plugins

Include the following content (don’t forget the period at the end)

[rabbitmq_jsonrpc_channel,
 rabbitmq_jsonrpc_channel_examples,
 rabbitmq_management,
 rabbitmq_management_visualiser,
 rabbitmq_tracing].


4. Set Environment Variables

export RABBITMQ_HOME=/usr/local/Cellar/rabbitmq/2.7.1
export HOMEBREW_LIBRARY_PATH=$HOMEBREW_LIBRARY_PATH:$LD_LIBRARY_PATH
export CPLUS_INCLUDE_PATH=/usr/local/include:$CPLUS_INCLUDE_PATH
export PYTHONPATH=/usr/local/lib/python2.7/site-packages:/usr/local/lib/python:$PYTHONPATH
export LDFLAGS=-L/usr/local/Cellar/readline/6.2.2/lib
export CPPFLAGS=-I/usr/local/Cellar/readline/6.2.2/include


5. Starting RabbitMQ

$ sudo rabbitmq-server

We will see the following console output:

Activating RabbitMQ plugins ...
12 plugins activated:
* amqp_client-0.0.0
* mochiweb-1.3-rmq0.0.0-git
* rabbitmq_jsonrpc-0.0.0
* rabbitmq_jsonrpc_channel-0.0.0
* rabbitmq_jsonrpc_channel_examples-0.0.0
* rabbitmq_management-0.0.0
* rabbitmq_management_agent-0.0.0
* rabbitmq_management_visualiser-0.0.0
* rabbitmq_mochiweb-0.0.0
* rabbitmq_tracing-0.0.0
* rfc4627_jsonrpc-0.0.0-git
* webmachine-1.7.0-rmq0.0.0-hg

+---+   +---+
|   |   |   |
|   |   |   |
|   |   |   |
|   +---+   +-------+
|                   |
| RabbitMQ  +---+   |
|           |   |   |
|   v2.7.1  +---+   |
|                   |
+-------------------+
AMQP 0-9-1 / 0-9 / 0-8
Copyright (C) 2007-2011 VMware, Inc.
Licensed under the MPL.  See http://www.rabbitmq.com/

node           : rabbit@Technophiliac
app descriptor : /usr/local/Cellar/rabbitmq/2.7.1/lib/rabbitmq/erlang/lib/rabbitmq-2.7.1/ebin/rabbit.app
home dir       : /Users/gordondickens
config file(s) : /usr/local/etc/rabbitmq/rabbitmq.config
cookie hash    : VBuPLzEtAR8Sdq9eR1g36w==
log            : /usr/local/var/log/rabbitmq/rabbit@Technophiliac.log
sasl log       : /usr/local/var/log/rabbitmq/rabbit@Technophiliac-sasl.log
database dir   : /usr/local/var/lib/rabbitmq/mnesia/rabbit@Technophiliac
erlang version : 5.8.5

-- rabbit boot start
starting file handle cache server                                     ...done
starting worker pool                                                  ...done
starting database                                                     ...done
starting codec correctness check                                      ...done
-- external infrastructure ready
starting plugin registry                                              ...done
starting auth mechanism cr-demo                                       ...done
starting auth mechanism amqplain                                      ...done
starting auth mechanism plain                                         ...done
starting statistics event manager                                     ...done
starting logging server                                               ...done
starting exchange type direct                                         ...done
starting exchange type fanout                                         ...done
starting exchange type headers                                        ...done
starting exchange type topic                                          ...done
-- kernel ready
starting alarm handler                                                ...done
starting node monitor                                                 ...done
starting cluster delegate                                             ...done
starting guid generator                                               ...done
starting memory monitor                                               ...done
-- core initialized
starting empty DB check                                               ...done
starting management agent                                             ...done
starting exchange, queue and binding recovery                         ...done
starting mirror queue slave sup                                       ...done
starting adding mirrors to queues                                     ...done
-- message delivery logic ready
starting error log relay                                              ...done
starting networking                                                   ...done
starting direct_client                                                ...done
starting notify cluster nodes                                         ...done

broker running
** Found 0 name clashes in code paths


The Console

After RabbitMQ starts, go to the console http://localhost:55672/
NOTE: The default user id/password is guest/guest.


Summary

In this blog we saw the steps to install and configure RabbitMQ to run locally on Mac OSX Lion. In the next blog, I’ll introduce the concepts of AMQP exchanges, routes and queues, using Groovy Scripts to create and test them. We will also discover how to visualize those components and their relationships within the console.

Posted in AMQP, Erlang, HomeBrew, RabbitMQ | Tagged , , , | Leave a comment

Unit Testing Spring with Mockito & PowerMock

Unit Testing Spring with Mockito & PowerMock

I’ve updated my Spring Mockito Demo app that I demonstrate when teaching with a PowerMock of a final class with a static method.



Demo Features

  • Maven 3.0
  • Maven Enforcer plugin restricting use of commons-logging, log4j, slf4j > 1.5, maven version range & java 1.6
  • All Maven plugin and java dependency versions are current and managed in properties of pom.xml
  • Maven Versions plugin for evaluating current configuration for any version updates of dependencies
    • mvn versions:display-dependency-updates scans dependencies and reports dependencies with newer versions
    • mvn versions:display-plugin-updates scans plugins and reports plugins with newer versions
    • To get the version changes w/o the ones that haven’t changed : mvn versions:display-dependency-updates | grep " -> "
  • Logback configuration with SLF4J
  • Mockito tests of the controller layer (services are mocked)
  • PowerMock configuration testing a final class with static method
  • All tests are true Unit tests, no use of Spring Context in tests, including the context creates integration tests

Code Repository

https://github.com/gordonad/core-spring-demos/tree/master/demos/mockitodemo




Want to Learn More?

Learn more about Spring by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in LogBack, Logging, Maven, Mocking, Mockito, PowerMock, SLF4J, Spring Framework, Spring MVC, Testing | Tagged , , , , , , , , | Leave a comment

Buzzing the Cloud with CloudBees and Roo

Looking to try out CloudBees for your Spring application?

Here is how you can get started quickly with CloudBees Run@Cloud platform.

  1. Get a CloudBees Account
  2. Configure a MySql instance on CloudBees
  3. Build a Spring Roo application
    see script below
  4. Create a cloudbees-web.xml file in WEB-INF
    same directory as web.xml
  5. Add Maven CloudBees Plugin
  6. Build and deploy with Maven
    mvn clean install bees:deploy


Roo 1.2.0 Script

Here is a simple item manager application script you can use/customize to create your application

# FOR SPRING ROO 1.2 - Spring Data JPA and Service Layer

development mode --enabled true

project --topLevelPackage com.gordondickens.roobees --java 6 --projectName roobees

jpa setup --provider HIBERNATE --database MYSQL --userName yourmysqluserid --databaseName yourmysqlinstancename --password yourmysqlpasswd

entity --class ~.domain.Item --activeRecord false

field string --fieldName name --sizeMin 3 --sizeMax 30 --class ~.domain.Item
field string --fieldName description --sizeMax 255 --class ~.domain.Item

repository jpa --interface ~.repository.ItemRepository --entity ~.domain.Item

service --interface ~.service.ItemService --entity ~.domain.Item

web mvc setup
web mvc all --package ~.web

logging setup --level DEBUG


Roo 1.1.5 Script

Here is a simple item manager application script you can use/customize to create your application

# FOR SPRING ROO 1.1.5

development mode --enabled true

project --topLevelPackage com.gordondickens.roobees --java 6 --projectName roobees

persistence setup --provider HIBERNATE --database MYSQL --userName yourmysqluserid --databaseName yourmysqlinstancename --password yourmysqlpasswd

entity --class ~.domain.Item

field string --fieldName name --sizeMin 3 --sizeMax 30 --class ~.domain.Item
field string --fieldName description --sizeMax 255 --class ~.domain.Item

web mvc setup
web mvc all --package ~.web

logging setup --level DEBUG


cloudbees-web.xml

<?xml version="1.0"?>
<cloudbees-web-app xmlns="http://www.cloudbees.com/xml/webapp/1">
  <appid>roobees</appid>
  <context-param>
    <param-name>application.environment</param-name>
    <param-value>prod</param-value>
  </context-param>
</cloudbees-web-app>


Maven CloudBees Plugin

Add the CloudBees repository to the pluginRepositories section.

<pluginRepositories>
  ...
  <pluginRepository>
    <id>bees-plugins-snapshots</id>
    <url>http://repository-cloudbees.forge.cloudbees.com/public-snapshot/</url>
    <releases>
      <enabled>false</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </pluginRepository>
  ...
</pluginRepositories>

Add the CloudBees Maven plugin to the plugins section.

<plugins>
  ...
  <plugin>
    <groupId>com.cloudbees</groupId>
    <artifactId>bees-maven-plugin</artifactId>
    <version>1.0-SNAPSHOT</version>
    <configuration>
       <!-- your username/appname -->
      <appid>youruserid/roobees</appid>
      <!-- your api key -->
      <apikey>BEBEBE2CEBEBEFBE</apikey>
      <!-- your secret key -->
      <secret>GEE0GERE0E-JE0EQETEHEPET+33MEIEIEI0EEZEEIEE00+</secret>
      <message>Roo ItemManager on CloudBees by Gordon Dickens</message>
    </configuration>
  </plugin>
  ...
</plugins>


Database Properties File

Edit the /src/main/resources/META-INF/spring/database.properties file.
Set the database.url to jdbc:cloudbees://yourmysqlinstance.
Set the database.driverClassName to com.cloudbees.jdbc.Driver.

database.username=yourmysqluserid
database.password=yourmysqlpasswd

database.url=jdbc:cloudbees://yourmysqlinstancename
database.driverClassName=com.cloudbees.jdbc.Driver

Download the Demo App

The demo app is in Git https://github.com/gordonad/gordonad-roo-1.2-cloudbees for Spring Roo 1.2.



Get Your Copy -->
Get it NOW! -->
Spring Roo in Action Image <-- All the cool kids have one
<-- You gotta have it!




Want to Learn More?

Learn more about Spring by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Cloud, CloudBees, Roo, Spring, Spring Roo | Tagged , , , | 6 Comments

Rocket to the Cloud Fast with Roo

Want to build a Spring 3 application FAST and run it on the Cloud?

It is incredibly easy to do with Spring Roo and CloudFoundry!

This post on using Postgres on CloudFoundry helped me get started, however I tried using the 1.2.M1 with the CloudFoundry addon, but was unable to install it successfully in either 1.1.5.RELEASE or 1.2.0.M1.

Recently, Spring Roo moved to GitHub


Steps

  1. Get a Free CloudFoundry Account
  2. Clone the Spring Roo Git Repository
  3. Configure GPG/PGP setup
    see /spring-roo/readme.txt
  4. Build Spring Roo with Maven
    mvn -U clean install -Dgpg.passphrase=yourpassphrase
  5. Link the Roo startup script
    see /spring-roo/readme.txt


Creating a Project

  1. Make a directory for your SimpleItem project
    mkdir /SimpleItem
  2. Go to the directory
    cd /SimpleItem
  3. Create the script file simpleitem.roo in the /SimpleItem directory
    (see the contents below)
  4. Start roo-dev
  5. Type the command
    script --file simpleitem.roo
  6. Go To: http://mysimpleitem.cloudfoundry.com/


The simpleitem.roo script file

development mode --enabled true
project --topLevelPackage com.gordondickens.simpleitem --java 6 --projectName SimpleItem
jpa setup --provider HIBERNATE --database POSTGRES
entity --class ~.domain.Item --testAutomatically --activeRecord false
field string --fieldName name --sizeMin 3 --sizeMax 30 --class ~.domain.Item
field string --fieldName description --sizeMax 255 --class ~.domain.Item
field date --fieldName visitDate --type java.util.Date --notNull --past
repository jpa --interface ~.repository.ItemRepository --entity ~.domain.Item
service --interface ~.service.ItemService --entity ~.domain.Item
finder add --finderName findItemsByName --class ~.domain.Item
finder add --finderName findVisitsByDescriptionLike
web mvc setup
web mvc all --package ~.web
web mvc finder all
logging setup --level DEBUG
perform package
download accept terms of use
pgp automatic trust

# ###########
# NOTE: Provide your credentials here, or perform these steps at the Roo prompt
# ###########
cloud foundry login --email you@mycompany.com --password n00n3w1llgu3ss

# ###########
# NOTE: The war file is the "--projectName" specified above
# ###########
cloud foundry deploy --appName mysimpleitem --path /target/SimpleItem-0.1.0.BUILD-SNAPSHOT.war --memory 512
cloud foundry create service --serviceName mysimpleitem-postgres --serviceType postgresql
cloud foundry bind service --serviceName mysimpleitem-postgres --appName mysimpleitem
cloud foundry start app --appName mysimpleitem

# ###########
# Go to URL: http://mysimpleitem.cloudfoundry.com/



NOTE CloudFoundry is Public

Since CloudFoundry is public, you may run into an issue deploying the application with the name above. You should change the --projectName to something unique with your name in it such as yourname-simpleitem.

Gunnar Hillert’s Blog explains this well.



Adding CloudFoundry Plugin to Maven

Thanks to Gunnar Hillert’s post, we can add to our project’s Maven pom.xml file the CloudFoundry Plugin.

<plugins>
  ...
  <plugin>
    <groupId>org.cloudfoundry</groupId>
    <artifactId>cf-maven-plugin</artifactId>
    <version>1.0.0.M1</version>
    <configuration>
      <server>mycloudfoundry-instance</server>
      <target>http://api.cloudfoundry.com</target>
      <url>${project.name}.cloudfoundry.com</url>
      <memory>256</memory>
    </configuration>
  </plugin>
  ...
</plugins>



Add CloudFoundry Credentials

Add credentials to our userhome/.m2/settings.xml

<servers>
  ...
  <server>
    <id>mycloudfoundry-instance</id>
    <username>you@mycompany.com</username>
    <password>n00n3w1llgu3ss</password>
  </server>
  ...
</servers>

To push (deploy) the code to CloudFoundry type mvn cf:push
For more plugin details type mvn cf:help



Get Your Copy -->
Get it NOW! -->
Spring Roo in Action Image <-- All the cool kids have one
<-- You gotta have it!




Want to Learn More?

Learn more about Spring by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Cloud, CloudFoundry, Java, Roo, Spring, Spring Data, Spring Roo | Tagged , , , , , , , , | Leave a comment

SyntaxHighlighter Missing XRegExp.js

I just ran into an issue when I updated my javascript files for SyntaxHighlighter.

Looked at the error console and discovered that shCore.js could not find XRegExp.js.

This blog link was a great start.

Additional Details

  1. Syntax Highlighter Git Repo
  2. Get the XRegExp.js from the scripts directory: /SyntaxHighlighter/scripts/XRegExp.js
  3. In your page above the shCore.js add XRegExp.js

Page Header Example

<script src='js/jquery-1.6.3.min.js' type='text/javascript'></script>
<script type="text/javascript" src="js/syntaxhighlighter/XRegExp.js"></script>
<script type="text/javascript" src="js/syntaxhighlighter/shCore.js"></script>
<script type="text/javascript" src="js/syntaxhighlighter/shBrushPlain.js"></script>
<script type="text/javascript" src="js/syntaxhighlighter/shBrushJava.js"></script>
<script type="text/javascript" src="js/syntaxhighlighter/shBrushGroovy.js"></script>
<script type="text/javascript" src="js/syntaxhighlighter/shBrushXml.js"></script>
<script type="text/javascript" src="js/syntaxhighlighter/shBrushCss.js"></script>
<link href="css/syntaxhighlighter/shCore.css" rel="stylesheet" type="text/css">
<link href="css/syntaxhighlighter/shThemeDefault.css" rel="stylesheet" type="text/css">
Posted in JavaScript, jQuery, SyntaxHighlighter | Tagged , , , , , | Leave a comment

tcServer Logging with Logback & SLF4J

Logback and SLF4J provide better logging for java applications. To configure VMware vFabric tcServer to take advantage of the speed and flexibility of Logback use the following steps as a starting point.

Download the tcServer Developer Edition free: http://www.springsource.com/developer/tcserver
This comes with Spring Insight: http://www.springsource.org/insight an awesome tool for inspecting application performance, see those expensive sql queries, etc.



1. Add JMX options

File: <appname>/bin/setenv.sh

CATALINA_OPTS="-Dcom.sun.management.jmxremote"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"



2. Enable JMX

File: <appname>/conf/server.xml

# In the <service> section:

<Connector port="8050"
  handler.list="mx"
  mx.enabled="true"
  mx.httpHost="localhost"
  mx.httpPort="8082"
  protocol="AJP/1.3" />



3. If using JNDI, add JNDI Configuration support for Logback

File: <appname>/bin/setenv.sh

JAVA_OPTS="$JAVA_OPTS -Dlogback.ContextSelector=JNDI"



4. Add Server Logging using Logback

File: <appname>/conf/server.xml

#In the <Hosts> Section:

<Valve className="ch.qos.logback.access.tomcat.LogbackValve" />



5. Create logback-access.xml file in <appname>/conf/ directory

<configuration>
  <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>combined</pattern>
    </encoder>
  </appender>

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>myApp.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>myApp-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>5MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <encoder>
      <pattern>combined</pattern>
    </encoder>
  </appender>

  <logger name="com.MYAPP.MYPKG" level="debug" />
  <logger name="org.springframework.web" level="debug" />
  <logger name="org.springframework.beans" level="debug" />
  <logger name="org.springframework.orm" level="debug" />
  <logger name="org.springframework.web" level="debug" />
  <logger name="net.sf.ehcache" level="error" />
  <logger name="org.hibernate.cache" level="error" />

  <root level="info">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>
</configuration>



6. In the <tomcatdir>/lib directory, add the following jars

By including JCL-over-SLF4J, we handle Apache Commons Logging through SLF4J (JCL = Jakarta Commons Logging)
By including JUL-to-SLF4J, we handle Java Util Logging through SLF4J

  • jcl-over-slf4j-1.6.2.jar
  • jul-to-slf4j-1.6.2.jar
  • slf4j-api-1.6.2.jar
  • logback-access-0.9.30.jar
  • logback-classic-0.9.30.jar
  • logback-core-0.9.30.jar



7. Configure the application for Logging Separation

See: http://logback.qos.ch/manual/loggingSeparation.html

<env-entry>
  <description>JNDI logging context for this app</description>
  <env-entry-name>logback/context-name</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>yourAppHere</env-entry-value>
</env-entry>

<env-entry>
  <description>URL for configuring logback context</description>
  <env-entry-name>logback/configuration-resource</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>logback.xml</env-entry-value>
</env-entry>

<listener>
  <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class>
</listener>

<filter>
  <filter-name>LoggerContextFilter</filter-name>
  <filter-class>ch.qos.logback.classic.selector.servlet.LoggerContextFilter</filter-class>
</filter>

<filter-mapping>
  <filter-name>LoggerContextFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>



8. Optional – To add a servlet to view the logback events

File: <application>/src/main/webapp/WEB-INF/web.xml
See: http://logback.qos.ch/manual/configuration.html
Status Messages will be available: http://yourWebapp/lbClassicStatus

<servlet>
  <servlet-name>ViewStatusMessages</servlet-name>
  <servlet-class>ch.qos.logback.classic.ViewStatusMessagesServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>ViewStatusMessages</servlet-name>
  <url-pattern>/lbClassicStatus</url-pattern>
</servlet-mapping>



Summary

Using tcServer with Insight provides us developers with a valuable resource for code inspection at runtime. Logback and SLF4J provides us with fast, flexible logging configuration and the logging separation for our application instances.




Want to Learn More?

Learn more about Spring by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Jakarta Commons Logging, Java, Java Util Logging, LogBack, Logging, SLF4J, Spring, Spring Insight, tcServer, Tomcat | Tagged , , , , , , | Leave a comment

Adding Queries to Spring Data-JPA

In my previous post, Simpler JPA with Spring Data-JPA I showed how to configure a repository interface which Spring Data will implement for us. Let me show how easy it is to add queries.



Modify the Repository Interface

Simply define the method interface and use the @Query annotation to define the OQL.

package com.gordondickens.myapp.repository;

import org.springframework.data.repository.CrudRepository;
import com.gordondickens.myapp.entity.Product;

public interface ProductRepository
   extends CrudRepository<Product, Long> {

	@Query("FROM Product")
	List<Product> findAllProducts();
}

Modifying Queries

  • Parameters can be marked by position with ?1, ?2, etc.
  • Parameters can be marked by name with :paramName and annotation @Param("paramName")
  • Modifying method signature can only return void, Integer or int
  • Updating queries MUST be transactional, mark with @Transactional
  • Spring Data will drop all non-flushed changes pending in the EntityManager, change with @Modifying(clearAutomatically=false)
package com.gordondickens.myapp.repository;

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

@Transactional(readOnly=true)
public interface ProductRepository
   extends CrudRepository<Product, Long> {

   @Query("FROM Product")
   List<Product> findAllProducts();

   // Example with positional params
   @Modifying
   @Transactional(readOnly=false)
   @Query("update Product p set p.description = ?2 where p.productId = ?1")
   Integer setNewDescriptionForProduct(String productId, String description);

   // Example with named params
   @Modifying
   @Query("update Product p set p.description = :description where p.productId = :productId")
   Integer setNewDescriptionForProduct(@Param("productId") String productId,
      @Param("description") String description);
}



Automatic Query Generation

The <jpa:repositories/> has an option query-lookup-strategy which defaults to “create-if-not-found” which will generate queries for us.

The default is “create-if-not-found“. Other options are “create” or “use-declared-query“.

   <jpa:repositories base-package="com.gordondickens.myapp.repository"
		query-lookup-strategy="create-if-not-found"/>

To create a find method that effectively does @Query("FROM Product p where p.productId = :productId")

public interface ProductRepository extends CrudRepository<Product, Long> {
   ...

   @Query
   Product findByProductId(String productId);

   ...



Summary

We see how simple interface additions provide custom methods based on query language. We can query either by positional or named parameters.




Want to Learn More?

Learn more about Spring by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Spring | 3 Comments

Simpler JPA with Spring Data-JPA

How to configure your Spring application with Simple CRUD configuration with Spring Data-JPA.



1. Add Spring Data-JPA to project configuration. In your Maven pom.xml file

<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-jpa</artifactId>
   <version>1.0.2.RELEASE</version>
</dependency>



2. Configure JPA Entity

...

@Entity
public class Product {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "id")
  private Long id;

  @NotNull
  @Column(unique = true)
  private String productId;

  @NotNull
  private Integer quantity;

  ...
}



3. Configure Typed Repository Interface

Spring Data JPA will create the beans for us.

package com.gordondickens.myapp.repository;

import org.springframework.data.repository.CrudRepository;
import com.gordondickens.myapp.entity.Product;

public interface ProductRepository
   extends CrudRepository<Product, Long> {}



4. Configure the application context

Note: this example uses Hibernate and HSQL

<!-- Directory to scan for repository classes -->
<jpa:repositories
   base-package="com.gordondickens.myapp.repository" />

<bean class="org.springframework.orm.jpa.JpaTransactionManager"
  id="transactionManager">
  <property name="entityManagerFactory"
      ref="entityManagerFactory" />
  <property name="jpaDialect">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
  </property>
</bean>

<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="HSQL" />
    </bean>
  </property>
</bean>



5. Inject the Repository

In our service class & tests we use the repository to execute our crud methods. Repository Methods: count(), exists(), delete(), deleteAll(), findOne(), findAll(), save().

public class ProductServiceImpl extends ProductService {

   @Autowired
   ProductRepository productRepository;

  ...
}

See Part 2 – Adding Queries to Spring Data-JPA



Summary

The Spring Data project abstracts away basic data management concepts. In addition to support for traditional relational methodologies, Spring Data provides support for NoSQL Graph, Key-Value and Map-Reduce types. As we saw in the above example configuring CRUD style applications is fairly trivial and Spring provides a convenient configuration for the typical cookie cutter code.

Click here to see my other blog which lists the annotations in “Spring Data-Commons” and “Spring Data-JPA”.




Want to Learn More?

Learn more about Spring by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Hibernate, JPA, Spring, Spring Data, Spring Framework | Tagged , , , , , , | 4 Comments

Quick Install for tcServer 2.5 with Spring Insight in STS

Installation & Config

  1. Download tcServer Developer’s Edition – current version is 2.5.1 (free registration required)
  2. Make a directory for tcServer (such as /opt/tcserver or c:\tcserver)
  3. Unzip the downloaded file into that directory
  4. Type at command line in your tcServer directory (.sh for unix/mac, .bat for Windows): tcruntime-instance.sh create myInsight -t insight
  5. Start STS (I am using 2.7.1)
  6. From menu: File > New > Other… > Server > Server
  7. Scroll to VMware, choose VMware vFabric tcServer 2.5
  8. Click Configure Runtime Environments link
  9. Add new tcServer, setting the location to your tcServer directory, press OK
  10. Choose the newly configured Server Runtime Environment from the drop down
  11. Press Next
  12. Choose Existing Instance radio button
  13. Choose myInsight from the dropdown



Configuring for Tomcat 6

By default, the tcruntime-instance script configures Tomcat 7.

To use Tomcat 6 instead:
Determine the version of Tomcat 6 that is available with tcServer – the version is in the directory name. For tcServer 2.5.1, the directory is <tcServer Dir>/tomcat-6.0.32.C.RELEASE, so we know that our version is “6.0.32.C.RELEASE“.
Now execute the command: tcruntime-instance.sh create myInsight -t insight --version 6.0.32.C.RELEASE



Deploying & Running with Insight

  1. R-click on a web app, Run on Server (or drag and drop to tcServer in Server view)
  2. If server not running press the Green play arrow in the Server view toolbar
  3. Popup: Spring Insight is Available… enable gathering of metrics? – Click YES
  4. Connect to your app – e.g. http://localhost:8080/myapp
  5. Connect to Insight – http://localhost:8080/insight




Want to Learn More?

Learn more about developing Spring Apps by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Eclipse, Installation, Spring, Spring Insight, STS, tcServer, Tomcat | Tagged , , , , , , | 2 Comments

RESTful MVC Features in Spring 3.0 and 3.1

Below is a feature summary you must know to use Spring’s MVC RESTful Web Services. This article will show the features available, but not discuss pros & cons, use-cases or sell you on the benefits of REST.



PUT & POST in Browser Based Clients

Browsers do not allow PUT & DELETE – In web.xml configure HiddenHttpMethodFilter & on the page add the following inside your form <input type="hidden" name="_method" value="PUT"/>, with form submit set to POST. If using the Spring <form:form> tag, the hidden field is created for you, use any of the standard 7 HTTP verbs as desired.



Receiving Values in the URL Path, the RESTful Way

@PathVariable in Controller methods to extract values from the path.



You Rarely Need to Write Custom Parsers

<mvc:annotation-driven/> – automatically registers several marshallers simply with presence of corresponding jar in classpath

Type group:artifact:current-version
JAXB2 com.sun.xml.bind:jaxb-impl:2.2.4
JAXP javax.xml:jaxp-api:1.4.2
Atom/RSS rome:rome:1.0
JSON org.codehaus.jackson:jackson-mapper-asl:1.8.3



Configure – Don’t Code

Automatic Marshalling & Unmarshalling of XML, JSON, ATOM/RSS data
Controller annotations: @RequestBody & @ResponseBody
Example of JAXB2 Configuration in my OXM blog post named http://gordondickens.com/wordpress/2011/02/07/sending-beans-as-xml-with-jmstemplate/



Sending HTTP Response Codes to Clients

Success response status with @ResponseStatus controller method annotation.
Exception handling with @ExceptionHandler annotation on controller methods OR custom classes, also with annotated @ResponseStatus.
Note: @ResponseStatus disables the default behavior of void controller methods automatically returning the view.



Content Negotiation

Accept Header in Browser Based Clients

The HTML Accept header is not a reliable option for browser based clients to request content type. See Content Negotiation below.

Managing Client Content Type Requests

The HTTP Accept header is the typical REST vehicle for receiving the client’s requested MIME content type (application/JSON, application/XML, etc.)

Content Negotiation – Flexible Config Options

Spring’s ContentNegotiatingViewResolver for configuring client request data format. Several methods beyond the standard “Accept” header which will not work if you have browser based clients (Accept header, url extension, parameter, Java Activation Framework). URL extension (referred to as file extension) allows a URL to be appended with a string which can be mapped to a MIME type.

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="mediaTypes">
    <map>
      <entry key="json" value="application/json" />
      <entry key="xml" value="application/xml" />
      <entry key="htm" value="text/html" />
    </map>
  </property>
  <property name="defaultContentType" value="text/html" />
</bean>

The same shortcut keys can be used in a parameter where URL can have “?format=json”. For JAF, the jar contains a /lib/mime.types file with mapped types already defined.

Type group:artifact:current-version
Java Activation javax.activation:activation:1.1.1
Java Mail javax.mail:mail:1.4.1



Client Side with RestTemplate

Spring’s RestTemplate is for client side development. In the Spring Template style, simply, set the URL, invoke the method & process the results. The main extension points in Spring Templates are done through Callbacks.

HTTP Method RestTemplate Method
DELETE delete(java.lang.String, java.lang.Object...)
GET getForObject(java.lang.String, java.lang.Class, java.lang.Object...), getForEntity(java.lang.String, java.lang.Class, java.lang.Object...)
HEAD headForHeaders(String url, String... urlVariables)
OPTIONS optionsForAllow(String url, String... urlVariables)
POST postForLocation(String url, Object request, String... urlVariables)

RestTemplate Callbacks

Callback Description Interface
RequestCallback Called when execute method is invoked public interface RequestCallback { void doWithRequest(ClientHttpRequest request) throws IOException;
}
AcceptHeaderRequestCallback Processing the Accept headers public void doWithRequest(ClientHttpRequest request)
HttpEntityRequestCallback Writes provided object to output stream public void doWithRequest(ClientHttpRequest httpRequest)



REST Improvements in Spring 3.1

Customizable @MVC

  • Custom @ExceptionHandler support for @Controller methods
  • Custom @ExceptionHandler support for @RequestBody & @ResponseBody
  • You can write a BeanPostProcessor to change AnnotationMethodHandlerAdapter after construction
  • Auto-detection of custom HttpMessageConverters – for example custom MyMappingJacksonHttpMessageConverter
  • Support for custom message codes resolver with <mvc:annotation-driven/>
<mvc:annotation-driven>
    <mvc:custom-web-argument-resolvers>
        <bean class="org.example.MyWebArgumentResolver"/>
    </mvc:custom-web-argument-resolvers>
</mvc:annotation-driven>
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>
<mvc:annotation-driven message-codes-resolver="org.example.MyMessageCodesResolver"/>

REST Enhancements

  • Interceptors for RestTemplate
  • ClientHttpRequestInterceptor – ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
  • bufferRequestBody property to the SimpleClientHttpRequestFactory to handle large payloads with RestTemplate
  • New WebRequest.checkNotModified(String) // only had long support previously
  • New @ResponseEntity
  • To support OAuth with ClientHttpRequestInterceptors



Other REST Concepts



HATEOAS

Hypermedia as the Engine of Application State

WADL

Web Application Description Language



Summary

Spring MVC REST helps us with:

  • The power of <mvc:annotation-driven/> provides us the automatic marshalling/unmarshalling of content in REST
  • The configuration flexibility of ContentNegotiatingViewResolver for our browser based clients




Want to Learn More?

Learn more about Spring REST by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in REST, Spring, Spring MVC, Web Services | Tagged , , , | 1 Comment