7

I'm having an "interesting" issue with the order in which ADF cartridges are executed (I think).

I'm using the "Set Claims as Characteristics" (c2c) cartridge to load device information into a user profile (see also this thread for more background) and this cartridge seems to be executing before the Context Engine, with the unfortunate result that characteristics are being set "one click too late".

Looking at my logs confirms that indeed the c2c cartridge is executed before the engine.

The order of the cartridges in cd_ambient_conf.xml is:

<Cartridge File="context_engine_cartridge_conf.xml" />
<Cartridge File="c2c.xml" />
<Cartridge File="cd_webservice_preview_cartridge.xml" />
<Cartridge File="footprint_cartridge_conf.xml" />

I've tried setting one of the Output claims of the context engine as an Input claim for the c2c cartridge, but that didn't make a change.

<ClaimProcessorDefinitions>
  <ClaimProcessorDefinition Uri="taf:custom:personalization"
    ImplementationClass="com.sdl.tridion.context.personalization.SetClaimsAsCharacteristics">
    <RequestStart>
      <InputClaims>
        <ClaimDefinition Uri="taf:claim:context:device:tablet" />
      </InputClaims>
    </RequestStart>
  </ClaimProcessorDefinition>
</ClaimProcessorDefinitions>

Any idea how to make sure this cartridge executes after the Context Engine?

UPDATE

After long debugging, the issue was found to be that the Context Engine Cartridge did not define any of its claims as an OutputClaim and therefore the ADF couldn't detect the dependency. Changing the context_engine_cartridge_conf.xml to specify at least one output claim "fixed" it. Now I have to go bug the context engine developers...

2
  • Isn't the order of execution simply reverse to the order of configuration? So putting c2c.xml first and context_engine_cartridge_conf.xml after it? Commented Oct 10, 2013 at 14:16
  • I thought so too... but no, it is based on claim dependencies, which makes sense. Anyway, the next version of the context engine (due soon) will not have this issue anymore.
    – Nuno Linhares
    Commented Oct 10, 2013 at 17:02

3 Answers 3

7

The order of cartridges are not guaranteed by default, but you can control it a little bit by declaring one cartridge dependent on the output claim of another cartridge. The caveat is that the output claim must be listed in the configuration of that cartridge (and then listed as an input claim on the dependent cartridge).

So if Cartridge A declares an output claim "taf:custom:outputA" and Cartridge B declares "taf:custom:outputA" as an input claim, Cartridge B will be run after Cartridge A. If Cartridge A outputs the claim but does not declare it as an output claim, the order is not guaranteed. That could be your issue here - in which case I would consider it a shortcoming of the c2c cartridge.

2
  • Cartridge A would be the Context Engine Cartridge, and it does declare taf:claim:context:device:tablet as an output claim. I've set this one as both input claim AND output claim on the c2c.xml and it still gets executed before the context engine cartridge...
    – Nuno Linhares
    Commented Oct 10, 2013 at 15:51
  • 1
    It should only be defined as an output claim in the engine, not your own cartridge. Commented Oct 10, 2013 at 15:57
4

Don't set multiple output claims:

The relationship between Input and Output claims should be N-1 (so 1 output claim can have more input claims

2

I looked at the code and this is how the cartridges are loaded:

public static Engine newEngine() throws AmbientDataException {
    try {
        AmbientDataConfig ambientDataConfig = AmbientDataContext.getAmbientDataConfig();
        Set cartridgeDefinitions = new HashSet();
        Configuration config;
        for (Iterator i$ = ambientDataConfig.getCartridgeConfigurations().iterator();
                i$.hasNext();
                cartridgeDefinitions.add(cartridgeDefinitionFromConfig(config))) {
            config = (Configuration)i$.next();
        }

        return new Engine(cartridgeDefinitions);
    } catch (ConfigurationException ex) {
        LOG.error("Unable to configure the AmbientData Framework", ex);
        throw new AmbientDataException("Error while configuring ambient data framework", ex);
    }
}

So it "seems" it loads the cartridges from the XML confg file (cd_ambient_conf.xml) in the getCartridgeConfigurations by executing the following loop:

for (Iterator i$ = ConfigurationHelper.getConfigurations(configuration,
            "/Configuration/Cartridges/Cartridge").iterator();
        i$.hasNext();
        result.add((new XMLConfigurationReader()).readConfiguration(fileName,
            "schemas/cd_ambient_cartridge_conf.xsd"))) {
       ....
}

Which means they should be loaded in the same order they show in the configuration file. Further investigation, the cartridges configuration are saved on a java.util.HashSet object which by definition it doesn't care about the order of its elements. Copied from the javadoc:

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, Serializable

This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.

So I think that answers your question. I don't think there's a way to control the order of the execution. But yet again, let's see if someone from R&D confirms my research.

UPDATED:

The ordering apparently happens using the DependencyAnalyzer class which moves the cartridge definitions into "Sorted Lists" (java.util.ArrayList). Such DependencyAnalyzer indeed checks the Input/Ouput claims configuration to determine what's the right order for the cartridges, it does it both for RequestStart & RequestEnd as well as SessionStart & SessionEnd.

2
  • Hope it is ok to partially show the -decompiled- code :) Commented Oct 10, 2013 at 14:48
  • OK, I'll go review my output claim names and scopes...
    – Nuno Linhares
    Commented Oct 10, 2013 at 15:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.