RTS-JTA bridge uses wrong participant address

20 views
Skip to first unread message

Sándor Orosz

unread,
May 19, 2023, 12:05:47 PM5/19/23
to narayana-users
Hi!

We have two nodes that run User and Document service respectively. We want to create REST endpoints that use distributed transactions. An overarching endpoint would create the transaction, and call User service which in turn would call Document service. We initialize the REST-AT transaction correctly via TxSupport, and we propagate the transaction by passing down the Link header for subsequent calls.

We use Wildfly 26 on both nodes with RTS enabled, and we use the User node as the transaction coordinator. Our dummy tests work perfectly when we use User node, but if we call out to Document node the transaction fails in the prepare phase. We debugged and logged everything, and it turns out that the RTS-JTA bridge contacts the wrong participant address.

Document node receives a Link header to the enlistment URL of the User node, but instead of parsing the host it just assumes localhost has the transaction coordinator. ParticipantsManagerImpl creates a new TxSupport class, which uses jboss.bind.address and defaults to localhost for the participant link. If we run the two services on one node this happens to be correct, but fails as soon as we run them on separate nodes like in Docker Compose. Relevant excerpts from the logs of the Document service:

2023-05-19T15:16:09.137002186Z 2023-05-19 17:16:09.136 TRACE [thread:default task-1] [org.jboss.narayana.rest.bridge.inbound.InboundBridgeManager] [sid:46GFJIYMRJ6LJH06] - InboundBridgeManager.createInboundBridge: enlistmentUrl=http://eets_user:8080/rest-at-coordinator/tx/transaction-manager/0_ffffac120003_-665263eb_646791da_37
[...]
2023-05-19T15:16:09.148074354Z 2023-05-19 17:16:09.147 TRACE [thread:default task-1] [org.jboss.narayana.rest.integration.ParticipantsManagerImpl] [sid:46GFJIYMRJ6LJH06] - ParticipantsManagerImpl.enlist: participant enlisted. participantUrl=http://0.0.0.0:8080/rest-at-participant/0:ffffac120002:-17edb7f9:646791d9:28, participantInformation=<ParticipantInformation: id=0:ffffac120002:-17edb7f9:646791d9:28, applicationId=org.jboss.narayana.rest.bridge.inbound.InboundBridgeManager:application_id, recoveryURL=http://eets_user:8080/rest-at-coordinator/tx/recovery-coordinator/0_ffffac120003_-665263eb_646791da_37/0_ffffac120003_-665263eb_646791da_3f, participant=org.jboss.narayana.rest.bridge.inbound.InboundBridgeParticipant@4542a258, status=TransactionActive>

For the moment I plan to create a workaround, use TxSupport.setTxnMgrUrl to set the address of the transaction manager from environment or properties. Is this the correct approach, or is there a more idiomatic way to do this?

Br,
Frigo

user.txt
document.txt

Sándor Orosz

unread,
May 20, 2023, 6:13:05 PM5/20/23
to narayana-users
Upon further inspection it turns out it's not TxSupport but rather ParticipantsService is at fault. It has a line where it sets the base URL of the participants factory:

    ParticipantsManagerFactory.getInstance().setBaseUrl(this.getBaseUrl());

And the base URL comes from AbstractRTSService.getBaseUrl():

    protected String getBaseUrl() {
        String address = ((SocketBinding)this.injectedSocketBinding.getValue()).getAddress().getHostAddress();
        int port = ((SocketBinding)this.injectedSocketBinding.getValue()).getAbsolutePort();
        return ((SocketBinding)this.injectedSocketBinding.getValue()).getAddress() instanceof Inet4Address ? "http://" + address + ":" + port : "http://[" + address + "]:" + port;
    }

So basically it takes whatever IP address was configured in standalone.xml, although I am not sure where exactly:

        <subsystem xmlns="urn:jboss:domain:rts:1.0">
            <servlet server="default-server" host="default-host" socket-binding="http"/>
        </subsystem>

        <subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
            <server name="default-server">
                <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
                <https-listener name="https" socket-binding="https" ssl-context="applicationSSC" enable-http2="true"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <http-invoker http-authentication-factory="application-http-authentication"/>
                </host>
            </server>
        </subsystem>

    <interfaces>
        <interface name="management">
            <inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
        </interface>
        <interface name="public">
            <inet-address value="${jboss.bind.address:127.0.0.1}"/>
        </interface>
    </interfaces>

    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
        <socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
        <socket-binding name="http" port="${jboss.http.port:8080}"/>
        <socket-binding name="https" port="${jboss.https.port:8443}"/>
        <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
        <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
        <socket-binding name="txn-recovery-environment" port="4712"/>
        <socket-binding name="txn-status-manager" port="4713"/>
        <outbound-socket-binding name="mail-smtp">
            <remote-destination host="${jboss.mail.server.host:localhost}" port="${jboss.mail.server.port:25}"/>
        </outbound-socket-binding>
    </socket-binding-group>

Where jboss.bind.address is 0.0.0.0 since we are using Docker containers.

How can I change the returned participant address so that it returns the Docker service names eets_document or eets_user?

Br,
Frigo

Marco Sappe Griot

unread,
May 22, 2023, 10:19:14 AM5/22/23
to Sándor Orosz, narayana-users
Good afternoon Sándor,
thank you for reaching out to us. If I understand correctly you are looking for a way to explicitly set the ip for jboss.bind.address in your Wildfly application.
I can link you a guide where it is well described how to do that: https://www.mastertheboss.com/jbossas/jboss-configuration/how-to-bind-wildfly-to-an-ip-address/
In particular for docker you might need to execute :
docker run -p 8080:8080 -p 9990:9990 -it jboss/wildfly /opt/jboss/wildfly/bin/standalone.sh -bmanagement=0.0.0.0 -b 0.0.0.0
As explained in the guide the '-b' option is used to specify the jboss.bind.address variable in the standalone.xml file.
If you keep having troubles could I ask you to share a reproducer?
Thanks,
Marco

--
You received this message because you are subscribed to the Google Groups "narayana-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to narayana-user...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/narayana-users/2437cd18-5b6c-4a4d-a11a-e9e1c7af7f6fn%40googlegroups.com.

Michael Musgrove

unread,
Nov 14, 2023, 6:57:33 AM11/14/23
to narayana-users
In light of Marco's answer I am marking this question as complete.
Reply all
Reply to author
Forward
0 new messages