Harshal Bhavsar Harshal Bhavsar - 19 days ago 6
Java Question

Java OPC-UA Client Eclipse Milo endpoint URL changes to localhost

I am using Java OPC-UA client Eclipse Milo. Whenever I create a session using endpoint URL of server, method

UaTcpStackClient.getEndpoints()
changes URL to
localhost
.

String endpointUrl = "opc.tcp://10.8.0.104:48809";

EndpointDescription[] endpoints = UaTcpStackClient.getEndpoints(endpointUrl).get();

EndpointDescription endpoint = Arrays.stream(endpoints)
.filter(e -> e.getSecurityPolicyUri().equals(securityPolicy.getSecurityPolicyUri()))
.findFirst().orElseThrow(() -> new Exception("no desired endpoints returned"));


However value of
endpoint.getEndpointUrl()
returns
opc.tcp://127.0.0.1:4880/
which results failure in connection.

I have no idea why my OPC URL gets changed?

Answer

This is a pretty common problem when implementing a UA client.

The server is ultimately responsible for the contents of the endpoints you get back, and the one you're connecting to is (mis)configured to return 127.0.0.1 in the endpoint URLs, apparently.

You need to check the endpoints you get from the server and then depending on the nature of your application either just replace them right away with new copied EndpointDescriptions containing URLs that you've modified or let the user know and ask them for permission first.

Either way, you need to create a new set of EndpointDescriptions in which you've corrected the URL before you go on to create the OpcUaClient.

Alternatively... you could figure out how to get your server configured properly so it returns endpoints containing a publicly reachable hostname or IP address.

Update:

The code to replace the endpoint URL could be some variation of this:

private static EndpointDescription updateEndpointUrl(
    EndpointDescription original, String hostname) throws URISyntaxException {

    URI uri = new URI(original.getEndpointUrl()).parseServerAuthority();

    String endpointUrl = String.format(
        "%s://%s:%s%s",
        uri.getScheme(),
        hostname,
        uri.getPort(),
        uri.getPath()
    );

    return new EndpointDescription(
        endpointUrl,
        original.getServer(),
        original.getServerCertificate(),
        original.getSecurityMode(),
        original.getSecurityPolicyUri(),
        original.getUserIdentityTokens(),
        original.getTransportProfileUri(),
        original.getSecurityLevel()
    );
}