diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogAgentClient.java b/src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogAgentClient.java index 57ea9702..06af9246 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogAgentClient.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/clients/DatadogAgentClient.java @@ -30,6 +30,7 @@ of this software and associated documentation files (the "Software"), to deal import com.timgroup.statsd.NonBlockingStatsDClient; import com.timgroup.statsd.ServiceCheck; import com.timgroup.statsd.StatsDClient; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -57,7 +58,6 @@ of this software and associated documentation files (the "Software"), to deal import org.datadog.jenkins.plugins.datadog.traces.mapper.JsonTraceSpanMapper; import org.datadog.jenkins.plugins.datadog.traces.write.*; import org.datadog.jenkins.plugins.datadog.util.CircuitBreaker; -import org.datadog.jenkins.plugins.datadog.util.SuppressFBWarnings; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; import org.json.JSONArray; import org.json.JSONObject; @@ -348,7 +348,7 @@ private void flushSafely() throws IOException { @Override public TraceWriteStrategy createTraceWriteStrategy() { - Set agentEndpoints = fetchAgentEndpoints(); + Set agentEndpoints = fetchAgentEndpoints(client, hostname, traceCollectionPort); boolean evpProxyExists = agentEndpoints.contains("/evp_proxy/v3/"); if (evpProxyExists) { DatadogGlobalConfiguration datadogGlobalDescriptor = DatadogUtilities.getDatadogGlobalDescriptor(); @@ -375,7 +375,7 @@ public TraceWriteStrategy createTraceWriteStrategy() { * @return a set of endpoints (if /info wasn't available, it will be empty) */ @SuppressFBWarnings("REC_CATCH_EXCEPTION") - Set fetchAgentEndpoints() { + public static Set fetchAgentEndpoints(HttpClient client, String hostname, Integer traceCollectionPort) { logger.fine("Fetching Agent info"); String url = String.format("http://%s:%d/info", hostname, traceCollectionPort); diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java index 273ffcbd..6f3ef5cf 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/configuration/DatadogAgentConfiguration.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.logging.Logger; import javax.annotation.Nonnull; import jenkins.model.Jenkins; @@ -17,6 +18,7 @@ import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; import org.datadog.jenkins.plugins.datadog.clients.DatadogAgentClient; +import org.datadog.jenkins.plugins.datadog.clients.HttpClient; import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -41,6 +43,8 @@ public class DatadogAgentConfiguration extends DatadogClientConfiguration { static final Integer DEFAULT_TRACE_COLLECTION_PORT_VALUE = 8126; static final Integer DEFAULT_LOG_COLLECTION_PORT_VALUE = null; + private static final int AGENT_CONNECTIVITY_CHECK_TIMEOUT_MILLIS = 2_000; + private final String agentHost; private final Integer agentPort; private final Integer agentLogCollectionPort; @@ -77,24 +81,28 @@ public DatadogClient createClient() { @Override public void validateTracesConnection() throws Descriptor.FormException { + FormValidation connectivityCheckResult = checkTracesConnectivity(agentHost, agentTraceCollectionPort); + if (connectivityCheckResult.kind == FormValidation.Kind.ERROR) { + throw new Descriptor.FormException("CI Visibility connectivity check failed: " + connectivityCheckResult.getMessage(), "ciVisibilityData"); + } + } + + private static FormValidation checkTracesConnectivity(String agentHost, Integer agentTraceCollectionPort) { if (StringUtils.isBlank(agentHost)) { - throw new Descriptor.FormException("CI Visibility requires agent host to be set", "agentHost"); + return FormValidation.error("Host name missing"); } if (agentTraceCollectionPort == null) { - throw new Descriptor.FormException("CI Visibility requires agent trace collection port to be set", "agentTraceCollectionPort"); + return FormValidation.error("Trace collection port missing"); } - String errorMessage = checkConnectivity(agentHost, agentTraceCollectionPort); - if (errorMessage != null) { - throw new Descriptor.FormException("CI Visibility connectivity check failed: " + errorMessage, "ciVisibilityData"); - } - } - - private static String checkConnectivity(final String host, final int port) { - try (Socket ignored = new Socket(host, port)) { - return null; - } catch (Exception ex) { - DatadogUtilities.severe(logger, ex, "Failed to create socket to host: " + host + ", port: " + port); - return ex.getMessage(); + try { + Set endpoints = DatadogAgentClient.fetchAgentEndpoints(new HttpClient(AGENT_CONNECTIVITY_CHECK_TIMEOUT_MILLIS), agentHost, agentTraceCollectionPort); + if (!endpoints.isEmpty()) { + return FormValidation.ok("Success!"); + } else { + return FormValidation.error("Failed to reach Datadog Agent using host " + agentHost + " and port " + agentTraceCollectionPort); + } + } catch (Exception e) { + return FormValidation.error(e.getMessage()); } } @@ -106,12 +114,21 @@ public void validateLogsConnection() throws Descriptor.FormException { if (agentLogCollectionPort == null) { throw new Descriptor.FormException("Logs collection requires agent log collection port to be set", "agentLogCollectionPort"); } - String errorMessage = checkConnectivity(agentHost, agentLogCollectionPort); + String errorMessage = checkTcpConnectivity(agentHost, agentLogCollectionPort); if (errorMessage != null) { throw new Descriptor.FormException("Logs collection connectivity check failed: " + errorMessage, "collectBuildLogs"); } } + private static String checkTcpConnectivity(final String host, final int port) { + try (Socket ignored = new Socket(host, port)) { + return null; + } catch (Exception ex) { + DatadogUtilities.severe(logger, ex, "Failed to create socket to host: " + host + ", port: " + port); + return ex.getMessage(); + } + } + @Override public Map toEnvironmentVariables() { if (StringUtils.isBlank(agentHost)) { @@ -194,7 +211,7 @@ public FormValidation doCheckLogConnectivity(@QueryParameter("agentHost") final if (agentLogCollectionPort == null) { return FormValidation.error("Please enter log collection port value"); } - String errorMessage = checkConnectivity(agentHost, agentLogCollectionPort); + String errorMessage = checkTcpConnectivity(agentHost, agentLogCollectionPort); if (errorMessage != null) { return FormValidation.error("Connectivity check failed: " + errorMessage); } @@ -205,17 +222,7 @@ public FormValidation doCheckLogConnectivity(@QueryParameter("agentHost") final @SuppressWarnings("lgtm[jenkins/no-permission-check]") // no side effects, no private information returned public FormValidation doCheckTraceConnectivity(@QueryParameter("agentHost") final String agentHost, @QueryParameter("agentTraceCollectionPort") Integer agentTraceCollectionPort) { - if (StringUtils.isBlank(agentHost)) { - return FormValidation.error("Please enter host value"); - } - if (agentTraceCollectionPort == null) { - return FormValidation.error("Please enter trace collection port value"); - } - String errorMessage = checkConnectivity(agentHost, agentTraceCollectionPort); - if (errorMessage != null) { - return FormValidation.error("Connectivity check failed: " + errorMessage); - } - return FormValidation.ok("Success!"); + return checkTracesConnectivity(agentHost, agentTraceCollectionPort); } public static String getDefaultAgentHost() { @@ -338,4 +345,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(agentHost, agentPort, agentLogCollectionPort, agentTraceCollectionPort); } -} \ No newline at end of file +}