Convert Spring custom valve to OSGi

Question

I have some custom valves in our project that I am trying to convert to OSGI for our Jahia 8 instance.

I followed the documentation and the code on OSGi-modules-samples/auth-valve/src/main/java/org/foo/modules/valve/MyValve.java at master · Jahia/OSGi-modules-samples (github.com)

With the spring configuration, after the first authentication, we do not enter the valve with a user who is logged in. With the OSGI configuration, we always enter the valve.

Answer

A valve is integrated into a pipeline, where each valve is activated sequentially in the order they are listed within the Pipeline valve array.

To ensure a valve is invoked at the appropriate stage, you can use one of three methods:

  1. Utilize a debugger to place a breakpoint in the invoke method of your valve. Attempt a login, and once the breakpoint is hit, examine the stack to identify which valves were called beforehand.
  2. Run the following script in Jahia's Groovy console:
    import org.jahia.osgi.BundleUtils;
    import org.jahia.pipelines.Pipeline;

    // We get the authPipeline:
    org.jahia.pipelines.impl.GenericPipeline authPipeline = BundleUtils.getOsgiService(Pipeline.class,"(type=authentication)");
    Valve[] registeredValves = authPipeline.getValves();
    int pos = 0;
    log.info("Position\tValve");
    for (Valve v : registeredValves) {
      if (v instanceof BaseAuthValve) {
          pos ++;
         log.info(pos+"\t\t"+((BaseAuthValve) v).getId());
      }
    }
  3. Enable specific debugging logs to check the invocation sequence.

If your valve is incorrectly positioned, review the OSGi component's activate method for the following line:

 @Activate
    public void activate(BundleContext bundleContext) {
        setId("testValve");
        removeValve(authPipeline);
-->     addValve(authPipeline, 0, null, null);
    }


According to the documentation on Spring-based Authentication valves, Authentication-valves, it's necessary to define your valve's position in the pipeline explicitly. Previously, with Spring beans, this was done at the bean definition level. In OSGi, it's specified in the method shown above.

addValve(authPipeline, 0, null, null);

The first argument specifies the authPipeline, the second the valve's position in the pipeline, where:

  • 0 positions the valve to be called first,
  • -1 positions it to be called last, or after/before a valve specified in the third or last arguments, respectively.
  • Any other value indicates a fixed position.

In the provided Jahia OSGi example, the valve is positioned at the beginning (0), it is why it was invoked each time.