Apache ServiceMix
First I had to answer myself why to deploy a web application on the Apache ServiceMix? Simply – because we had it in place. We use it as a runtime container for web services (many popular ESB’s are based on the ServiceMix, such as Fuse ESB, Talend ESB, ..). I find the Apache ServiceMix very lightweight, having small footprint even under workload. So when creating a web application accessing exposed services (Web Services or OSGi based), it makes sense to deploy the web app directly in the ServiceMix instead of spinning up an extra web server just for one or two simple apps.
There’s a great resource by David Valeri about deploying a spring-mvc web application in the OSGi environment (and much more..). http://davidvaleri.wordpress.com/2011/08/17/deploying-spring-mvc-based-web-applications-to-osgi-using-apache-servicemix/
In this exercise Talend ESB 5.2.0 based on Apache Karaf 2.2.9 is used. And lot of web searching and trying.
Configuring the authentication and authorization
Once I had my web app running, from the J2EE world I am used to set up the role based security using built in JAAS. It proved to be not so straightforward with the default Apache ServiceMix setup. The ServiceMix already uses JAAS realm ‘karaf’ by default users and groups defined in the ./etc/user.properties file. for start I am happy with that. There are ways to set up JDBC or LDAP based realms, but it is not the goal and all I wanted is at least a simple basic role based security around my web app without weight of the whole spring-security configuration.
org.ops4j.pax.web.config.file=./etc/jetty.xml
in the ./etc/user.properties file I defined a user with its role user (e.g. webuser=
<?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.xsd">
<bean id="loginService" class="org.eclipse.jetty.plus.jaas.JAASLoginService">
<property name="name" value="karaf" />
<property name="loginModuleName" value="karaf" />
</bean>
<bean id="constraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="BASIC"/>
<property name="roles" value="user"/>
<property name="authenticate" value="true"/>
</bean>
<bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="constraint"/>
<property name="pathSpec" value="/*"/>
</bean>
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="authenticator">
<bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator"/>
</property>
<property name="constraintMappings">
<list>
<ref bean="constraintMapping"/>
</list>
</property>
<property name="loginService" ref="loginService" />
<property name="strict" value="false" />
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>example_application</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<security-constraint>
<display-name>authenticated</display-name>
<web-resource-collection>
<web-resource-name>All files</web-resource-name>
<description/>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description/>
<role-name>user</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>karaf</realm-name>
</login-config>
<security-role>
<description/>
<role-name>user</role-name>
</security-role>
</web-app>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<!--
Enable support for non-bundle packaging types
See: http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html
-->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
</execution>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Bundle-SymbolicName>gmap1</Bundle-SymbolicName>
<Export-Package/>
<Import-Package>
javax.servlet,
javax.servlet.http,
javax.servlet.*,javax.servlet.jsp.*,
javax.servlet.jsp.jstl.*,
javax.security.auth,
javax.security.auth.callback,
javax.security.auth.login,
javax.security.auth.spi,
org.apache.karaf.jaas.modules,
org.eclipse.jetty.plus.jaas,
org.eclipse.jetty.security,
org.eclipse.jetty.util.security,
org.eclipse.jetty.security.authentication,
*
</Import-Package>
<DynamicImport-Package>javax.*, org.xml.sax, org.xml.sax.*, org.w3c.*</DynamicImport-Package>
<Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>
WEB-INF/lib</Embed-Directory>
*;scope=compile|runtime</Embed-Dependency>
true</Embed-Transitive>
<Web-ContextPath>/gmap1</Web-ContextPath>
<Webapp-Context>/gmap1</Webapp-Context>
</instructions>
</configuration>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>jar</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
<instructions>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>7.5.3.v20111011</version>
<scope>provided</scope>
</dependency>
</dependencies>
I believe on the *NIX environment we can happily set up the NIO transport channel instead of the blocking connectors.
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host">
<SystemProperty name="jetty.host" />
</Set>
<Set name="port">
<SystemProperty name="jetty.port" default="8040"/>
</Set>
<Set name="maxIdleTime">30000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<Set name="lowResourcesConnections">5000</Set>
<Set name="lowResourcesMaxIdleTime">5000</Set>
<Set name="requestHeaderSize">8192</Set>
<Set name="responseHeaderSize">8192</Set>
<Set name="useDirectBuffers">false</Set>
</New>
</Arg>
</Call>
features:install war
install -s war:mvn:<group-id>/<artifact-id>/<version>/war