Skip to content

Enhanced Switch with prefix fallback mode - #749

Merged
ar merged 3 commits into
jpos:mainfrom
barspi:feat/swtich-with-prefix
Aug 11, 2026
Merged

Enhanced Switch with prefix fallback mode#749
ar merged 3 commits into
jpos:mainfrom
barspi:feat/swtich-with-prefix

Conversation

@barspi

@barspi barspi commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

This PR extends Switch with optional prefix-based routing while preserving the existing strict behavior by default. Prefix matching is enabled only when configured with mode=prefix.

How it works

In prefix mode, Switch first attempts the traditional exact (strict) lookup. If no exact match exists, it checks the configured routing keys from longest to shortest, giving the most specific (i.e., longest) prefix priority.

For efficiency, the configured <property> keys are sorted once during configuration in a cached list, while group values continue to be retrieved from the Configuration at selection time.

Test and docs

  • A thorough SwitchTest is provided (one did not exist before).
  • The documentation in the proguide has been updated.

OBSERVATIONS:

  • The pre-sorting caching mechanism could break under property reconfiguration (only if changing the key set) after the initial instantiation and configuration of the participant. But this is a very unusual situation, and probably bad practice.

  • Only the key set is pre-sorted. The values themselves are still retrieved from cfg every time (as it was before) because that allows the value to be resolved dynamically each time if they use some jPOS Environment expression or jPOS Environment Provider string.

Configuration example

<participant class="org.jpos.transaction.participant.Switch"
             logger="Q2" realm="Switch">
    <property name="mode" value="prefix" />

    <property name="100"
              value="generic" />
    <property name="100.30"
              value="balance-inquiry" />
    <property name="100.30.182"
              value="customer-balance-inquiry" />

    <property name="unknown"
              value="unsupported" />
</participant>

@ar-agt ar-agt left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Switch accepts the generic Configuration interface, but prefix mode caches raw cfg.keySet() entries as routing keys. This does not work with SubConfiguration: get("100") resolves through its prefix, while keySet() returns keys such as switch.100. With switch.mode=prefix and switch.100=generic, selecting 100.30 finds no matching cached key and falls through to unknown.

Please add a SubConfiguration regression test and normalize the routing keys (or avoid deriving routes from keySet()).

@ar-agt

ar-agt commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Suggested fix: correct the inconsistency in SubConfiguration, then keep the regression at the Switch boundary. get("100") resolves a prefixed property, so keySet() should return that same logical namespace.

diff --git a/jpos/src/main/java/org/jpos/core/SubConfiguration.java b/jpos/src/main/java/org/jpos/core/SubConfiguration.java
@@
     public Set<String> keySet() {
         Set<String> keys = new HashSet<String>();
         for (String k : cfg.keySet())
             if (k.startsWith(prefix))
-                keys.add(k);
+                keys.add(k.substring(prefix.length()));

         return keys;
     }
diff --git a/jpos/src/test/java/org/jpos/transaction/participant/SwitchTest.java b/jpos/src/test/java/org/jpos/transaction/participant/SwitchTest.java
@@
 import org.jpos.core.Configuration;
 import org.jpos.core.SimpleConfiguration;
+import org.jpos.core.SubConfiguration;
@@
+    @Test
+    public void testPrefixModeWorksWithSubConfiguration() {
+        Configuration parent = new SimpleConfiguration();
+        parent.put("switch.mode", "prefix");
+        parent.put("switch.100", "generic");
+        parent.put("switch.unknown", UNKNOWN_GROUP);
+        selector.setConfiguration(new SubConfiguration(parent, "switch."));
+
+        assertEquals("generic", select("100.30"));
+    }

A Switch-only workaround cannot reliably infer an arbitrary Configuration prefix.

@barspi

barspi commented Aug 10, 2026

Copy link
Copy Markdown
Contributor Author

@ar-agt
SubConfiguration@keySet() has been fixed to respect the contract and return local (unprefixed) property names.

This makes Switch work fine under the hypothetical-never-gonna-happen Switch usage with SubConfiguration.

New tests have been added.

@ar
ar merged commit d34531e into jpos:main Aug 11, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants