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

1

6

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?

Kessiah answered 11/11, 2016 at 18:38 Comment(0)
H
5

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 2:

Since v0.2.2 there has been EndpointUtil.updateUrl that can be used to modify EndpointDescriptions.

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()
    );
}

Caveat: this works in most cases, but one notable case it does not work is when the remote endpoint URL contains characters that aren't allowed in a URL hostname (according to the RFC), such as underscore (a '_'), which unfortunately IS allowed in e.g. the hostname of a Windows machine. So you may need to use some other method of parsing the endpoint URL rather than relying on the URI class to do it.

Hunley answered 11/11, 2016 at 19:53 Comment(3)
thanks for the reply Kevin , i understand what you are trying to say .. how can i though create new set of EndpointDescriptions , i dont see any way or setter methods for itKessiah
" So you may need to use some other method of parsing the endpoint URL rather than relying on the URI class to do it.". What about EndpointUtil.getHost(url)?Badly
@Badly this was originally written before EndpointUtil.updateUrl and EndpointUtil.getHost existed. There's a second update in here that mentions these now.Hunley

© 2022 - 2024 — McMap. All rights reserved.