<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.armstrongconsulting.com</title>
	<atom:link href="http://blog.armstrongconsulting.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.armstrongconsulting.com</link>
	<description>code snippets and stuff we think might be useful for other enterprise developers</description>
	<lastBuildDate>Thu, 26 Aug 2010 11:54:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Clustering wicket apps</title>
		<link>http://blog.armstrongconsulting.com/?p=145</link>
		<comments>http://blog.armstrongconsulting.com/?p=145#comments</comments>
		<pubDate>Wed, 25 Aug 2010 20:14:40 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[clustering]]></category>
		<category><![CDATA[haproxy]]></category>
		<category><![CDATA[hazelcast]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[Wicket]]></category>

		<guid isPermaLink="false">http://blog/?p=145</guid>
		<description><![CDATA[I had a hard time figuring out what was required to cluster our Wicket apps. None of the Wicket books discuss it in any detail &#8211; presumably because its not considered a Wicket-specific topic. I bothered the guys in the ##Wicket IRC Channel for a while and Victor Igumnov helped me figure it out and [...]]]></description>
			<content:encoded><![CDATA[<p>I had a hard time figuring out what was required to cluster our Wicket apps. None of the Wicket books discuss it in any detail &#8211; presumably because its not considered a Wicket-specific topic. I bothered the guys in the ##Wicket IRC Channel for a while and Victor Igumnov helped me figure it out and provided me with all the Wicket and Jetty pieces I needed.</p>
<p>Before I start, I should explain that we&#8217;re running our Wicket apps with embedded Jetty (&#8221;don&#8217;t run your apps in Jetty, run Jetty in your apps&#8221;). We really like it because it essentially turns web apps into plain old java apps which you can develop, debug and deploy without all that tomcat clutter. So we wanted clustering solution which worked with embedded Jetty, preferably in an uncomplicated fashion.</p>
<p>My first idea was to use Hazelcast &#8211; we&#8217;re already using it for distributed locking and queuing (its a paragon of simplicity, exemplifying the &#8220;it just works&#8221; principle). However, I was unable to find exactly what I needed based on Hazelcast, so I followed Victor&#8217;s advice and used memcached instead.</p>
<p>You need three things to cluster a Wicket app:<br />
(1) A load balancer &#8211; we use HAProxy (as does everybody  else).<br />
(2) A distributed map to store the application sessions &#8211; we&#8217;re using memcached here.<br />
(3) A http session implementation which stores the session in the distributed map instead of locally.</p>
<p>Since the main point of clustering is fault-tolerance, you need to make sure that you avoid single points of failure in the system. Unfortunately, this means that you have to cluster not only your application, but also provide failover for HAProxy and for memcached. I won&#8217;t cover that here, but you just need to be aware that when you install those components, you&#8217;ll need to install at least two of each with failover. This is simple for memcached &#8211; for HAProxy its a bit harder, but at least you can reuse this infrastructure for multiple apps.</p>
<p>HAProxy is the load balancer which will take care of presenting one address for your app to clients, even though your app is running as a cluster of servers. I&#8217;m not going to explain how to configure HAProxy here except to say that you&#8217;ll need session affinity (aka sticky-sessions) turned on &#8211; this means that users stay on a server for a whole session unless the server goes down. Wicket prefers sticky-session load balancing, and its more efficient, so its best to use it.</p>
<p>Installing memcached is no problem. Just follow the instructions. The default configuration only allows connections from localhost, so you&#8217;ll need to allow access from the subnet containing the app servers, but otherwise there&#8217;s nothing to configure.</p>
<p>Then you need to have your http session persist itself to memcached instead of to the local machine. Frsi download Victor&#8217;s tcache distributed cache client library from http://github.com/victori/tcache. Then get Victor&#8217;s jetty-session-cache from http://github.com/victori/jetty-session-cache. Add the built jars to your project (or maven repository). Victor describes how to configure jetty via XML to use the MemcachedSessionManager. Since we confgure the embedded Jetty programatically, we needed the following line in our Jetty startup code:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">&nbsp;
context.<span style="color: #006633;">setSessionHandler</span><span style="color: #009900;">&#40;</span>
  <span style="color: #000000; font-weight: bold;">new</span> SessionHandler<span style="color: #009900;">&#40;</span>
     <span style="color: #000000; font-weight: bold;">new</span> MemcachedSessionManager<span style="color: #009900;">&#40;</span>memcachedServers, <span style="color: #0000ff;">&quot;my_app_session_store&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>where memcachedServers is a String[] containing a list of your memcached servers, like &#8220;server1:11211&#8243;, &#8220;server2:11211&#8243;.</p>
<p>You then need to tell Wicket to store its pages in the http session instead of the default disk-based page store. However, this apparently doesn&#8217;t work very efficiently, so the recommended approach is to use a custom page store which stores its pages directly to memcached instead of using the http session.</p>
<p>Victor has a solution here too, go to http://letsgetdugg.com/2010/02/07/clustering-wicket-for-fun-and-profit/ and follow the instructions to override your applications newSessionStore() and provide a memcached page store.</p>
<p>Now your Wicket app is clustered. You can try it out by accessing it via HAProxy, logging on to your app, killing the server with your app&#8217;s session and then continue using the app (for test purposes, I display the server running the app session, so I can see when it fails over).</p>
<p>I&#8217;d still like to replace memcached with Hazelcast (fully java-based embedded clustering in your app with no single point of failure)- maybe Victor will embrace Hazelcast and add it to the list of caches supported by tcache.</p>
<p>=================================<br />
26.08.2010<br />
I got a mail from Talip Ozturk of Hazelcast to say that Hazelcast supports the memcached protocol, so it should be possible to use a memcached session and page store implementation against a Hazelcast server. This would be fantastic, since it would eliminate the need to have multiple memcached servers &#8211; one less piece of infrastructure to worry about. I&#8217;ll try to get this working and let you know how I get on.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=145</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Deploying with Continuum and Maven</title>
		<link>http://blog.armstrongconsulting.com/?p=138</link>
		<comments>http://blog.armstrongconsulting.com/?p=138#comments</comments>
		<pubDate>Thu, 05 Aug 2010 07:37:29 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[continuum]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://blog.armstrongconsulting.com/?p=138</guid>
		<description><![CDATA[We are now deploying to our staging servers from our Maven repository using wget (the url is like &#8216;http://maven:8080/nexus/service/local/artifact/maven/redirect? r=snapshots&#038;g=com.armstrongconsulting.controlcenter.server &#038;a=controlcenterwebapp&#038;v=LATEST&#038;e=jar&#038;c=jar-with-dependencies&#8217;.). The runnable jars (or wars) in the Maven repository are built, unit-tested and deployed to Maven by Continuum automatically. If any errors are found, the developer who made the offending commit to SVN is [...]]]></description>
			<content:encoded><![CDATA[<p>We are now deploying to our staging servers from our Maven repository using wget (the url is like &#8216;http://maven:8080/nexus/service/local/artifact/maven/redirect? r=snapshots&#038;g=com.armstrongconsulting.controlcenter.server &#038;a=controlcenterwebapp&#038;v=LATEST&#038;e=jar&#038;c=jar-with-dependencies&#8217;.). The runnable jars (or wars) in the Maven repository are built, unit-tested and deployed to Maven by Continuum automatically. If any errors are found, the developer who made the offending commit to SVN is informed by Continuum. Works great, highly recommended. Thanks to Gabriel for setting it all up.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=138</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hazelcast distributed locks for easy fault tolerance</title>
		<link>http://blog.armstrongconsulting.com/?p=132</link>
		<comments>http://blog.armstrongconsulting.com/?p=132#comments</comments>
		<pubDate>Thu, 17 Jun 2010 10:55:03 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[distributed programming]]></category>
		<category><![CDATA[hazelcast]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog/?p=132</guid>
		<description><![CDATA[Hazelcast (hazelcast.com) provides an easy way to implement distributed locking to allow your applications to run multiple, fault-tolerant instances without worrying about issues related concurrent access to shared resources (like files, databases or whatever).

try &#123;
	java.util.concurrent.locks.Lock lock = Hazelcast.getLock&#40;&#34;mylock&#34;&#41;;
	while &#40;true&#41; &#123;
		lock.lock&#40;&#41;;
		try &#123;
			// do some work involving access to shared resources
		&#125; finally &#123;
			lock.unlock&#40;&#41;;
		&#125;
	&#125;
&#125; finally &#123;
	Hazelcast.shutdown&#40;&#41;;
&#125;

We have an [...]]]></description>
			<content:encoded><![CDATA[<p>Hazelcast (<a href="http://hazelcast.com">hazelcast.com</a>) provides an easy way to implement distributed locking to allow your applications to run multiple, fault-tolerant instances without worrying about issues related concurrent access to shared resources (like files, databases or whatever).</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
	java.<span style="color: #006633;">util</span>.<span style="color: #006633;">concurrent</span>.<span style="color: #006633;">locks</span>.<span style="color: #006633;">Lock</span> lock <span style="color: #339933;">=</span> Hazelcast.<span style="color: #006633;">getLock</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mylock&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		lock.<span style="color: #006633;">lock</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// do some work involving access to shared resources</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">finally</span> <span style="color: #009900;">&#123;</span>
			lock.<span style="color: #006633;">unlock</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">finally</span> <span style="color: #009900;">&#123;</span>
	Hazelcast.<span style="color: #006633;">shutdown</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>We have an SMS server which retrieved mail messages from a POP3 mailbox, entered them to a database and then delivered via the Clickatell messaging gateway. Making it run multiple instances concurrently would have been a headache since it would involve various issues relating to transactions across the POP3 and the Clickatell interfaces. It was a whole lot easier to wrap the business logic with a hazelcast lock and let it run on two servers. The beauty of hazelcast is that it just works &#8211; since the default configuration uses multicast to detect other members of the cluster, there&#8217;s no additional infrastructure &#8211; just add the jar to your application and off you go. We might still implement Zookeeper or Terracotta in future, but both of them require more infrastructure (i.e. dedicated (virtual) servers) and configuration.<br />
Postscript: I had occasional hangs with Hazelcast 1.8.4 which caused me to switch to Zookeeper. As expected, Zookeeper was a lot harder to use than Hazelcast &#8211; you need Zookeeper installed on 3 servers. There&#8217;s no official java client, just some recipes and I found an implementation of Zookeeper locks called Cages on google code. For a java developer, Hazelcast is obviously way easier to use. Anyway, after upgrading to Hazelcast version 1.8.5, the hang problem went away so I happily went back to using Hazelcast. We&#8217;re also now using the distributed queues &#8211; works great so far.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=132</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wicket dropdowns with mismatched models</title>
		<link>http://blog.armstrongconsulting.com/?p=130</link>
		<comments>http://blog.armstrongconsulting.com/?p=130#comments</comments>
		<pubDate>Tue, 01 Jun 2010 05:34:14 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog/?p=130</guid>
		<description><![CDATA[Sometimes you have a class containing an id of another (lets say a Machine class containing an owner id rather than an Owner object). The owner id is actually a primary key from the Owner table in the database. Now you want to display the Machine class in a wicket form with a dropdown to [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you have a class containing an id of another (lets say a Machine class containing an owner id rather than an Owner object). The owner id is actually a primary key from the Owner table in the database. Now you want to display the Machine class in a wicket form with a dropdown to select the Owner.</p>
<p>In an ideal world, your Machine class would have &#8220;Owner getOwner()&#8221; and &#8220;setOwner (Owner owner)&#8221; methods and your MachineService class would have a static &#8220;List<Owner> getOwners()&#8221; method and wicket&#8217;s DropDownChoice would just work with:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">final</span> Form<span style="color: #339933;">&lt;</span>Machine<span style="color: #339933;">&gt;</span> form <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Form<span style="color: #339933;">&lt;</span>Machine<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;form&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> CompoundPropertyModel<span style="color: #339933;">&lt;</span>Machine<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span>machine<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  add<span style="color: #009900;">&#40;</span>form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  form.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DropDownChoice<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;owner&quot;</span>, MachineService.<span style="color: #006633;">getOwners</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>However, in our Machine class, the owner property is an id of an Owner and not an Owner object. So how do we use the DropDownChoice without changing our Machine class? There are a few different approaches, but a simple one is to use a custom model with the DropDownChoice which converts between object and id representation, as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">final</span> Form<span style="color: #339933;">&lt;</span>Machine<span style="color: #339933;">&gt;</span> form <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Form<span style="color: #339933;">&lt;</span>Machine<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;form&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> CompoundPropertyModel<span style="color: #339933;">&lt;</span>Machine<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span>machine<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  add<span style="color: #009900;">&#40;</span>form<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  Model<span style="color: #339933;">&lt;</span>Owner<span style="color: #339933;">&gt;</span> model <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #339933;">&lt;</span>Owner<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">long</span> serialVersionUID <span style="color: #339933;">=</span> 1L<span style="color: #339933;">;</span>
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Owner</span> getObject<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>machine.<span style="color: #006633;">getOwner</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Owner</span><span style="color: #009900;">&#40;</span>machine.<span style="color: #006633;">getOwner</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> setObject<span style="color: #009900;">&#40;</span><span style="color: #003399;">Owner</span> owner<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>owner <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        machine.<span style="color: #006633;">setOwner</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
        machine.<span style="color: #006633;">setOwner</span><span style="color: #009900;">&#40;</span>owner.<span style="color: #006633;">getOwnerNr</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
 form.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> DropDownChoice<span style="color: #339933;">&lt;</span>Owner<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;owner&quot;</span>, model, ControlCenterService.<span style="color: #006633;">getOwners</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>So now, when wicket needs to get the current selection, it calls getObject on your custom model and gets an object which it can compare. When it needs to set the selection, it calls setObject which writes the correct id into the machine object. Note: Your Machine class will need to implement toString() for the display in the dropdown. Additionally it will need a constructor which takes an id and an overridden equals() and hashCode() based on the id field.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=130</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enforcing multiple levels of page access in Wicket</title>
		<link>http://blog.armstrongconsulting.com/?p=126</link>
		<comments>http://blog.armstrongconsulting.com/?p=126#comments</comments>
		<pubDate>Thu, 27 May 2010 08:57:01 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog.armstrongconsulting.com/?p=126</guid>
		<description><![CDATA[In Wicket when you want to require user login for some pages, you typically inherit the pages from a superclass called say ProtectedPage and then use a wicket SimplePageAuthorizationStrategy to protect these pages as follows:

getSecuritySettings&#40;&#41;.setAuthorizationStrategy&#40;new SimplePageAuthorizationStrategy&#40;ProtectedPage.class, LoginPage.class&#41; &#123;
  @Override
  protected boolean isAuthorized&#40;&#41; &#123;
    return &#40;&#40;ApplicationSession&#41; Session.get&#40;&#41;&#41;.getLoggedInUser&#40;&#41; != null;
  &#125;
&#125;&#41;;

This [...]]]></description>
			<content:encoded><![CDATA[<p>In Wicket when you want to require user login for some pages, you typically inherit the pages from a superclass called say ProtectedPage and then use a wicket SimplePageAuthorizationStrategy to protect these pages as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">getSecuritySettings<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setAuthorizationStrategy</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> SimplePageAuthorizationStrategy<span style="color: #009900;">&#40;</span>ProtectedPage.<span style="color: #000000; font-weight: bold;">class</span>, LoginPage.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  @Override
  <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> isAuthorized<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>ApplicationSession<span style="color: #009900;">&#41;</span> Session.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getLoggedInUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>This will cause any access to a protected page by a non-logged-in user to be redirected to the login page first.</p>
<p>In the real world, its likely however, that your application will also require administrator privileges for access to certain pages. To do this, you need to use a wicket CompoundAuthorizationStrategy as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  CompoundAuthorizationStrategy pageAuthorizationStrategy <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> CompoundAuthorizationStrategy<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  pageAuthorizationStrategy.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> SimplePageAuthorizationStrategy<span style="color: #009900;">&#40;</span>AdminPage.<span style="color: #000000; font-weight: bold;">class</span>, AccessDeniedPage.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    @Override
     <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> isAuthorized<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>ApplicationSession<span style="color: #009900;">&#41;</span> Session.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getLoggedInUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>ApplicationSession<span style="color: #009900;">&#41;</span> Session.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getLoggedInUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">isAdministrator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  pageAuthorizationStrategy.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> SimplePageAuthorizationStrategy<span style="color: #009900;">&#40;</span>ProtectedPage.<span style="color: #000000; font-weight: bold;">class</span>, LoginPage.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    @Override
     <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">boolean</span> isAuthorized<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>ApplicationSession<span style="color: #009900;">&#41;</span> Session.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getLoggedInUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
     <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   getSecuritySettings<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setAuthorizationStrategy</span><span style="color: #009900;">&#40;</span>pageAuthorizationStrategy<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The above requires the user to be logged in to access any page inherited from ProtectedPage and to be both logged in AND be an administrator to access any page inherited from AdminPage.</p>
<p>Thanks to selckin for the tip!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=126</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Embedded Jetty instead of Tomcat</title>
		<link>http://blog.armstrongconsulting.com/?p=115</link>
		<comments>http://blog.armstrongconsulting.com/?p=115#comments</comments>
		<pubDate>Tue, 11 May 2010 16:53:38 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog.armstrongconsulting.com/?p=115</guid>
		<description><![CDATA[I recently used embedded Jetty for a small REST server project and it was a revelation. It took exactly no time to get it running and now I can deploy web-apps just by starting a runnable jar. That&#8217;s reason enough &#8211; no more Tomcat with all the complexity of sharing a single server amongst multiple [...]]]></description>
			<content:encoded><![CDATA[<p>I recently used embedded Jetty for a small REST server project and it was a revelation. It took exactly no time to get it running and now I can deploy web-apps just by starting a runnable jar. That&#8217;s reason enough &#8211; no more Tomcat with all the complexity of sharing a single server amongst multiple apps, but, even more importantly, its wonderful for development. No more fooling around with Tomcat in Eclipse &#8211; just debug web-apps directly as a Java application.</p>
<p>We run all of our apps as multiple instances behind a load-balancer (HAProxy), so its convenient to run each app on a separate port and let the load-balancer handle the forwarding from port 80.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=115</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JDBC vs IBATIS vs Hibernate</title>
		<link>http://blog.armstrongconsulting.com/?p=113</link>
		<comments>http://blog.armstrongconsulting.com/?p=113#comments</comments>
		<pubDate>Mon, 10 May 2010 08:47:23 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog.armstrongconsulting.net/?p=113</guid>
		<description><![CDATA[Christoph has spent the last couple of weeks refactoring a web project to use IBATIS instead of Hibernate. I also refactored a smaller project to use IBATIS instead of JDBC. Here&#8217;s our take on the issues:
If you like JDBC and PreparedStatements, you&#8217;ll feel comfortable with IBATIS. It doesn&#8217;t force any major changes on you and [...]]]></description>
			<content:encoded><![CDATA[<p>Christoph has spent the last couple of weeks refactoring a web project to use IBATIS instead of Hibernate. I also refactored a smaller project to use IBATIS instead of JDBC. Here&#8217;s our take on the issues:</p>
<p>If you like JDBC and PreparedStatements, you&#8217;ll feel comfortable with IBATIS. It doesn&#8217;t force any major changes on you and reduces the lines of boilerplate code you&#8217;ll need for your database access. It has other benefits as well, such as automatically handling boolean and date mappings which are tedious and error-prone in JDBC.</p>
<p>We had successfully used Hibernate in a number of other projects, but in this particular project, Hibernate turned out to be an awkward fit. The problem was that we already had a database model which we couldn&#8217;t change and furthermore, we were porting an existing code base. This combination proved overly complex with Hibernate and we eventually redid the DAO in IBATIS, resulting in a much simpler port.</p>
<p>In summary, if you&#8217;re having difficulties integrating Hibernate into your application, consider using IBATIS instead &#8211; you get many of the benefits of ORM without the paradigm shifts which Hibernate implies.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=113</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>LDAPAuthentication with Active Directory</title>
		<link>http://blog.armstrongconsulting.com/?p=105</link>
		<comments>http://blog.armstrongconsulting.com/?p=105#comments</comments>
		<pubDate>Mon, 10 May 2010 08:10:36 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog.armstrongconsulting.net/?p=105</guid>
		<description><![CDATA[Here&#8217;s something I had to piece together myself from various code fragments. Its a class to authenticate a user in Windows Active Directory environment using LDAP. It first locates the domain controllers (DNS lookup of SRV records for _ldap._tcp.domain), parses out the server part and then tries to authenticate the user against a domain controller.

import [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s something I had to piece together myself from various code fragments. Its a class to authenticate a user in Windows Active Directory environment using LDAP. It first locates the domain controllers (DNS lookup of SRV records for _ldap._tcp.domain), parses out the server part and then tries to authenticate the user against a domain controller.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.ArrayList</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Hashtable</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.List</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.AuthenticationException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.CommunicationException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.Context</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.NamingException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.directory.Attribute</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.directory.Attributes</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.directory.DirContext</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.naming.directory.InitialDirContext</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.sun.jndi.ldap.LdapCtxFactory</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * LDAPAuthentication class for authenticating Microsoft Active Directory users
 * 
 * If the user or password is wrong, you'll get an AuthenticationException If
 * none of the domain controllers are reachable, you'll get a
 * CommunicationException. If a domain controller cannot be located (via DNS)
 * you'll get a NamingException.
 * 
 * @author Roger Armstrong, Armstrong Consulting GmbH
 * 
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> LDAPAuthentication <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> authenticateUser<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> user, <span style="color: #003399;">String</span> password, <span style="color: #003399;">String</span> domain<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">AuthenticationException</span>, <span style="color: #003399;">NamingException</span> <span style="color: #009900;">&#123;</span>
		List<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> ldapServers <span style="color: #339933;">=</span> findLDAPServersInWindowsDomain<span style="color: #009900;">&#40;</span>domain<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>ldapServers.<span style="color: #006633;">isEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">NamingException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Can't locate an LDAP server (try nslookup type=SRV _ldap._tcp.&quot;</span> <span style="color: #339933;">+</span> domain <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		Hashtable<span style="color: #339933;">&lt;</span>String, String<span style="color: #339933;">&gt;</span> props <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Hashtable<span style="color: #339933;">&lt;</span>String, String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">String</span> principalName <span style="color: #339933;">=</span> user <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;@&quot;</span> <span style="color: #339933;">+</span> domain<span style="color: #339933;">;</span>
		props.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, principalName<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		props.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, password<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">Integer</span> count <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> ldapServer <span style="color: #339933;">:</span> ldapServers<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
				count<span style="color: #339933;">++;</span>
				LdapCtxFactory.<span style="color: #006633;">getLdapCtxInstance</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ldap://&quot;</span> <span style="color: #339933;">+</span> ldapServer, props<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">CommunicationException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #666666; font-style: italic;">// this is what'll happen if one of the domain controllers is unreachable</span>
				<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>count.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>ldapServers.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #666666; font-style: italic;">// we've got no more servers to try, so throw the CommunicationException to indicate that we failed to reach an LDAP server</span>
					<span style="color: #000000; font-weight: bold;">throw</span> e<span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> List<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> findLDAPServersInWindowsDomain<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> domain<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">NamingException</span> <span style="color: #009900;">&#123;</span>
		List<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> servers <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		Hashtable<span style="color: #339933;">&lt;</span>String, String<span style="color: #339933;">&gt;</span> env <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Hashtable<span style="color: #339933;">&lt;</span>String, String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.dns.DnsContextFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;java.naming.provider.url&quot;</span>, <span style="color: #0000ff;">&quot;dns:&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">DirContext</span> ctx <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">Attributes</span> attributes <span style="color: #339933;">=</span> ctx.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;_ldap._tcp.&quot;</span> <span style="color: #339933;">+</span> domain, <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">&quot;SRV&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// that's how Windows domain controllers are registered in DNS</span>
		<span style="color: #003399;">Attribute</span> a <span style="color: #339933;">=</span> attributes.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SRV&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> a.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #003399;">String</span> srvRecord <span style="color: #339933;">=</span> a.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// each SRV record is in the format &quot;0 100 389 dc1.company.com.&quot;</span>
			<span style="color: #666666; font-style: italic;">// priority weight port server (space separated)</span>
			servers.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>srvRecord.<span style="color: #006633;">split</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot; &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		ctx.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">return</span> servers<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=105</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding an activity monitor to your wicket application</title>
		<link>http://blog.armstrongconsulting.com/?p=86</link>
		<comments>http://blog.armstrongconsulting.com/?p=86#comments</comments>
		<pubDate>Mon, 04 Jan 2010 10:27:50 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog.armstrongconsulting.com/?p=86</guid>
		<description><![CDATA[Sometimes its useful in an application to have a list of users who are currently logged onto an application on a server.

To do this, you first need a SessionAttributeListener which listens for attributes being added to and removed from the session:

public class SessionAttributeListener implements HttpSessionAttributeListener &#123;
	private static List&#60;String&#62; activeUsers = Collections.synchronizedList&#40;new ArrayList&#60;String&#62;&#40;&#41;&#41;; // listener is [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes its useful in an application to have a list of users who are currently logged onto an application on a server.<br />
<br/><br />
To do this, you first need a SessionAttributeListener which listens for attributes being added to and removed from the session:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> SessionAttributeListener <span style="color: #000000; font-weight: bold;">implements</span> HttpSessionAttributeListener <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> List<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> activeUsers <span style="color: #339933;">=</span> <span style="color: #003399;">Collections</span>.<span style="color: #006633;">synchronizedList</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// listener is being called from multiple threads and ArrayList is unsynchronized</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> List<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> getActiveUsers<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">return</span> activeUsers<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> attributeAdded<span style="color: #009900;">&#40;</span>HttpSessionBindingEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;wicket:wicket.acpro:user.name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			activeUsers.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> attributeRemoved<span style="color: #009900;">&#40;</span>HttpSessionBindingEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;wicket:wicket.acpro:user.name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
			activeUsers.<span style="color: #006633;">remove</span><span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	@Override
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> attributeReplaced<span style="color: #009900;">&#40;</span>HttpSessionBindingEvent event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Then from within your application login, you can set a session attribute when a user logs on <br/></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">Session.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setAttribute</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;user.name&quot;</span>, getLoggedOnUser<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You don&#8217;t need to remove the attribute on logout, as long as you are invalidating the session &#8211; this will automatically remove the attribute and invoke the attributeRemoved method of the listener.<br/><br />
The final step is to add an activity monitor display to you application which calls SessionAttributeListener.getActiveUsers() and displays the list.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=86</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to display images in Wicket</title>
		<link>http://blog.armstrongconsulting.com/?p=91</link>
		<comments>http://blog.armstrongconsulting.com/?p=91#comments</comments>
		<pubDate>Mon, 04 Jan 2010 09:58:01 +0000</pubDate>
		<dc:creator>roger</dc:creator>
				<category><![CDATA[Other]]></category>

		<guid isPermaLink="false">http://blog/?p=91</guid>
		<description><![CDATA[For someone starting out with Wicket, it can be tricky to figure out basic things like how to display images. Here are basic three scenarios:


1. Simple fixed image &#8211; no wicket code required:
HTML:

&#60;img src=&#34;images/search_icon.png&#34;/&#62;

This is fine as long as you don&#8217;t need any control over the image.

2. Image set from code:
HTML:

&#60;img wicket:id=&#34;search_icon&#34;/&#62;

JAVA:

.add&#40;new Image&#40;&#34;search_icon&#34;, new ContextRelativeResource&#40;&#34;/images/search_icon.png&#34;&#41;&#41;&#41;

The [...]]]></description>
			<content:encoded><![CDATA[<p>For someone starting out with Wicket, it can be tricky to figure out basic things like how to display images. Here are basic three scenarios:<br />
<br/></p>
<hr/>
1. Simple fixed image &#8211; no wicket code required:<br/><br />
HTML:<br/></p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;img src=&quot;images/search_icon.png&quot;/&gt;</pre></div></div>

<p>This is fine as long as you don&#8217;t need any control over the image.</p>
<hr/>
2. Image set from code:<br/><br />
HTML:<br/></p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;img wicket:id=&quot;search_icon&quot;/&gt;</pre></div></div>

<p>JAVA:<br/></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Image</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;search_icon&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> ContextRelativeResource<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/images/search_icon.png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>The ContextRelativeResource method here tells wicket to load the image from the images folder in your application (the same path as used in the relative src attribute used in the simple HTML example 1).</p>
<hr/>
3. Image set using CSS:<br/><br />
HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div class=&quot;search&quot;/&gt;</pre></div></div>

<p>CSS:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">.search {
	background-image: url(images/search_icon.png);
	background-position: center center;
	background-repeat: no-repeat;
	width: 20px;
	height: 20px;
}</pre></div></div>

<p>This approach is preferred for images which are really only part of the styling of the application (like say a green tick beside a list item) because it reduces the image to an an implicit part of a CSS class, allowing it to be restyled or removed without affecting the code. To change the CSS class of a component at runtime using wicket, you can use a wicket AttributeModifier to change the CSS class of the component.<br />
<br/><br />
Note: in the example above, the image path is relative to the referring stylesheet (so if the stylesheet is in the /CSS folder, the image will have to be in /CSS/images folder). However, since the image is simply part of the styles, it makes sense to keep such images together with the stylesheet.<br />
<br/></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> AttributeModifier<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;class&quot;</span>, <span style="color: #000066; font-weight: bold;">true</span>, <span style="color: #000000; font-weight: bold;">new</span> Model<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;search&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.armstrongconsulting.com/?feed=rss2&amp;p=91</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
