technical

Intercepting controllers in Spring MVC

Posted by Cameron Stokes on December 26, 2009
software development, technical / No Comments

Working on my latest project the past couple days I was trying to figure out a way to enforce authentication for some requests but not others.  I first wrote a Filter but when I started mapping the filter to my specific URLs I realized how tedious this could become.  I then remembered that Spring allowed for interceptors in its web framework and after a quick glance through their documentation I found the section I was looking for.  Unfortunately this still wasn’t exactly what I needed as Spring applies your interceptors to all requests configured in your handler mapping.  Looking at the HandlerInterceptor API I found I had access to the handler that was being processed and I just needed to decorate my handlers that needed authentication and adjust my interceptor to first check the handler.  I decided to create an empty Interface named AuthenticatedController which my controllers could implement to indicate they needed to be protected from unauthenticated access.  You could also do this using annotations, but here’s my code:

AuthenticatedController.java

public interface AuthenticatedController {
    // This is empty on purpose.
}

SimpleController.java

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;

public class StateController implements AuthenticatedController {

    public ModelAndView handleRequest( final HttpServletRequest httpServletRequest,
            final HttpServletResponse httpServletResponse ) throws Exception {
        ...
    }

}

AuthenticationInterceptor.java

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class AuthenticationInterceptor extends HandlerInterceptorAdapter {

    public boolean preHandle( HttpServletRequest request, HttpServletResponse response,
            Object handler ) throws Exception {

        if ( !( handler instanceof AuthenticatedController ) ) {
            // Authentication not needed, allow request to continue.
            return true;
        }

        boolean isAuthenticated = checkAuthentication(...);

        if ( !isAuthenticated ) {
            // User is not authenticated, handle response as needed, and halt processing.
            response.setStatus( HttpServletResponse.SC_FORBIDDEN );
            return false;
        }

        // User is authenticated, allow request to continue.
        return true;
    }
}

spring-beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean name="authenticationInterceptor" class="custom.AuthenticationInterceptor" />

<bean name="urlMapping"
    class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="interceptors">
         <list>
	     <ref bean="authenticationInterceptor" />
	</list>
    </property>
    <property name="mappings">
	<props>
            <prop key="/controller1.json">controller1</prop>
            <prop key="/controller2.json">controller2</prop>
            <prop key="/controller3.json">controller3</prop>
        </props>
    </property>
</bean>

</beans>

Tags: , ,

Using svnversion from Ant

Posted by Cameron Stokes on December 12, 2009
software development, technical / No Comments

At work we use a combination of Subversion (svn), Maven, and Ant to build and deploy our applications and integrate the svn revision number into our deployment packages.  As an example, if we’re packaging our callcenter application our build scripts will create a callcenter-7175.jar package.  This makes it easy for us to upgrade and rollback between versions as needed.

The svnversion program makes it easy to get the revision number of your working copy by simply executing the program:

macbookpro:rel-091105 stokesc$ svnversion
7175

To use this from Ant we can use the exec task. The example below will execute svnversion and capture its output into the Ant property repository.revision which is used later on in our build script:

<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="Build Script" default="make" basedir=".">

    <target name="make">

        <!-- Get current working directory. -->
        <exec executable="pwd" outputproperty="dir.root" />

        <!-- Get subversion revision number. -->
        <exec executable="svnversion" outputproperty="repository.revision" />

        <echo message="Repository revision is ${repository.revision}" />

    </target>

</project>

This worked well for us for a few years but when we needed to build from an older branch the revision number wasn’t representative of the last revision in the branch.  Looking at the options for svnversion I found passing -c will return the revision number of the last change rather than the current revision which is what we really wanted.

macbookpro:rel-091105 stokesc$ svnversion -c
1:6985

You can see the difference in revision numbers from this command versus the one above, but this still isn’t perfect due to the starting revision number that’s been added.  A little change to our Ant script can strip this off for us.  Here we use the redirector and filterchain types and a regular expression to modify the output.

<?xml version="1.0" encoding="ISO-8859-1"?>
<project name="Build Script" default="make" basedir=".">

    <target name="make">

        <!-- Get current working directory. -->
        <exec executable="pwd" outputproperty="dir.root" />

        <!-- Get subversion revision number. -->
        <exec executable="svnversion" outputproperty="repository.revision">
            <!-- Specify '-c' to get last changed rather than current revisions. -->
            <arg value="-c" />
            <!-- Use redirector/filterchain to parse output.
                 svnversion -c will return output in format [initial]:[current]
                 and we want to strip off [initial]: -->
            <redirector>
                <outputfilterchain>
                    <tokenfilter>
                        <replaceregex pattern="[0-9]+\:" replace="" />
                    </tokenfilter>
                </outputfilterchain>
            </redirector>
        </exec>

        <echo message="Repository revision is ${repository.revision}" />

    </target>

</project>

We’re now able to go back and package older versions of our application with a true indication of their svn revision.

Tags: , , , ,

“Flash erase operation failed” with Syba SD-SATA-4P (Sil3114)

Posted by Cameron Stokes on February 10, 2009
geek, technical / 4 Comments

Background

I’ve been needing to upgrade my home fileserver for a while and finally broke down and bought some parts. Being afraid of losing my data, I decided I’d move to OpenSolaris so I could take advantage of the extra features ZFS has to keep my bits safe. One of the first issues I encountered was that the 2 Promise SATA300 TX4 cards I had in my computer weren’t supported in OpenSolaris. After some googling I found that the Syba SD-SATA-4P SATA controller, based on the Sil3114 chipset from Silicon Image, available on Newegg was supported as long as the non-RAID BIOS was installed on the card.

The Issue

After receiving it from Newegg, I fired up the Sun Device Detection Tool to see if it was reported as supported. It was not, but having read the reviews on Newegg I knew I needed to install the non-RAID BIOS on the card. I downloaded the 5.4.0.3 version from the Silicon Imaging site (download here) and realized I needed either a DOS boot disk or a Windows machine from which I could update it. Having neither, I pulled out one of the older computers from my closet, installed Windows XP, and proceeded to install the card’s drivers. Once that was complete I tried to flash the non-RAID BIOS, but received a pretty nasty error message:

Flash erase operation failed.

Given how finicky BIOS updates can be, I was afraid I had bricked the card. I tried the RAID bios and it flashed without an issue. I decided to try the first rule in troubleshooting a computer issue, reboot. After rebooting I was still having the issue, I tried a few more times, read a few more posts online, checked the Syba website which gave me nothing.

The Solution

About to give up hope I re-read the readme that came with the download and noticed this line:

Ensure that a SATA device is plugged into a 3114 SATA port.

I remember reading the line earlier but brushed it off, figuring that couldn’t really be required. Having tried everything else, I shutdown, plugged in a SATA drive, started back up and was able to flash the BIOS without issue. I ran the Sun Device Detection Tool again and the card was recognized and shown as being supported. I’m still curious why there needs to be a drive connected in order to flash the card.

Tags: ,

Migrating my email to Google Apps

Posted by Cameron Stokes on August 29, 2008
geek, google, openbsd, technical / No Comments

I’ve been running my own email server for several years now and the biggest issues have certainly been dealing with spam. For the longest time I just put up with it and filtered manually. Then about 2 years ago I put in place an anti-spam gateway using OpenBSD and the excellent guide over at flakshak.com. This worked great. I was able to configure the anti-spam settings using SpamAssassin and tweak to my heart’s delight.

The biggest issue with this was managing the box(es) running the anti-spam software. We (I was running a hosting company at the time with two other people.) ended up filling up the various disk partitions with either massive email log files or SpamAssassin data as we added more and more users to the server. If we didn’t keep an eye on it, the disk would fill up, and the server would then die in strange ways. (Fortunately, we were running redundant OpenBSD servers with pf and carp so we often didn’t notice the server had died until we tried to login to it later.) Anyway, after shutting down the anti-spam servers and moving my personal server I had to figure out another way to deal with the spam.

I ended up using the same email server software as before and setup some forwarding rules following Using Gmail as a Spam Filter. This worked great as well but sometimes caused a delay in getting emails and given my setup I had to reconcile email in both gmail and my mail server. That is, marking items as read in my email server didn’t mark them as read in gmail as well, so I had to do it in both places…not a big issue but mildly annoying.

Fast forward a year or so and I’ve now moved my email hosting to Google Apps entirely. The process was a piece of cake though not as fast as I would have liked. After signing up, you have to prove that you own the domain you’re wanting them to host, either by uploading an html document that they specify or creating a sub-domain on your DNS server that they specify. This process seems to take about 30 minutes to an hour for them to verify though they claim it can take 24-48 hours. After this you have to enable E-mail for your domain which again takes about 30 minuts to an hour as they enable their email servers to accept email for your domain. Once this is done you just need to change your DNS settings so that your MX records point to Google’s servers. The process takes a couple hours, but it’s mostly waiting.

I left the email server running on my personal server for the next several days so that I could still get email while the DNS changes propagated out to everyone. About 7 days later I was still getting email to it, but when I checked who was sending it was mostly spam and the number of emails had dropped considerably. I decided to go ahead and shut it down and not worry about any other email coming in.

All in all, the setup process was painless. I no longer have to worry about running my own email server or dealing with anti-spam software. It’s no wonder why Google provides this, they now gets tons of information about me as they offer ads based on the content of my email. I may be paranoid, I don’t like Google knowing so much about me (certainly a topic for a future post), but they’ve made their services so enticing that it’s difficult to justify running my own server or paying someone else to do it.

Tags: , , ,

“Java heap space” error from SAP Memory Analyzer

Posted by Cameron Stokes on July 27, 2008
geek, howto, technical / No Comments

I ran into a fairly ironic error message when using the SAP Memory Analyzer to do some memory analysis of one of our applications at work. The reason given for the error was “Java heap space”.

"Java heap space" error from SAP Memory Analyzer.

"Java heap space" error from SAP Memory Analyzer.

The heap dump I was trying to analyze was around 1 gigabyte so I took the error to mean that the process ran out of memory. I finally figured out how to change the memory settings for the Mac OS X package by finding how to do the same thing for Eclipse (I’m only 2 months in using OS X as my primary OS).

In any case, to increase the heap size available to the program you have to edit the MemoryAnalyzer.ini file in the ./MemoryAnalyzer/Contents/MacOS/ folder. You can do this through Finder by right-clicking on the MemoryAnalyzer package and clicking Show Package Contents.

Here’s what my MemoryAnalyzer.ini looked like after the change.

-showsplash
org.eclipse.platform
-vmargs
-Xdock:icon=../Resources/Eclipse.icns
-XstartOnFirstThread
-Xms40m
-Xmx1024m
-XX:MaxPermSize=256m
-Dorg.eclipse.swt.internal.carbon.smallFonts

Changing the maximum heap setting value -Xmx to 1024m allowed me to open the heap dump without a problem.

Tags: , , ,