June 21, 2013

Tenant-aware bean proxying

Filed under: Pustefix, Spring — mtld @ 12:57 pm

In the last blog entry I showed how you can make Spring automatically create and manage an own bean instance per tenant using the tenant scope. Another use case within multitenant applications is using different beans (with different configuration or implementation, but common base class or interface) for different tenants.

Whereas the idea of the tenant scope is to inject a proxy object which delegates to an own bean instance of the same class (automatically managed for each tenant), now we inject a proxy object which delegates to other Spring managed beans (only needing a common interface or base class to be able to create a JDK proxy or CGLIB based proxy class).

With Spring’s ProxyFactoryBean you can easily create AOP proxies. The AOP invocation target can be set using a TargetSource. Pustefix provides a custom TargetSource implementation, which returns the target bean for the currently set tenant.

Let’s continue the Counter example from the last blog entry. We inject the counter bean into the web layer to increment the counter on each submit:

  @Autowired Counter counter;

  public void handleSubmittedData(Context context, IWrapper wrapper) throws Exception {

    counter.increment();

  }

Now we want different Counter instances for different countries, but this time we also want different beans, having different implementation classes sharing a common Counter interface. Here you can see how the proxy bean is configured:

  <bean name="counter" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetSource">
      <bean class="org.pustefixframework.container.spring.beans.TenantTargetSource">
        <property name="targets">
          <map>
            <entry key="DE">
              <bean class="mypackage.CounterImpl"/>
            </entry>
            <entry key="US">
              <bean class="mypackage.OtherCounterImpl"/>
            </entry>
          </map>
        </property>
      </bean>
    </property>
  </bean>

Pustefix also provide a custom ProxyFactoryBean implementation internally relying on the TenantTargetSource implementation, which makes the configuration a little bit shorter:

  <bean name="counter" class="org.pustefixframework.container.spring.beans.TenantProxyFactoryBean">
    <property name="targets">
      <map>
        <entry key="DE">
          <bean class="mypackage.CounterImpl"/>
        </entry>
        <entry key="US">
          <bean class="mypackage.OtherCounterImpl"/>
        </entry>
      </map>
    </property>
  </bean>

This feature will be available with Pustefix 0.18.48.

April 9, 2013

Multitenant Spring beans in Pustefix

Filed under: Pustefix, Spring — mtld @ 4:40 pm

Pustefix’s multitenancy support lets you create applications serving multiple tenants (e.g. countries) and languages within a single application instance. So far multitenancy in Pustefix focused on the view layer, helping you create internationalized pages composed of tenant/language-dependent content and resources.

In the next step we want to extend Pustefix’s application logic layer with multitenant capabilities. Looking at a usual Pustefix application’s Spring configuration we normally see a lot of singleton scoped beans implemented with a concrete application instance in mind. Making such an application multitenant means that such a bean will be shared between the tenants. Imagine a simple counter bean backing a website request counter. It will count the total number of requests, independent of the tenant. But what, if you want to have an own counter for each supported tenant?

You could create multiple counter beans, manage them in a map keyed by the tenant name and programmatically select the according counter within the request processing logic. But wouldn’t it be much nicer, if you don’t have to care about the tenants in your code and let Spring automatically manage this for you?

The solution is the implementation of an own tenant-aware Spring scope. Giving a Spring bean tenant scope, will mean that an own instance of this bean will be created and managed for each tenant. Injecting the bean as dependency will work similar to session-scoped beans: Spring will inject a proxy bean, which will delegate method calls to the appropriate instance associated with the current tenant.

A bean can be made tenant-scoped by setting the according scope attribute within the Spring configuration:

  <bean name="counter" class="mypackage.Counter" scope="tenant">
    <aop:scoped-proxy/>
  </bean>

Using the bean, e.g. in an IHandler, is straightforward:

  @Autowired Counter counter;

  public void handleSubmittedData(Context context, IWrapper wrapper) throws Exception {

    counter.increment();

  }

This feature will be available with Pustefix 0.18.44.

The next step will be the transparent injection of different tenant-depending bean instances (e.g. differently configured instances of the same class or different implementations of a common interface) using Spring’s ProxyFactoryBean together with a tenant-aware TargetSource implementation.

February 19, 2013

Finding things

Filed under: Pustefix, Tips & tricks — mtld @ 4:24 pm

This blog has been sleeping for almost a year. So it’s time to breathe new life into it. Let’s start where the last blog entry ended.

Finding things is still an issue. The more complex the application, the greater the need for a simple way to dive into the application, keeping track of where things are located and thus helping you to understand how they interact. Therefor Pustefix 0.18.38 implements a full text search as part of the in-webapp development tooling.

Some developers might argue that they’re having their IDE and nerdy command line tools, so there’s no need for another search tool. This is almost correct, if you stay within the Java world. But developing a complex view composed of thousands of XML and XSL fragments, located in different modules (available in different forms, like zipped archive or RCS checkout), will require that your IDE is accordingly configured to search all these different locations.

The Pustefix in-webapp full text search is a simple solution to search you webapp without having to use and configure an IDE, e.g. if you just want to test an application without having to set up an IDE project, or if you’re an frontend/view developer who wants to stay with the favored text editor. Besides it’s useful for debugging, e.g. if resource changes on the file system aren’t picked up by the webapp, you can verify from where resources are loaded, etc.

The full text search supports searching the webapp, modules and the classpath based on file name patterns and matching text lines using regular expressions. The search can be found on the pfxinternals page (e.g. local URL: http://localhost:8080/pfxinternals/search).

Pustefix internals - Full text search

February 29, 2012

Where the deuce is this template?

Filed under: Announcements, Pustefix, Tips & tricks — mtld @ 1:54 pm

Having highly modularized applications together with Pustefix’s multi-level XSL transformations sometimes can be a little bit annoying, e.g. if you want to reproduce a view bug and you don’t have a clue how the HTML output is produced and where the involved XSL templates come from.

Therefor Pustefix (since 0.18.10) can visualize the so-called target dependency model, showing you how the XSL stylesheets on each transformation level are composed, which XSL transforms which XML, what XML parts and images are included, etc.

Besides showing the dependency model Pustefix also lists the XSL templates available on the selected transformation level. All XML/XSL files can be directly viewed/downloaded (even if coming from a module archive).

This view is generated as part of the pfxinternals page (e.g. locally accessible in development mode under http://localhost:8080/pfxinternals/targets).

September 16, 2011

Pustefix discontinues OSGi work

Filed under: Announcements, Pustefix — mtld @ 11:50 am

More than 2 years ago we started to add OSGi-support to Pustefix. In September 2009 we officially released Pustefix 1.0.0, see an excerpt of the annonuncement:

Pustefix 1.0.0 has been released. This groundbreaking new release offers full OSGi support, i.e. Pustefix not just can be run inside an OSGi runtime, but Pustefix itself is built on the principles of OSGi, empowering you to modularize all aspects of a webapplication (business logic, view components, etc.) using an OSGi service based extension point mechanism.

Today we officially postpone OSGi support. Actually development stood still for more than a year because of the lack of adoption by our user community. To be honest we have to state that our OSGi experiment has failed and there are evident reasons.

I still think OSGi is a great technology and I’m sure there are a lot of use cases where OSGi already works very well, but the web application development scenarios targeted by Pustefix do not fit (yet).

In a way OSGi offers much more than we need, and at the same time not enough to make it worth paying the price for the effort of introducing a new programming model, a more complex development process and managing the various pitfalls when developing within an environment which itself is not yet ready for OSGi (infrastructure, tools, third party libraries, etc.).

But postponed is not abandoned and we’re looking forward to the modularization support coming with JDK 8, Project Jigsaw and JSR 294.

Starting from today the Pustefix main development will take place in the SVN trunk again. The OSGi implementation was moved to a branch and will be further available for backreference.

September 15, 2011

Pustefix ready for Java SE 7 and dropping support for Java 1.5

Filed under: Announcements, Pustefix, Tips & tricks — mtld @ 3:59 pm

Starting with version 0.18 Pustefix will no longer officially support Java SE 1.5 or older (nearly 5 years public availability of Java SE 1.6 should have been enough time for upgrading existing applications).

One reason for dropping support is the proprietary annotation processing in 1.5 (Sun’s deprecated apt tool) and the new standardized way in 1.6 (JSR269 Pluggable Annotation Processing API and JSR199 Java Compiler API), which will replace the apt tool in upcoming Pustefix releases.

Switching to the new annotation processing standard Pustefix now is also ready for upcoming Java releases. In general Java SE 7 can be already used with older Pustefix versions. I have only encountered a problem with Pustefix’s JAXWS/AJAX services, which will be fixed in the next 0.18 release (whereas it’s recommended to use the lightweight JSON services instead anyway).

If you still want to use JAXWS/AJAX services with older Pustefix versions and Java 1.7, you will have to upgrade to a newer JAXWS version, because the used JAXWS version stumbles accross the new getSuppressed() property in java.lang.Throwable when generating Exception beans. Additionally you will have to adapt the tools.jar Maven dependency because the java.vendor property used to activate the dependency profile changed from “Sun Microsystems Inc.” to “Oracle Corporation”.

August 8, 2011

Using the Live-JAR mechanism with mvn tomcat:run-war

Filed under: Pustefix, Tips & tricks — mtld @ 4:30 pm

If you’re running a modularized Pustefix application using mvn tomcat:run-war, you can enable the Live-JAR mechanism to load resources from the module/Maven projects’ source folder instead of the JAR files from the classpath.

Thus you don’t have to rebuild your modules when you modify a resource. Modified static resources and view parts (XML, XSLT) are automatically reloaded by Pustefix, modified configuration files (Pustefix, Spring) only will require a Webapp reload or Tomcat restart (but no build).

Since Pustefix 0.16 the most simple way to enable the Live-JAR mechanism is by specifying the pustefix.liveroot system property. Its value is the root directory where Pustefix will look for the backing Maven projects. Pustefix will also search sub directories, but for performance reasons the default depth is limited to 4 (it can be changed using the pustefix.liveroot.maxdepth property).

Here’s the example commandline for a Maven multi project with a webapp subproject from which you start Tomcat, whereas the other subprojects are found by using the main project as root using the relative path ..:

[/tmp/mainproject/webapp]$ mvn tomcat:run-war -Dpustefix.liveroot=..

Alternatively you can specify an absolute path:

[/tmp/mainproject/webapp]$ mvn tomcat:run-war -Dpustefix.liveroot=/tmp/mainproject