diff --git a/src/main/java/hudson/remoting/Engine.java b/src/main/java/hudson/remoting/Engine.java
index 96a2b11a2..15484e12d 100644
--- a/src/main/java/hudson/remoting/Engine.java
+++ b/src/main/java/hudson/remoting/Engine.java
@@ -128,6 +128,7 @@ public void run() {
* This value is determined from {@link #candidateUrls} after a successful connection.
* Note that this URL DOES NOT have "tcpSlaveAgentListener" in it.
*/
+ @CheckForNull
private URL hudsonUrl;
private final String secretKey;
@@ -171,6 +172,12 @@ public void setJarCache(JarCache jarCache) {
this.jarCache = jarCache;
}
+ /**
+ * Provides Jenkins URL if available.
+ * @return Jenkins URL. May return {@code null} if the connection is not established or if the URL cannot be determined
+ * in the {@link JnlpAgentEndpointResolver}.
+ */
+ @CheckForNull
public URL getHudsonUrl() {
return hudsonUrl;
}
@@ -334,6 +341,7 @@ private void innerRun(IOHub hub, SSLContext context, ExecutorService service) {
events.status("Could not resolve server among " + candidateUrls);
return;
}
+ hudsonUrl = endpoint.getServiceUrl();
events.status(String.format("Agent discovery successful%n"
+ " Agent address: %s%n"
diff --git a/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpoint.java b/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpoint.java
index 203b45d9e..af58d7afc 100644
--- a/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpoint.java
+++ b/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpoint.java
@@ -29,6 +29,7 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.URL;
import java.nio.channels.SocketChannel;
import java.security.interfaces.RSAPublicKey;
import java.util.Collections;
@@ -65,7 +66,23 @@ public class JnlpAgentEndpoint {
*/
@CheckForNull
private final Set protocols;
+
+ /**
+ * Jenkins URL for the discovered endpoint.
+ * @since TODO
+ */
+ @CheckForNull
+ private final URL serviceUrl;
+ /**
+ * @deprecated Use {@link #JnlpAgentEndpoint(java.lang.String, int, java.security.interfaces.RSAPublicKey, java.util.Set, java.lang.String)}
+ */
+ @Deprecated
+ public JnlpAgentEndpoint(@Nonnull String host, int port, @CheckForNull RSAPublicKey publicKey,
+ @CheckForNull Set protocols) {
+ this(host, port, publicKey, protocols, null);
+ }
+
/**
* Constructor for a remote {@code Jenkins} instance.
*
@@ -73,9 +90,12 @@ public class JnlpAgentEndpoint {
* @param port the port.
* @param publicKey the {@code InstanceIdentity.getPublic()} of the remote instance (if known).
* @param protocols The supported protocols.
+ * @param serviceURL URL of the service hosting the remoting endpoint.
+ * Use {@code null} if it is not a web service or if the URL cannot be determined
+ * @since TODO
*/
public JnlpAgentEndpoint(@Nonnull String host, int port, @CheckForNull RSAPublicKey publicKey,
- @CheckForNull Set protocols) {
+ @CheckForNull Set protocols, @CheckForNull URL serviceURL) {
if (port <= 0 || 65536 <= port) {
throw new IllegalArgumentException("Port " + port + " is not in the range 1-65535");
}
@@ -83,6 +103,7 @@ public JnlpAgentEndpoint(@Nonnull String host, int port, @CheckForNull RSAPublic
this.port = port;
this.publicKey = publicKey;
this.protocols = protocols == null ? null : Collections.unmodifiableSet(new LinkedHashSet(protocols));
+ this.serviceUrl = serviceURL;
}
/**
@@ -95,6 +116,15 @@ public InetSocketAddress getAddress() {
return new InetSocketAddress(host, port);
}
+ /**
+ * Retrieves URL of the web service providing the remoting endpoint.
+ * @return Service URL if available. {@code null} otherwise.
+ */
+ @CheckForNull
+ public URL getServiceUrl() {
+ return serviceUrl;
+ }
+
/**
* Gets the hostname.
*
diff --git a/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpointResolver.java b/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpointResolver.java
index 5ba2bda58..2984d80d5 100644
--- a/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpointResolver.java
+++ b/src/main/java/org/jenkinsci/remoting/engine/JnlpAgentEndpointResolver.java
@@ -127,7 +127,16 @@ public void setTunnel(String tunnel) {
public JnlpAgentEndpoint resolve() throws IOException {
IOException firstError = null;
for (String jenkinsUrl : jenkinsUrls) {
- URL salURL = toAgentListenerURL(jenkinsUrl);
+
+ final URL selectedJenkinsURL;
+ final URL salURL;
+ try {
+ selectedJenkinsURL = new URL(jenkinsUrl);
+ salURL = toAgentListenerURL(jenkinsUrl);
+ } catch (MalformedURLException ex) {
+ LOGGER.log(Level.WARNING, String.format("Cannot parse agent endpoint URL %s. Skipping it", jenkinsUrl), ex);
+ continue;
+ }
// find out the TCP port
HttpURLConnection con =
@@ -223,7 +232,8 @@ public int compare(String o1, String o2) {
if (tokens[0].length() > 0) host = tokens[0];
if (tokens[1].length() > 0) port = Integer.parseInt(tokens[1]);
}
- return new JnlpAgentEndpoint(host, port, identity, agentProtocolNames);
+
+ return new JnlpAgentEndpoint(host, port, identity, agentProtocolNames, selectedJenkinsURL);
} finally {
con.disconnect();
}