diff --git a/Server/src/config/config.xml b/Server/src/config/config.xml index a4ee28ed..42bea2a3 100644 --- a/Server/src/config/config.xml +++ b/Server/src/config/config.xml @@ -80,7 +80,7 @@ pollerConfigBase.outboxdir="$properties.storageBaseDir$/outbox/$partnership.receiver.as2_id$" pollerConfigBase.errordir="$properties.storageBaseDir$/outbox/error/$date.yyyy$-$date.MM$-$date.dd$/$partnership.receiver.as2_id$" pollerConfigBase.interval="5" - pollerConfigBase.defaults="sender.as2_id=$partnership.sender.as2_id$, receiver.as2_id=$partnership.receiver.as2_id$" + pollerConfigBase.defaults="sender.as2_id=$partnership.sender.as2_id$, receiver.as2_id=$partnership.receiver.as2_id$, name=$partnership.name$" pollerConfigBase.sendfilename="true" pollerConfigBase.mimetype="application/EDI-X12" pollerConfigBase.process_files_in_parallel="false" diff --git a/Server/src/main/java/org/openas2/params/MessageParameters.java b/Server/src/main/java/org/openas2/params/MessageParameters.java index cd26c1b1..65fd3284 100644 --- a/Server/src/main/java/org/openas2/params/MessageParameters.java +++ b/Server/src/main/java/org/openas2/params/MessageParameters.java @@ -13,6 +13,7 @@ public class MessageParameters extends ParameterParser { public static final String KEY_SENDER = "sender"; public static final String KEY_RECEIVER = "receiver"; + public static final String KEY_NAME = "name"; public static final String KEY_ATTRIBUTES = "attributes"; public static final String KEY_HEADERS = "headers"; public static final String KEY_CONTENT_FILENAME = "content-disposition"; @@ -29,6 +30,15 @@ public MessageParameters(Message target) { public void setParameter(String key, String value) throws InvalidParameterException { StringTokenizer keyParts = new StringTokenizer(key, ".", false); + if (keyParts.countTokens() == 1) { + if (key.equals(KEY_NAME)) { + getTarget().getPartnership().setName(value); + } else { + throw new InvalidParameterException("Unsupported key identifier", this, key, null); + } + return; + } + if (keyParts.countTokens() != 2) { throw new InvalidParameterException("Invalid key format", this, key, null); } diff --git a/Server/src/test/java/org/openas2/processor/receiver/PartnershipNameRoutingTest.java b/Server/src/test/java/org/openas2/processor/receiver/PartnershipNameRoutingTest.java new file mode 100644 index 00000000..939f148e --- /dev/null +++ b/Server/src/test/java/org/openas2/processor/receiver/PartnershipNameRoutingTest.java @@ -0,0 +1,91 @@ +package org.openas2.processor.receiver; + +import org.junit.jupiter.api.Test; +import org.openas2.Session; +import org.openas2.message.AS2Message; +import org.openas2.message.Message; +import org.openas2.params.InvalidParameterException; +import org.openas2.params.MessageParameters; +import org.openas2.partner.Partnership; +import org.openas2.partner.XMLPartnershipFactory; + +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +/** + * Verifies that a poller whose "defaults" include the partnership name (e.g. + * "..., name=$partnership.name$") resolves that partnership by name, so that several partnerships + * between the same sender and receiver AS2 IDs can each send with their own configuration instead + * of all using the first partnership that matches the ID pair. + */ +public class PartnershipNameRoutingTest { + + private static final String DEFAULTS = "sender.as2_id=MyCompany_OID, receiver.as2_id=PartnerA_OID"; + + private static Partnership partnership(String name, String subject) { + Partnership p = new Partnership(); + p.setName(name); + p.setSenderID(Partnership.PID_AS2, "MyCompany_OID"); + p.setReceiverID(Partnership.PID_AS2, "PartnerA_OID"); + p.setAttribute(Partnership.PA_SUBJECT, subject); + return p; + } + + private static AS2DirectoryPollingModule poller(String partnershipName) { + XMLPartnershipFactory factory = new XMLPartnershipFactory(); + List partnerships = new ArrayList(); + partnerships.add(partnership("MyCompany-to-PartnerA", "first config")); + partnerships.add(partnership("MyCompany-to-PartnerA-alt", "second config")); + factory.setPartnerships(partnerships); + + Session session = (Session) Proxy.newProxyInstance(Session.class.getClassLoader(), new Class[]{Session.class}, + (proxy, method, args) -> "getPartnershipFactory".equals(method.getName()) ? factory : null); + + AS2DirectoryPollingModule module = new AS2DirectoryPollingModule() { + @Override + public Session getSession() { + return session; + } + }; + String defaults = DEFAULTS; + if (partnershipName != null) { + defaults += ", " + MessageParameters.KEY_NAME + "=" + partnershipName; + } + module.setParameter(MessageBuilderModule.PARAM_DEFAULTS, defaults); + return module; + } + + @Test + public void pollerUsesItsOwnPartnershipWhenAnotherSharesTheSameIds() throws Exception { + Message msg = poller("MyCompany-to-PartnerA-alt").buildBaseMessage("test.edi"); + + assertEquals("MyCompany-to-PartnerA-alt", msg.getPartnership().getName()); + assertEquals("second config", msg.getSubject()); + } + + @Test + public void pollerWithoutPartnershipNameStillResolvesByIds() throws Exception { + Message msg = poller(null).buildBaseMessage("test.edi"); + + assertEquals("MyCompany-to-PartnerA", msg.getPartnership().getName()); + assertEquals("first config", msg.getSubject()); + } + + @Test + public void unknownPartnershipNameFallsBackToIdLookup() throws Exception { + Message msg = poller("no-such-partnership").buildBaseMessage("test.edi"); + + assertEquals("MyCompany-to-PartnerA", msg.getPartnership().getName()); + } + + @Test + public void unsupportedSinglePartKeyIsRejected() { + MessageParameters params = new MessageParameters(new AS2Message()); + + assertThrows(InvalidParameterException.class, () -> params.setParameters("foo=bar")); + } +}