Kontakt

Archive for Dezember, 2009

Mapped Diagnostic Context with Tapestry Filters

Dienstag, Dezember 29th, 2009

In this post Howard describes how you can handle security in your Tapestry app. The approach is based on Tapestry’s request processing mechanism that allows you to extend the framework by your own contributions. In his post Howard contributes a filter for the ComponentRequestHandler pipeline to prevent any access to particular pages unless the user is logged in. For more details read Howard’s post.

Based on Howard’s post I would like to show you how to differentiate the logging output of one client from another. In web applications multiple clients request the same pages, components and services simultaneously. This fact leads to tons of logging output that is unusable because you can’t see which logging output belongs to which user. A simple technique called Mapped Diagnostic Contexts (MDC) can help you to stamp each logging output. The idea is to put contextual information into your logger and is described here.

Mapped Diagnostic Context is a map which is managed on a per thread basis. In log4j or slf4j you can put key-value pairs into the context. These pairs will be used by the logging framework when the logging output is generated. Let’s have a look at a simple log4j configuration. The most interesting part is %X{username}. The %X conversion specifier tells log4j that the contextual information username should be put into the logging output. When generating output the logger will look for a value the context under this key. If available the value will apear in the output.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration>
   <appender name="console">
      <param name="Threshold" value="INFO"/>
      <layout>
         <param name="ConversionPattern"
            value="%d{dd.MM.yyyy HH:mm:ss,SSS} [%X{username}] # %-5p # %c # [%C{1}.%M] # %m%n"/>
      </layout>
   </appender>

   <root>
      <appender-ref ref="console"/>
   </root>

</log4j:configuration>

Now let’s put the name of the logged in user into the MDC. A ComponentRequestFilter is a part of the Tapestry’s request processing mechanism and that’s why a good place to provide the contextual information.¬† The following filter along with a bunch of other filters is responsible for handling the page requests or component events. Every time a page is rendered or a component event is triggered our MDCFilter will put the name of the logged in user into the context before delegating to the next handler in the pipeline. After the invocation of the next handler is finished the name of the user is removed from the context.

public class MDCFilter implements ComponentRequestFilter {

    static final String MDC_KEY = "username";
    private final ApplicationStateManager applicationStateManager;

    public MDCFilter(final ApplicationStateManager manager) {
        this.applicationStateManager = manager;
    }

    public void handleComponentEvent(
	    ComponentEventRequestParameters parameters,
	    ComponentRequestHandler handler) throws IOException {
        put();

        try {
            handler.handleComponentEvent(parameters);
        } finally {
            remove();
        }
    }

    public void handlePageRender(
	    PageRenderRequestParameters parameters,
	    ComponentRequestHandler handler) throws IOException {
        put();

        try {
            handler.handlePageRender(parameters);
        } finally {
            remove();
        }

    }

    private void put() {
        User user = this.applicationStateManager
                            .getIfExists(User.class);

        if (user != null) {
            MDC.put(MDC_KEY, user.getUsername());
        }
    }

    private void remove() {
        MDC.remove(MDC_KEY);
    }

}

The last part of this is to plugin into the request processing mechanism of Tapestry. This is done by a contribution to the ComponentRequestHandler service’s configuration.

public class AppModule {
   public static void contributeComponentRequestHandler(
         OrderedConfiguration configuration) {
      configuration.addInstance("MDC", MDCFilter.class);
   }
}

If you are using Howard’s ComponentRequestFilter to check if the user is logged in you should place the MDCFilter after the RequiresLoginFilter. For this purpose we pass the order constraint after:RequiresLogin into the third parameter of the addInstance() method. This constraint is used to order the object relative to other contributed objects. This way MDCFilter will be executed after the RequiresLoginFilter.

public class AppModule {
   public static void contributeComponentRequestHandler(
         OrderedConfiguration configuration) {
      configuration.addInstance(
            "MDC", MDCFilter.class, "after:RequiresLogin"");
   }
}

That’s it. When a user is logged in you will see logging output like the following one. If the user is not there you will see just [] instead of [bart.simpson].

28.12.2009 22:55:41,066 [bart.simpson] # INFO  # foo.bar.pages.MyPage # [MyPage.onSuccess] # Bla bla bla

It is worth to mention that ComponentRequestHandler pipeline is not the only one place to plug into the request processing mechanism. You can also contribute a RequestFilter to the RequestHandler pipeline. Check out this diagramm for more details.

Beitrag im Blog von Addison-Wesley

Dienstag, Dezember 15th, 2009

Ich habe eben im Blog von meinem Verlag Addison-Wesley einen Beitrag zu Tapestry gepostet. Es handelt sich um eine kurze Einf√ľhrung in Tapestry 5.

Viel Spaß beim Lesen.

HiveMind Still Alive

Donnerstag, Dezember 3rd, 2009

I just ran across Gaderian – a fork of the recently retired Apache HiveMind project. HiveMind was the IoC container of Tapestry 4 and was founded by Tapestry founder Howard M. Lewis Ship. In April 2009 the project has reached its end of life and has been moved to Apache Attic. The reason for dropping HiveMind was the difficulty of managing the release two complex frameworks.

HiveMind was my first experience with IoC and loved the project. Tapestry IoC is the IoC container for Tapestry 5 and is the successor of HiveMind. It was designed with session learned from HiveMind. The central concept in Tapestry IoC is to eliminate XML-driven approach of HiveMind and build an equivalent system around simple objects and methods.

However if you are a hard core HiveMind user and migrating to Tapestry IoC is not an option then Gaderian might be a project you should look at. The migration guide from HiveMind to Gaderian is available here.

Tapestry at JUG Cologne

Dienstag, Dezember 1st, 2009

I’ll be speaking at JUG Cologne on December 7th.¬† If you’re in the area of Cologne and you are interested in Tapestry you can attend the talk. I’m going to show the basics of Tapestry 5 and show a lot of demos. The attenders will learn how to write web applications with minimal amount of Java code. Also some of the productivity benefits provided by Tapestry will be shown in the talk. The talk will be in German. Hope to see you there!

Tapestry 5 Blog - Copyright © 2009 - Eclectic Theme by Your Inspiration Web - Powered by WordPress