Create a Custom Valve - BloomReach Experience - Open Source CMS
15-04-2019

Create a Custom Valve

Introduction

Goal

Develop a custom valve and inject it into the delivery tier's request processing pipeline.

Background

In Bloomreach Experience Manager's delivery framework (HST), requests are processed through a series of valves assembled together as a pipeline. Implementation projects can inject custom valves at any point into the default pipeline.

This page explains how to create a custom valve and inject it into the default request processing pipeline using Spring configuration.

The default pipeline is defined as DefaultSitePipeline in classpath:/org/hippoecm/hst/site/container/SpringComponentManager-pipelines.xml.

Details

A custom valve is implemented as a Java class extending org.hippoecm.hst.container.valves.AbstractOrderableValve. In the Spring bean definition for the custom valve, the properties beforeValves and afterValves can be used to specify where in the existing pipeline the custom valve should be injected. To enable other valves to position themselves relative to the custom valve, the bean definition should also define the property valveName.

Typically, beforeValves and afterValves each specify a single valve but both accept a comma-separated list of valves as well. The valveName, as a best practice, should be equal to the Spring bean id (in case of no id, use a logical name, like the camel case class name).

An example bean definition for a custom valve (full example below):

<bean id="myCustomValve" class="org.example.container.MyCustomValve">
    <property name="valveName" value="myCustomValve" />
    <property name="afterValves" value="securityValve, subjectBasedSessionValve"/>
    <property name="beforeValves" value="pageCachingValve"/>
</bean>

Example

This example shows a custom valve class MyCustomValve that is injected into the existing HST DefaultSitePipeline after the securityValve and before the pageCachingValve.

Create a Custom Valve Class

In the site/components module of your project, create a Java class MyCustomValve and make it extend AbstractOrderableValve.

site/components/src/main/java/org/example/container/MyCustomValve.java

package org.example.container;

import org.hippoecm.hst.container.valves.AbstractOrderableValve;
import org.hippoecm.hst.core.container.ContainerException;
import org.hippoecm.hst.core.container.ValveContext;

public class MyCustomValve extends AbstractOrderableValve {
    @Override
    public void invoke(ValveContext context) throws ContainerException {
        try {
            // perform custom processing here
        } finally {
            context.invokeNext();
        }
    }
}

Configure Spring to Inject the Custom Valve

In the site/components module of your project, create a Spring configuration file src/main/resources/META-INF/hst-assembly/overrides/custom-valves.xml.

Configure a myCustomValve bean for your valve class and specify the valveName, afterValves, and beforeValves properties. Inject your custom bean into the existing HST DefaultSitePipeline.

site/components/src/main/resources/META-INF/hst-assembly/overrides/custom-valves.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.xsd">

  <bean id="myCustomValve" class="org.example.container.MyCustomValve">
    <property name="valveName" value="myCustomValve" />
    <property name="afterValves" value="securityValve" />
    <property name="beforeValves" value="pageCachingValve" />
  </bean>

  <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
      <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="org.hippoecm.hst.core.container.Pipelines" />
        <property name="targetMethod" value="getPipeline" />
        <property name="arguments">
          <value>DefaultSitePipeline</value>
        </property>
      </bean>
    </property>
    <property name="targetMethod" value="addProcessingValve" />
    <property name="arguments">
      <ref bean="myCustomValve" />
    </property>
  </bean>

</beans>

Rebuild and Restart

Rebuild and restart your project.

Request a page in the site. Your custom valve should be invoked.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?