diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java b/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java index 1b9997e8..ac6706e1 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration.java @@ -32,6 +32,8 @@ of this software and associated documentation files (the "Software"), to deal import com.cloudbees.plugins.credentials.common.StandardListBoxModel; import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; import hudson.Extension; +import hudson.init.InitMilestone; +import hudson.init.Initializer; import hudson.model.AbstractProject; import hudson.model.Item; import hudson.security.ACL; @@ -45,8 +47,10 @@ of this software and associated documentation files (the "Software"), to deal import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import javax.annotation.Nullable; import javax.management.InvalidAttributeValueException; import javax.servlet.ServletException; import jenkins.model.GlobalConfiguration; @@ -54,11 +58,9 @@ of this software and associated documentation files (the "Software"), to deal import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogAgentClient; import org.datadog.jenkins.plugins.datadog.clients.DatadogApiClient; -import org.datadog.jenkins.plugins.datadog.clients.HttpClient; -import org.datadog.jenkins.plugins.datadog.traces.write.TraceWriterFactory; import org.datadog.jenkins.plugins.datadog.util.SuppressFBWarnings; import org.datadog.jenkins.plugins.datadog.util.config.DatadogAgentConfiguration; import org.jenkinsci.plugins.plaincredentials.StringCredentials; @@ -183,6 +185,15 @@ public DatadogGlobalConfiguration() { loadEnvVariables(); // Load environment variables after as they should take precedence. } + @Initializer(after = InitMilestone.PLUGINS_STARTED) + public void onStartup() { + try { + ClientHolder.setClient(createClient()); + } catch (Exception e) { + DatadogUtilities.logException(logger, Level.INFO, "Could not init Datadog client", e); + } + } + public void loadEnvVariables() { String reportWithEnvVar = System.getenv(REPORT_WITH_PROPERTY); if(StringUtils.isNotBlank(reportWithEnvVar) && @@ -442,7 +453,7 @@ public FormValidation doTestConnection( throws IOException, ServletException { Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); final Secret secret = findSecret(targetApiKey, targetCredentialsApiKey); - if (DatadogApiClient.validateDefaultIntakeConnection(new HttpClient(60_000), targetApiURL, secret)) { + if (DatadogApiClient.validateDefaultIntakeConnection(targetApiURL, secret)) { return FormValidation.ok("Great! Your API key is valid."); } else { return FormValidation.error("Hmmm, your API key seems to be invalid."); @@ -461,7 +472,7 @@ public ListBoxModel doFillTargetCredentialsApiKeyItems( @QueryParameter("targetCredentialsApiKey") String targetCredentialsApiKey ) { StandardListBoxModel result = new StandardListBoxModel(); - // If the users does not have permissions to list credentials, only list the current value + // If the user does not have permissions to list credentials, only list the current value if (item == null) { if (!Jenkins.get().hasPermission(Jenkins.ADMINISTER)) { return result.includeCurrentValue(targetCredentialsApiKey); @@ -504,7 +515,7 @@ public FormValidation doTestFilteringConfig( /** - * Tests the targetCredentialsApiKey field from the configuration screen, to check its' validity. + * Tests the targetCredentialsApiKey field from the configuration screen, to check its validity. * * @param item - The context within which to list available credentials. * @param targetCredentialsApiKey - A String containing the API key as a credential @@ -720,7 +731,6 @@ public String getDisplayName() { @SuppressFBWarnings("REC_CATCH_EXCEPTION") public boolean configure(final StaplerRequest req, final JSONObject formData) throws FormException { try { - if(!super.configure(req, formData)){ return false; } @@ -828,16 +838,8 @@ public boolean configure(final StaplerRequest req, final JSONObject formData) th final Secret apiKeySecret = findSecret(formData.getString("targetApiKey"), formData.getString("targetCredentialsApiKey")); this.setUsedApiKey(apiKeySecret); - //When form is saved.... - DatadogClient client = ClientFactory.getClient(DatadogClient.ClientType.valueOf(this.getReportWith()), this.getTargetApiURL(), - this.getTargetLogIntakeURL(), this.getTargetWebhookIntakeURL(), this.getUsedApiKey(), this.getTargetHost(), - this.getTargetPort(), this.getTargetLogCollectionPort(), this.getTargetTraceCollectionPort(), this.getCiInstanceName()); - // ...reinitialize the DatadogClient - if(client == null) { - return false; - } - - TraceWriterFactory.onDatadogClientUpdate(client); + DatadogClient client = createClient(); + ClientHolder.setClient(client); // Persist global configuration information save(); @@ -851,12 +853,26 @@ public boolean configure(final StaplerRequest req, final JSONObject formData) th DatadogUtilities.severe(logger, e, "Failed to save configuration"); return false; } - } - public boolean reportWithEquals(String value){ - return this.reportWith.equals(value); + + @Nullable + public DatadogClient createClient() { + if (StringUtils.isBlank(reportWith)) { + return null; + } + + DatadogClient.ClientType type = DatadogClient.ClientType.valueOf(reportWith); + switch(type){ + case HTTP: + return new DatadogApiClient(targetApiURL, targetLogIntakeURL, targetWebhookIntakeURL, usedApiKey); + case DSD: + return new DatadogAgentClient(targetHost, targetPort, targetLogCollectionPort, targetTraceCollectionPort); + default: + throw new IllegalArgumentException("Unsupported client type: " + type); + } } + /** * Getter function for the reportWith global configuration. * diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/clients/ClientFactory.java b/src/main/java/org/datadog/jenkins/plugins/datadog/clients/ClientFactory.java deleted file mode 100644 index 90ec8d16..00000000 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/clients/ClientFactory.java +++ /dev/null @@ -1,84 +0,0 @@ -/* -The MIT License - -Copyright (c) 2015-Present Datadog, Inc -All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - */ - -package org.datadog.jenkins.plugins.datadog.clients; - -import hudson.util.Secret; -import org.datadog.jenkins.plugins.datadog.DatadogClient; -import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; -import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.traces.write.TraceWriterFactory; - -public class ClientFactory { - private static DatadogClient testClient; - - public static void setTestClient(DatadogClient testClient){ - // Only used for tests - ClientFactory.testClient = testClient; - TraceWriterFactory.onDatadogClientUpdate(testClient); - } - - public static DatadogClient getClient(DatadogClient.ClientType type, String apiUrl, String logIntakeUrl, - String webhookIntakeUrl, Secret apiKey, String host, Integer port, - Integer logCollectionPort, Integer traceCollectionPort, String traceServiceName) { - if(testClient != null){ - // Only used for tests - return testClient; - } - switch(type){ - case HTTP: - return DatadogApiClient.getInstance(apiUrl, logIntakeUrl, webhookIntakeUrl, apiKey); - case DSD: - return DatadogAgentClient.getInstance(host, port, logCollectionPort, traceCollectionPort); - default: - return null; - } - } - - public static DatadogClient getClient() { - if(testClient != null){ - // Only used for tests - return testClient; - } - - DatadogGlobalConfiguration descriptor = DatadogUtilities.getDatadogGlobalDescriptor(); - if (descriptor == null) { - return null; - } - - String reportWith = descriptor.getReportWith(); - String targetApiURL = descriptor.getTargetApiURL(); - String targetLogIntakeURL = descriptor.getTargetLogIntakeURL(); - String targetWebhookIntakeURL = descriptor.getTargetWebhookIntakeURL(); - Secret targetApiKey = descriptor.getUsedApiKey(); - String targetHost = descriptor.getTargetHost(); - Integer targetPort = descriptor.getTargetPort(); - Integer targetLogCollectionPort = descriptor.getTargetLogCollectionPort(); - Integer targetTraceCollectionPort = descriptor.getTargetTraceCollectionPort(); - String ciInstanceName = descriptor.getCiInstanceName(); - return ClientFactory.getClient(DatadogClient.ClientType.valueOf(reportWith), targetApiURL, targetLogIntakeURL, targetWebhookIntakeURL, - targetApiKey, targetHost, targetPort, targetLogCollectionPort, targetTraceCollectionPort, ciInstanceName); - } -} diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/clients/ClientHolder.java b/src/main/java/org/datadog/jenkins/plugins/datadog/clients/ClientHolder.java new file mode 100644 index 00000000..fce62416 --- /dev/null +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/clients/ClientHolder.java @@ -0,0 +1,49 @@ +/* +The MIT License + +Copyright (c) 2015-Present Datadog, Inc +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + */ + +package org.datadog.jenkins.plugins.datadog.clients; + +import java.util.Objects; +import javax.annotation.Nullable; +import org.datadog.jenkins.plugins.datadog.DatadogClient; +import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; +import org.datadog.jenkins.plugins.datadog.DatadogUtilities; +import org.datadog.jenkins.plugins.datadog.traces.write.TraceWriterFactory; + +public class ClientHolder { + private static volatile DatadogClient CLIENT; + + public static synchronized void setClient(DatadogClient client) { + if (!Objects.equals(CLIENT, client)) { + CLIENT = client; + TraceWriterFactory.onDatadogClientUpdate(client); + } + } + + @Nullable + public static DatadogClient getClient() { + return CLIENT; + } +} 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 7a717aa0..9c4b4bf0 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 @@ -39,12 +39,13 @@ of this software and associated documentation files (the "Software"), to deal import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.logging.Handler; import java.util.logging.Logger; import java.util.logging.SocketHandler; -import org.apache.commons.lang.StringUtils; +import javax.annotation.concurrent.GuardedBy; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogEvent; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; @@ -69,84 +70,40 @@ public class DatadogAgentClient implements DatadogClient { private static final int PAYLOAD_SIZE_LIMIT = 5 * 1024 * 1024; // 5 MB - private static volatile DatadogAgentClient instance = null; - // Used to determine if the instance failed last validation last time, so - // we do not keep retrying to create the instance and logging the same error - private static volatile boolean failedLastValidation = false; - private static final Logger logger = Logger.getLogger(DatadogAgentClient.class.getName()); - @SuppressFBWarnings(value="MS_SHOULD_BE_FINAL") - public static boolean enableValidations = true; - - private StatsDClient statsd; - private Logger ddLogger; - private String previousPayload; - private final String hostname; private final Integer port; private final Integer logCollectionPort; private final Integer traceCollectionPort; - private String resolvedIp = ""; - private boolean isStoppedStatsDClient = true; private final HttpClient client; + // logs + private volatile Logger ddLogger; + private final Object ddLoggerInitLock = new Object(); + private String previousPayload; + + // statsd + private volatile StatsDClient statsd; + private final Object statsdInitLock = new Object(); + @GuardedBy("statsdInitLock") + private String resolvedIp; /** - * Timeout of 1 minutes for connecting and reading via the synchronous Agent EVP Proxy. + * Timeout of 1 minute for connecting and reading via the synchronous Agent EVP Proxy. * this prevents this plugin from causing jobs to hang in case of * flaky network or Datadog being down. Left intentionally long. */ private static final int HTTP_TIMEOUT_EVP_PROXY_MS = 60 * 1000; - /** - * NOTE: Use ClientFactory.getClient method to instantiate the client in the Jenkins Plugin - * This method is not recommended to be used because it misses some validations. - * @param hostname - target hostname - * @param port - target port - * @param logCollectionPort - target log collection port - * @param traceCollectionPort - target trace collection port - * @return an singleton instance of the DogStatsDClient. - */ - @SuppressFBWarnings(value={"DC_DOUBLECHECK", "RC_REF_COMPARISON"}) - public static DatadogClient getInstance(String hostname, Integer port, Integer logCollectionPort, Integer traceCollectionPort){ - // If the configuration has not changed, return the current instance without validation - // since we've already validated and/or errored about the data - - DatadogAgentClient newInstance = new DatadogAgentClient(hostname, port, logCollectionPort, traceCollectionPort); - if (instance != null && instance.equals(newInstance)) { - if (DatadogAgentClient.failedLastValidation) { - return null; - } - return instance; - } - - synchronized (DatadogAgentClient.class) { - DatadogAgentClient.instance = newInstance; - if (enableValidations) { - try { - newInstance.validateConfiguration(); - DatadogAgentClient.failedLastValidation = false; - } catch(IllegalArgumentException e){ - logger.severe(e.getMessage()); - DatadogAgentClient.failedLastValidation = true; - return null; - } - } - } - if (instance != null){ - instance.reinitializeStatsDClient(true); - instance.reinitializeLogger(true); - } - return instance; - } - - protected DatadogAgentClient(String hostname, Integer port, Integer logCollectionPort, Integer traceCollectionPort) { + public DatadogAgentClient(String hostname, Integer port, Integer logCollectionPort, Integer traceCollectionPort) { this(hostname, port, logCollectionPort, traceCollectionPort, HTTP_TIMEOUT_EVP_PROXY_MS); } - protected DatadogAgentClient(String hostname, Integer port, Integer logCollectionPort, Integer traceCollectionPort, long evpProxyTimeoutMillis) { + public DatadogAgentClient(String hostname, Integer port, Integer logCollectionPort, Integer traceCollectionPort, long evpProxyTimeoutMillis) { + validate(hostname, port, logCollectionPort, traceCollectionPort); + this.hostname = hostname; this.port = port; this.logCollectionPort = logCollectionPort; @@ -154,16 +111,7 @@ protected DatadogAgentClient(String hostname, Integer port, Integer logCollectio this.client = new HttpClient(evpProxyTimeoutMillis); } - public static ConnectivityResult checkConnectivity(final String host, final int port) { - try(Socket ignored = new Socket(host, port)) { - return ConnectivityResult.SUCCESS; - } catch (Exception ex) { - DatadogUtilities.severe(logger, ex, "Failed to create socket to host: " + host + ", port: " +port + ". Error: " + ex); - return new ConnectivityResult(true, ex.toString()); - } - } - - public void validateConfiguration() throws IllegalArgumentException { + private static void validate(String hostname, Integer port, Integer logCollectionPort, Integer traceCollectionPort) { if (hostname == null || hostname.isEmpty()) { throw new IllegalArgumentException("Datadog Target URL is not set properly"); } @@ -179,142 +127,19 @@ public void validateConfiguration() throws IllegalArgumentException { } } - @Override - public boolean equals(Object object) { - if (object == this) { - return true; - } - if (!(object instanceof DatadogAgentClient)) { - return false; - } - - DatadogAgentClient newInstance = (DatadogAgentClient) object; - - if ((StringUtils.equals(getHostname(), newInstance.getHostname()) - && (((getPort() == null) && (newInstance.getPort() == null)) || (null != getPort() && port.equals(newInstance.getPort()))) - && (((getLogCollectionPort() == null) && (newInstance.getLogCollectionPort() == null)) || (null != getLogCollectionPort() && logCollectionPort.equals(newInstance.getLogCollectionPort()))) - && (((getTraceCollectionPort() == null) && (newInstance.getTraceCollectionPort() == null)) || (null != getTraceCollectionPort() && traceCollectionPort.equals(newInstance.getTraceCollectionPort()))) - )){ - return true; - } - - return false; - } - - @Override - public int hashCode() { - int result = hostname != null ? hostname.hashCode() : 0; - result = 47 * result + (port != null ? port.hashCode() : 0); - result = 47 * result + (logCollectionPort != null ? logCollectionPort.hashCode() : 0); - result = 47 * result + (traceCollectionPort != null ? traceCollectionPort.hashCode() : 0); - return result; - } - - /** - * reinitialize the dogStatsD Client - * @param force - force to reinitialize - * @return true if reinitialized properly otherwise false - */ - private boolean reinitializeStatsDClient(boolean force) { - try { - boolean refreshClient = DatadogUtilities.getDatadogGlobalDescriptor().isRefreshDogstatsdClient(); - if(!this.isStoppedStatsDClient && this.statsd != null && !force && (!refreshClient || !this.hasIpChanged())){ - return true; - } - this.stopStatsDClient(); - logger.info("Re/Initialize DogStatsD Client: hostname = " + this.hostname + ", port = " + this.port); - this.statsd = new NonBlockingStatsDClient(null, this.hostname, this.port); - this.isStoppedStatsDClient = false; - } catch (Exception e){ - DatadogUtilities.severe(logger, e, "Failed to reinitialize DogStatsD Client"); - this.stopStatsDClient(); - } - - return !isStoppedStatsDClient; - } - - private String resolveHostnameIp() throws UnknownHostException { - InetAddress inet = InetAddress.getByName(this.hostname); - String ipAddress = inet.getHostAddress(); - return ipAddress; - } - - private boolean hasIpChanged() throws UnknownHostException { - String ipAddress = this.resolveHostnameIp(); - if (this.resolvedIp.equals(ipAddress)) { - return false; - } else { - this.resolvedIp = ipAddress; - return true; - } - } - - /** - * reinitialize the Logger Client - * @param force - force to reinitialize - * @return true if reinitialized properly otherwise false - */ - private boolean reinitializeLogger(boolean force) { - if(this.ddLogger != null && !force){ - return true; - } - if(!DatadogUtilities.getDatadogGlobalDescriptor().isCollectBuildLogs() || this.logCollectionPort == null){ - return false; - } - try { - logger.info("Re/Initialize Datadog-Plugin Logger: hostname = " + this.hostname + ", logCollectionPort = " + this.logCollectionPort); - // need to close existing logger since it has a socket opened - not closing it leads to a file descriptor leak - close(this.ddLogger); - this.ddLogger = Logger.getLogger("Datadog-Plugin Logger"); - this.ddLogger.setUseParentHandlers(false); - //Remove all existing Handlers - Handler[] handlers = this.ddLogger.getHandlers(); - - if (handlers != null) { - for(Handler h : handlers){ - this.ddLogger.removeHandler(h); - } - } - //Add New Handler - SocketHandler socketHandler = new SocketHandler(this.hostname, this.logCollectionPort); - socketHandler.setFormatter(new DatadogFormatter()); - socketHandler.setErrorManager(new DatadogErrorManager()); - this.ddLogger.addHandler(socketHandler); - } catch (Exception e){ - if(e instanceof UnknownHostException){ - DatadogUtilities.severe(logger, e, "Failed to reinitialize Datadog-Plugin Logger, Unknown Host " + this.hostname); - }else if(e instanceof ConnectException){ - DatadogUtilities.severe(logger, e, "Failed to reinitialize Datadog-Plugin Logger, Connection exception. This may be because your port is incorrect " + this.logCollectionPort); - }else{ - DatadogUtilities.severe(logger, e, "Failed to reinitialize Datadog-Plugin Logger"); - } - return false; - } - return true; - } - - - private void close(Logger logger) { - if (logger == null) { - return; - } - Handler[] handlers = logger.getHandlers(); - if (handlers == null) { - return; - } - for (Handler handler : handlers) { - try { - handler.close(); - } catch (Exception e) { - // ignore - } + public static ConnectivityResult checkConnectivity(final String host, final int port) { + try(Socket ignored = new Socket(host, port)) { + return ConnectivityResult.SUCCESS; + } catch (Exception ex) { + DatadogUtilities.severe(logger, ex, "Failed to create socket to host: " + host + ", port: " +port + ". Error: " + ex); + return new ConnectivityResult(true, ex.toString()); } } /** * Fetches the supported endpoints from the Trace Agent /info API * - * @return a list of endpoints (if /info wasn't available, it will be empty) + * @return a set of endpoints (if /info wasn't available, it will be empty) */ @SuppressFBWarnings("REC_CATCH_EXCEPTION") public Set fetchAgentSupportedEndpoints() { @@ -342,37 +167,6 @@ public Set fetchAgentSupportedEndpoints() { } } - private boolean stopStatsDClient(){ - if (this.statsd != null){ - try{ - this.statsd.stop(); - }catch(Exception e){ - DatadogUtilities.severe(logger, e, "Failed to stop DogStatsD Client"); - return false; - } - this.statsd = null; - } - - this.isStoppedStatsDClient = true; - return true; - } - - public String getHostname() { - return hostname; - } - - public Integer getPort() { - return port; - } - - public Integer getLogCollectionPort() { - return logCollectionPort; - } - - public Integer getTraceCollectionPort() { - return traceCollectionPort; - } - @Override public boolean event(DatadogEvent event) { try { @@ -436,7 +230,7 @@ public void rate(String name, double value, String hostname, Map headers = new HashMap<>(); + headers.put("DD-API-KEY", Secret.toString(apiKey)); + + byte[] body = "{}".getBytes(StandardCharsets.UTF_8); + try { + JSON jsonResponse = new HttpClient(HTTP_TIMEOUT_MS).post(webhookIntakeUrl, headers, "application/json", body, JSONSerializer::toJSON); + // consider test successful if JSON was parsed without errors return true; - } - if (!(object instanceof DatadogApiClient)) { + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + DatadogUtilities.severe(logger, e, "Failed to validate webhook connection"); + return false; + } catch (Exception e) { + DatadogUtilities.severe(logger, e, "Failed to validate webhook connection"); return false; } - - DatadogApiClient newInstance = (DatadogApiClient) object; - - return StringUtils.equals(getLogIntakeUrl(), newInstance.getLogIntakeUrl()) - && StringUtils.equals(getWebhookIntakeUrl(), newInstance.getWebhookIntakeUrl()) - && StringUtils.equals(getUrl(), newInstance.getUrl()) - && ((newInstance.getApiKey() == null && getApiKey() == null)|| newInstance.getApiKey().equals(getApiKey())); } - @Override - public int hashCode() { - int result = apiKey != null ? apiKey.hashCode() : 0; - result = 43 * result + (url != null ? url.hashCode() : 0); - result = 43 * result + (logIntakeUrl != null ? logIntakeUrl.hashCode() : 0); - result = 43 * result + (webhookIntakeUrl != null ? webhookIntakeUrl.hashCode() : 0); - return result; - } - - public String getUrl() { - return url; + private static boolean validateLogIntakeConnection(String logsIntakeUrl, Secret apiKey) { + String payload = "{\"message\":\"[datadog-plugin] Check connection\", " + + "\"ddsource\":\"Jenkins\", \"service\":\"Jenkins\", " + + "\"hostname\":\"" + DatadogUtilities.getHostname(null) + "\"}"; + return postLogs(new HttpClient(HTTP_TIMEOUT_MS), logsIntakeUrl, apiKey, payload); } - public String getLogIntakeUrl() { - return logIntakeUrl; - } + private static boolean postLogs(HttpClient httpClient, String logIntakeUrl, Secret apiKey, String payload) { + if(payload == null){ + logger.fine("No payload to post"); + return true; + } - public String getWebhookIntakeUrl() { - return webhookIntakeUrl; - } + Map headers = new HashMap<>(); + headers.put("DD-API-KEY", Secret.toString(apiKey)); - public Secret getApiKey() { - return apiKey; + byte[] body = payload.getBytes(StandardCharsets.UTF_8); + try { + httpClient.postAsynchronously(logIntakeUrl, headers, "application/json", body); + return true; + } catch (Exception e) { + DatadogUtilities.severe(logger, e, "Failed to post logs"); + return false; + } } public boolean event(DatadogEvent event) { logger.fine("Sending event"); - if(this.defaultIntakeConnectionBroken){ - logger.severe("Your client is not initialized properly"); - return false; - } - try { JSONObject payload = new JSONObject(); payload.put("title", event.getTitle()); @@ -354,15 +301,10 @@ public boolean serviceCheck(String name, Status status, String hostname, Map headers = new HashMap<>(); headers.put("DD-API-KEY", Secret.toString(apiKey)); @@ -379,86 +321,11 @@ private void postApi(final JSONObject payload, final String type) throws IOExcep * @return a boolean to signify the success or failure of the HTTP POST request. */ public boolean sendLogs(String payload) { - if(this.logIntakeConnectionBroken){ - logger.severe("Your client is not initialized properly"); - return false; - } - - if(this.getLogIntakeUrl() == null || this.getLogIntakeUrl().isEmpty()){ + if(logIntakeUrl == null || logIntakeUrl.isEmpty()){ logger.severe("Datadog Log Intake URL is not set properly"); throw new RuntimeException("Datadog Log Collection Port not set properly"); } - - return postLogs(payload); - } - - @SuppressFBWarnings("REC_CATCH_EXCEPTION") - private boolean postLogs(String payload) { - if(payload == null){ - logger.fine("No payload to post"); - return true; - } - - String url = getLogIntakeUrl(); - - Map headers = new HashMap<>(); - headers.put("DD-API-KEY", Secret.toString(apiKey)); - - byte[] body = payload.getBytes(StandardCharsets.UTF_8); - - try { - httpClient.postAsynchronously(url, headers, "application/json", body); - return true; - } catch (Exception e) { - DatadogUtilities.severe(logger, e, "Failed to post logs"); - return false; - } - } - - public static boolean validateDefaultIntakeConnection(HttpClient client, String validatedUrl, Secret apiKey) { - String urlParameters = "?api_key=" + Secret.toString(apiKey); - String url = validatedUrl + VALIDATE + urlParameters; - - try { - JSONObject json = (JSONObject) client.get(url, Collections.emptyMap(), JSONSerializer::toJSON); - return json.getBoolean("valid"); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - DatadogUtilities.severe(logger, e, "Failed to validate webhook connection"); - return false; - } catch (Exception e) { - DatadogUtilities.severe(logger, e, "Failed to validate webhook connection"); - return false; - } - } - - private boolean validateLogIntakeConnection() throws IOException { - return postLogs("{\"message\":\"[datadog-plugin] Check connection\", " + - "\"ddsource\":\"Jenkins\", \"service\":\"Jenkins\", " + - "\"hostname\":\""+DatadogUtilities.getHostname(null)+"\"}"); - } - - @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE") - private boolean validateWebhookIntakeConnection() throws IOException { - String url = getWebhookIntakeUrl(); - - Map headers = new HashMap<>(); - headers.put("DD-API-KEY", Secret.toString(apiKey)); - - byte[] body = "{}".getBytes(StandardCharsets.UTF_8); - - try { - JSON jsonResponse = httpClient.post(url, headers, "application/json", body, JSONSerializer::toJSON); - // consider test successful if JSON was parsed without errors - return true; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - DatadogUtilities.severe(logger, e, "Failed to validate webhook connection"); - return false; - } catch (Exception e) { - DatadogUtilities.severe(logger, e, "Failed to validate webhook connection"); - return false; - } + return postLogs(httpClient, logIntakeUrl, apiKey, payload); } @Override @@ -467,13 +334,9 @@ public TraceWriteStrategy createTraceWriteStrategy() { } private void sendSpans(Collection spans) { - if (this.webhookIntakeConnectionBroken) { - throw new RuntimeException("Your client is not initialized properly; webhook intake connection is broken."); - } - DatadogGlobalConfiguration datadogGlobalDescriptor = DatadogUtilities.getDatadogGlobalDescriptor(); String urlParameters = datadogGlobalDescriptor != null ? "?service=" + datadogGlobalDescriptor.getCiInstanceName() : ""; - String url = getWebhookIntakeUrl() + urlParameters; + String url = webhookIntakeUrl + urlParameters; Map headers = new HashMap<>(); headers.put("DD-API-KEY", Secret.toString(apiKey)); @@ -496,4 +359,24 @@ private void sendSpans(Collection spans) { httpClient.postAsynchronously(url, headers, "application/json", body); } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + DatadogApiClient that = (DatadogApiClient) o; + return Objects.equals(url, that.url) + && Objects.equals(logIntakeUrl, that.logIntakeUrl) + && Objects.equals(webhookIntakeUrl, that.webhookIntakeUrl) + && Objects.equals(apiKey, that.apiKey); + } + + @Override + public int hashCode() { + return Objects.hash(url, logIntakeUrl, webhookIntakeUrl, apiKey); + } } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java index 2d7a4c10..3c92f119 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListener.java @@ -51,7 +51,7 @@ of this software and associated documentation files (the "Software"), to deal import org.datadog.jenkins.plugins.datadog.DatadogEvent; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.events.BuildAbortedEventImpl; import org.datadog.jenkins.plugins.datadog.events.BuildFinishedEventImpl; import org.datadog.jenkins.plugins.datadog.events.BuildStartedEventImpl; @@ -555,6 +555,6 @@ public Queue getQueue() { } public DatadogClient getDatadogClient() { - return ClientFactory.getClient(); + return ClientHolder.getClient(); } } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogComputerListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogComputerListener.java index 0d6fa142..29158a08 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogComputerListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogComputerListener.java @@ -30,19 +30,21 @@ of this software and associated documentation files (the "Software"), to deal import hudson.model.TaskListener; import hudson.slaves.ComputerListener; import hudson.slaves.OfflineCause; +import java.io.IOException; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogEvent; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; +import org.datadog.jenkins.plugins.datadog.events.ComputerLaunchFailedEventImpl; +import org.datadog.jenkins.plugins.datadog.events.ComputerOfflineEventImpl; +import org.datadog.jenkins.plugins.datadog.events.ComputerOnlineEventImpl; import org.datadog.jenkins.plugins.datadog.metrics.Metrics; -import org.datadog.jenkins.plugins.datadog.events.*; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; -import java.io.IOException; -import java.util.Map; -import java.util.Set; -import java.util.logging.Logger; /** * This class registers an {@link ComputerListener} to trigger events and calculate metrics: @@ -69,7 +71,7 @@ public void onOnline(Computer computer, TaskListener listener) throws IOExceptio logger.fine("Start DatadogComputerListener#onOnline"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -103,7 +105,7 @@ public void onOffline(@Nonnull Computer computer, @CheckForNull OfflineCause cau logger.fine("Start DatadogComputerListener#onOffline"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -135,7 +137,7 @@ public void onTemporarilyOnline(Computer computer) { logger.fine("Start DatadogComputerListener#onTemporarilyOnline"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -166,7 +168,7 @@ public void onTemporarilyOffline(Computer computer, OfflineCause cause) { logger.fine("Start DatadogComputerListener#onTemporarilyOffline"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -198,7 +200,7 @@ public void onLaunchFailure(Computer computer, TaskListener taskListener) throws logger.fine("Start DatadogComputerListener#onLaunchFailure"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListener.java index a08071e5..c9487abf 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListener.java @@ -40,7 +40,7 @@ of this software and associated documentation files (the "Software"), to deal import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; import org.datadog.jenkins.plugins.datadog.audit.DatadogAudit; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.metrics.Metrics; import org.datadog.jenkins.plugins.datadog.metrics.MetricsClient; import org.datadog.jenkins.plugins.datadog.model.BuildData; @@ -112,7 +112,7 @@ public void onNewHead(FlowNode flowNode) { directParentName = "root"; } - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if (client == null) { return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogItemListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogItemListener.java index 6b6baa76..d09de28a 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogItemListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogItemListener.java @@ -28,20 +28,19 @@ of this software and associated documentation files (the "Software"), to deal import hudson.Extension; import hudson.model.Item; import hudson.model.listeners.ItemListener; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogEvent; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; -import org.datadog.jenkins.plugins.datadog.metrics.Metrics; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.events.ItemCRUDEventImpl; import org.datadog.jenkins.plugins.datadog.events.ItemCopiedEventImpl; import org.datadog.jenkins.plugins.datadog.events.ItemLocationChangedEventImpl; +import org.datadog.jenkins.plugins.datadog.metrics.Metrics; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; -import java.util.Map; -import java.util.Set; -import java.util.logging.Logger; - /** * This class registers an {@link ItemListener} to trigger events and calculate metrics: * - When an item gets created, the {@link #onCreated(Item)} method will be invoked. @@ -82,7 +81,7 @@ private void onCRUD(Item item, String action) { logger.fine("Start DatadogItemListener#on" + action); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -115,7 +114,7 @@ public void onCopied(Item src, Item item) { logger.fine("Start DatadogItemListener#onCopied"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -148,7 +147,7 @@ public void onLocationChanged(Item item, String oldFullName, String newFullName) logger.fine("Start DatadogItemListener#onLocationChanged"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSCMListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSCMListener.java index 342d6358..b8285bd6 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSCMListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSCMListener.java @@ -48,9 +48,9 @@ of this software and associated documentation files (the "Software"), to deal import org.datadog.jenkins.plugins.datadog.DatadogJobProperty; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; import org.datadog.jenkins.plugins.datadog.audit.DatadogAudit; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; -import org.datadog.jenkins.plugins.datadog.metrics.Metrics; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.events.SCMCheckoutCompletedEventImpl; +import org.datadog.jenkins.plugins.datadog.metrics.Metrics; import org.datadog.jenkins.plugins.datadog.model.BuildData; import org.datadog.jenkins.plugins.datadog.model.GitCommitAction; import org.datadog.jenkins.plugins.datadog.model.GitRepositoryAction; @@ -132,7 +132,7 @@ public void onCheckout(Run build, SCM scm, FilePath workspace, TaskListene } // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if (client == null) { return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSaveableListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSaveableListener.java index 11c49e2c..e201209b 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSaveableListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSaveableListener.java @@ -29,16 +29,15 @@ of this software and associated documentation files (the "Software"), to deal import hudson.XmlFile; import hudson.model.Saveable; import hudson.model.listeners.SaveableListener; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.metrics.Metrics; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; -import java.util.Map; -import java.util.Set; -import java.util.logging.Logger; - /** * This class registers an {@link SaveableListener} to trigger events and calculate metrics: * - When an saveable gets changed, the {@link #onChange(Saveable, XmlFile)} method will be invoked. @@ -60,7 +59,7 @@ public void onChange(Saveable config, XmlFile file) { logger.fine("Start DatadogSaveableListener#onChange"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSecurityListener.java b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSecurityListener.java index a9321d92..9075541a 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSecurityListener.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogSecurityListener.java @@ -26,21 +26,20 @@ of this software and associated documentation files (the "Software"), to deal package org.datadog.jenkins.plugins.datadog.listeners; import hudson.Extension; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; +import javax.annotation.Nonnull; import jenkins.security.SecurityListener; import org.acegisecurity.userdetails.UserDetails; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogEvent; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; -import org.datadog.jenkins.plugins.datadog.metrics.Metrics; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.events.UserAuthenticationEventImpl; +import org.datadog.jenkins.plugins.datadog.metrics.Metrics; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; -import javax.annotation.Nonnull; -import java.util.Map; -import java.util.Set; -import java.util.logging.Logger; - /** * This class registers an {@link SecurityListener} to trigger events and calculate metrics: * - When an user authenticates, the {@link #authenticated(UserDetails)} method will be invoked. @@ -65,7 +64,7 @@ protected void authenticated(@Nonnull UserDetails details) { logger.fine("Start DatadogSecurityListener#authenticated"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -97,7 +96,7 @@ protected void failedToAuthenticate(@Nonnull String username) { logger.fine("Start DatadogSecurityListener#failedToAuthenticate"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } @@ -140,7 +139,7 @@ protected void loggedOut(@Nonnull String username) { logger.fine("Start DatadogSecurityListener#loggedOut"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/logs/DatadogWriter.java b/src/main/java/org/datadog/jenkins/plugins/datadog/logs/DatadogWriter.java index 06dfb582..6bbe2c8d 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/logs/DatadogWriter.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/logs/DatadogWriter.java @@ -29,7 +29,7 @@ of this software and associated documentation files (the "Software"), to deal import org.apache.commons.lang.StringUtils; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.model.BuildData; import org.datadog.jenkins.plugins.datadog.model.PipelineStepData; import org.datadog.jenkins.plugins.datadog.traces.CITags; @@ -77,7 +77,7 @@ public void write(String line) { payload.put(PipelineStepData.StepType.PIPELINE.getTagName() + CITags._NAME, this.buildData.getJobName()); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if(client == null){ return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisher.java b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisher.java index 1ae82f90..4f930863 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisher.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisher.java @@ -40,7 +40,7 @@ of this software and associated documentation files (the "Software"), to deal import jenkins.model.Jenkins; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.metrics.MetricsClient; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; @@ -64,7 +64,7 @@ public long getRecurrencePeriod() { protected void doRun() throws Exception { logger.fine("doRun called: Computing Node metrics"); - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if (client == null) { return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogCountersPublisher.java b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogCountersPublisher.java index 96e8f499..d4401a03 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogCountersPublisher.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogCountersPublisher.java @@ -35,7 +35,7 @@ of this software and associated documentation files (the "Software"), to deal import java.util.logging.Logger; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.metrics.MetricKey; import org.datadog.jenkins.plugins.datadog.metrics.Metrics; import org.datadog.jenkins.plugins.datadog.metrics.MetricsClient; @@ -57,7 +57,7 @@ public long getRecurrencePeriod() { @Override protected void execute(TaskListener taskListener) throws IOException, InterruptedException { logger.fine("Execute called: Publishing counters"); - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if (client == null) { return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisher.java b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisher.java index cae7cfa5..4b30408d 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisher.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisher.java @@ -30,20 +30,19 @@ of this software and associated documentation files (the "Software"), to deal import hudson.PluginWrapper; import hudson.model.PeriodicWork; import hudson.model.Project; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; import jenkins.model.Jenkins; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.metrics.MetricsClient; import org.datadog.jenkins.plugins.datadog.model.PluginData; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.logging.Logger; - /** * This class registers a {@link PeriodicWork} with Jenkins to run periodically in order to enable * us to compute metrics related to Jenkins level metrics. @@ -66,7 +65,7 @@ protected void doRun() throws Exception { logger.fine("doRun called: Computing Jenkins metrics"); // Get Datadog Client Instance - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); String hostname = DatadogUtilities.getHostname(null); if(client == null){ return; diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisher.java b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisher.java index 3636ddee..a492250e 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisher.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisher.java @@ -37,7 +37,7 @@ of this software and associated documentation files (the "Software"), to deal import java.util.logging.Logger; import org.datadog.jenkins.plugins.datadog.DatadogClient; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.metrics.MetricsClient; import org.datadog.jenkins.plugins.datadog.util.TagsUtil; import org.jenkinsci.plugins.workflow.job.WorkflowJob; @@ -64,7 +64,7 @@ public long getRecurrencePeriod() { protected void doRun() throws Exception { logger.fine("doRun called: Computing queue metrics"); - DatadogClient client = ClientFactory.getClient(); + DatadogClient client = ClientHolder.getClient(); if (client == null) { return; } diff --git a/src/main/java/org/datadog/jenkins/plugins/datadog/traces/write/TraceWriterFactory.java b/src/main/java/org/datadog/jenkins/plugins/datadog/traces/write/TraceWriterFactory.java index 71714cee..596aebd4 100644 --- a/src/main/java/org/datadog/jenkins/plugins/datadog/traces/write/TraceWriterFactory.java +++ b/src/main/java/org/datadog/jenkins/plugins/datadog/traces/write/TraceWriterFactory.java @@ -3,7 +3,7 @@ import hudson.init.Terminator; import javax.annotation.Nullable; import org.datadog.jenkins.plugins.datadog.DatadogClient; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; public class TraceWriterFactory { @@ -37,7 +37,7 @@ public static synchronized void stop() throws InterruptedException { @Nullable public static TraceWriter getTraceWriter() { if (TRACE_WRITER == null) { - onDatadogClientUpdate(ClientFactory.getClient()); + onDatadogClientUpdate(ClientHolder.getClient()); } return TRACE_WRITER; } diff --git a/src/main/resources/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration/config.jelly b/src/main/resources/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration/config.jelly index ff4a5f1e..3e2b0b25 100644 --- a/src/main/resources/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration/config.jelly +++ b/src/main/resources/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration/config.jelly @@ -15,7 +15,7 @@ + checked="${'DSD' == instance.reportWith}" inline="true"> @@ -39,7 +39,7 @@ + checked="${'HTTP' == instance.reportWith}" inline="true" > diff --git a/src/main/resources/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration/help-targetSite.html b/src/main/resources/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration/help-targetSite.html new file mode 100644 index 00000000..1e2a8e72 --- /dev/null +++ b/src/main/resources/org/datadog/jenkins/plugins/datadog/DatadogGlobalConfiguration/help-targetSite.html @@ -0,0 +1,6 @@ +
+ Datadog offers different sites throughout the world. + Each site is completely independent, and you cannot share data across sites. + Each site gives you benefits (for example, government security regulations) or allows you to store your data in specific locations around the world. + See Datadog documentation for more information about sites. +
diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/clients/DatadogClientTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/clients/DatadogClientTest.java index a557659e..2bd1c186 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/clients/DatadogClientTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/clients/DatadogClientTest.java @@ -25,7 +25,11 @@ of this software and associated documentation files (the "Software"), to deal package org.datadog.jenkins.plugins.datadog.clients; -import org.datadog.jenkins.plugins.datadog.DatadogClient; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; import org.datadog.jenkins.plugins.datadog.metrics.MetricKey; @@ -36,14 +40,6 @@ of this software and associated documentation files (the "Software"), to deal import org.jvnet.hudson.test.JenkinsRule; import org.mockito.Mockito; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.*; - public class DatadogClientTest { @ClassRule @@ -52,68 +48,50 @@ public class DatadogClientTest { @Test public void testHttpClientGetInstanceApiKey() { //validateConfiguration throws an error when given an invalid API key when the urls are valid - Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> { - DatadogApiClient.enableValidations = false; - DatadogApiClient client = (DatadogApiClient) DatadogApiClient.getInstance("http", "test", "test", null); - client.validateConfiguration(); - }); + Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> new DatadogApiClient("http", "test", "test", null)); String expectedMessage = "Datadog API Key is not set properly"; String actualMessage = exception.getMessage(); - Assert.assertTrue(actualMessage.equals(expectedMessage)); + Assert.assertEquals(actualMessage, expectedMessage); } @Test public void testHttpClientGetInstanceApiUrl() { // validateConfiguration throws an error when given an invalid url - Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> { - DatadogApiClient.enableValidations = false; - DatadogApiClient client = (DatadogApiClient) DatadogApiClient.getInstance("", null, null, null); - client.validateConfiguration(); - }); + Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> new DatadogApiClient("", null, null, null)); String expectedMessage = "Datadog Target URL is not set properly"; String actualMessage = exception.getMessage(); - Assert.assertTrue(actualMessage.equals(expectedMessage)); + Assert.assertEquals(actualMessage, expectedMessage); } @Test public void testHttpClientGetInstanceEnableValidations() { - // calling getInstance with invalid data returns null - DatadogApiClient.enableValidations = true; - DatadogClient client = DatadogApiClient.getInstance("https", null, null, null); - Assert.assertEquals(client, null); + Assert.assertThrows(IllegalArgumentException.class, () -> new DatadogApiClient("https", null, null, null)); } - @Test public void testDogstatsDClientGetInstanceTargetPort() { // validateConfiguration throws an error when given an invalid port - Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> { - DatadogAgentClient.enableValidations = false; - DatadogAgentClient client = (DatadogAgentClient) DatadogAgentClient.getInstance("test", null, null, null); - client.validateConfiguration(); - }); + Exception exception = Assert.assertThrows(IllegalArgumentException.class, () -> new DatadogAgentClient("test", null, null, null)); String expectedMessage = "Datadog Target Port is not set properly"; String actualMessage = exception.getMessage(); - Assert.assertTrue(actualMessage.equals(expectedMessage)); + Assert.assertEquals(actualMessage, expectedMessage); } @Test public void testDogstatsDClientGetInstanceEnableValidations() { // calling getInstance with invalid data returns null - DatadogAgentClient.enableValidations = true; - DatadogClient client = DatadogAgentClient.getInstance("https", null, null, null); - Assert.assertEquals(client, null); + Assert.assertThrows(IllegalArgumentException.class, () -> new DatadogAgentClient("https", null, null, null)); } @Test public void testEvpProxyEnabled() { DatadogGlobalConfiguration cfg = DatadogUtilities.getDatadogGlobalDescriptor(); cfg.setEnableCiVisibility(true); - DatadogAgentClient client = Mockito.spy(new DatadogAgentClient("test",1234, 1235, 1236, 1_000)); - Mockito.doReturn(new HashSet<>(Arrays.asList("/evp_proxy/v3/"))).when(client).fetchAgentSupportedEndpoints(); + DatadogAgentClient client = Mockito.spy(new DatadogAgentClient("test", 1234, 1235, 1236, 1_000)); + Mockito.doReturn(new HashSet<>(Collections.singletonList("/evp_proxy/v3/"))).when(client).fetchAgentSupportedEndpoints(); Assert.assertTrue(client.isEvpProxySupported()); } @@ -121,7 +99,7 @@ public void testEvpProxyEnabled() { public void testEvpProxyDisabled() { DatadogGlobalConfiguration cfg = DatadogUtilities.getDatadogGlobalDescriptor(); cfg.setEnableCiVisibility(true); - DatadogAgentClient client = Mockito.spy(new DatadogAgentClient("test",1234, 1235, 1236, 1_000)); + DatadogAgentClient client = Mockito.spy(new DatadogAgentClient("test", 1234, 1235, 1236, 1_000)); Mockito.doReturn(new HashSet()).when(client).fetchAgentSupportedEndpoints(); Assert.assertFalse(client.isEvpProxySupported()); } @@ -135,19 +113,17 @@ public void testEmptyAgentSupportedEndpointsWithNoAgent() { } @Test - public void testIncrementCountAndFlush() throws IOException, InterruptedException { - DatadogApiClient.enableValidations = false; - DatadogClient client = DatadogApiClient.getInstance("test", null, null, null); + public void testIncrementCountAndFlush() { Map> tags1 = new HashMap<>(); - tags1 = DatadogClientStub.addTagToMap(tags1, "tag1", "value"); - tags1 = DatadogClientStub.addTagToMap(tags1, "tag2", "value"); + DatadogClientStub.addTagToMap(tags1, "tag1", "value"); + DatadogClientStub.addTagToMap(tags1, "tag2", "value"); Metrics.getInstance().incrementCounter("metric1", "host1", tags1); Metrics.getInstance().incrementCounter("metric1", "host1", tags1); Map> tags2 = new HashMap<>(); - tags2 = DatadogClientStub.addTagToMap(tags2, "tag1", "value"); - tags2 = DatadogClientStub.addTagToMap(tags2, "tag2", "value"); - tags2 = DatadogClientStub.addTagToMap(tags2, "tag3", "value"); + DatadogClientStub.addTagToMap(tags2, "tag1", "value"); + DatadogClientStub.addTagToMap(tags2, "tag2", "value"); + DatadogClientStub.addTagToMap(tags2, "tag3", "value"); Metrics.getInstance().incrementCounter("metric1", "host1", tags2); Metrics.getInstance().incrementCounter("metric1", "host2", tags2); @@ -160,151 +136,32 @@ public void testIncrementCountAndFlush() throws IOException, InterruptedExceptio // Check counter is reset as expected Map countersEmpty = Metrics.getInstance().getAndResetCounters(); - Assert.assertTrue("size = " + countersEmpty.size(), countersEmpty.size() == 0); + Assert.assertEquals("size = " + countersEmpty.size(), 0, countersEmpty.size()); // Check that metrics to submit are correct boolean check1 = false, check2 = false, check3 = false, check4 = false; - Assert.assertTrue("counters = " + counters.size(), counters.size() == 4); + Assert.assertEquals("counters = " + counters.size(), 4, counters.size()); for (MetricKey counterMetric: counters.keySet()) { int count = counters.get(counterMetric); - if(counterMetric.getMetricName().equals("metric1") && counterMetric.getHostname().equals("host1") - && counterMetric.getTags().size() == 2){ - Assert.assertTrue("count = " + count, count == 2); + if (counterMetric.getMetricName().equals("metric1") && counterMetric.getHostname().equals("host1") + && counterMetric.getTags().size() == 2) { + Assert.assertEquals("count = " + count, 2, count); check1 = true; } else if (counterMetric.getMetricName().equals("metric1") && counterMetric.getHostname().equals("host1") - && counterMetric.getTags().size() == 3){ - Assert.assertTrue("count = " + count,count == 1); + && counterMetric.getTags().size() == 3) { + Assert.assertEquals("count = " + count, 1, count); check2 = true; } else if (counterMetric.getMetricName().equals("metric1") && counterMetric.getHostname().equals("host2") - && counterMetric.getTags().size() == 3){ - Assert.assertTrue("count = " + count,count == 2); + && counterMetric.getTags().size() == 3) { + Assert.assertEquals("count = " + count, 2, count); check3 = true; } else if (counterMetric.getMetricName().equals("metric2") && counterMetric.getHostname().equals("host2") - && counterMetric.getTags().size() == 3){ - Assert.assertTrue("count = " + count,count == 1); + && counterMetric.getTags().size() == 3) { + Assert.assertEquals("count = " + count, 1, count); check4 = true; } } Assert.assertTrue(check1 + " " + check2 + " " + check3 + " " + check4, check1 && check2 && check3 && check4); } - - - @Test - public void testIncrementCountAndFlushThreadedEnv() throws IOException, InterruptedException { - ExecutorService executor = Executors.newFixedThreadPool(2); - - Runnable increment = new Runnable() { - @Override - public void run() { - // We use a new instance of a client on every run. - DatadogApiClient.enableValidations = false; - DatadogClient client = DatadogApiClient.getInstance("test2", null, null, null); - Map> tags = new HashMap<>(); - tags = DatadogClientStub.addTagToMap(tags, "tag1", "value"); - tags = DatadogClientStub.addTagToMap(tags, "tag2", "value"); - Metrics.getInstance().incrementCounter("metric1", "host1", tags); - } - }; - - for(int i = 0; i < 10000; i++){ - executor.submit(increment); - } - - stop(executor); - - // Check counter is reset as expected - Map counters = Metrics.getInstance().getAndResetCounters(); - Assert.assertTrue("size = " + counters.size(), counters.size() == 1); - Assert.assertTrue("counters.values() = " + counters.values(), counters.values().contains(10000)); - - } - - @Test - public void testIncrementCountAndFlushThreadedEnvThreadCheck() throws IOException, InterruptedException, ExecutionException { - ExecutorService executor = Executors.newFixedThreadPool(2); - Runnable increment = new Runnable() { - @Override - public void run() { - // We use a new instance of a client on every run. - DatadogApiClient.enableValidations = false; - DatadogClient client = DatadogApiClient.getInstance("test3", null, null, null); - Map> tags = new HashMap<>(); - tags = DatadogClientStub.addTagToMap(tags, "tag1", "value"); - tags = DatadogClientStub.addTagToMap(tags, "tag2", "value"); - Metrics.getInstance().incrementCounter("metric1", "host1", tags); - } - }; - - for(int i = 0; i < 10000; i++){ - executor.submit(increment); - } - - stop(executor); - - // We also check the result in a distinct thread - ExecutorService single = Executors.newSingleThreadExecutor(); - Callable check = new Callable() { - @Override - public Boolean call() throws Exception { - // Check counter is reset as expected - Map counters = Metrics.getInstance().getAndResetCounters(); - Assert.assertTrue("size = " + counters.size(), counters.size() == 1); - Assert.assertTrue("counters.values() = " + counters.values(), counters.values().contains(10000)); - return true; - } - }; - - Future value = single.submit(check); - - stop(single); - - Assert.assertTrue(value.get()); - - } - - @Test - public void testIncrementCountAndFlushThreadedEnvOneClient() throws IOException, InterruptedException { - ExecutorService executor = Executors.newFixedThreadPool(2); - DatadogApiClient.enableValidations = false; - final DatadogClient client = DatadogApiClient.getInstance("testing", null, null, null); - Runnable increment = new Runnable() { - @Override - public void run() { - Map> tags = new HashMap<>(); - tags = DatadogClientStub.addTagToMap(tags, "tag1", "value"); - tags = DatadogClientStub.addTagToMap(tags, "tag2", "value"); - Metrics.getInstance().incrementCounter("metric1", "host1", tags); - } - }; - - for(int i = 0; i < 10000; i++){ - executor.submit(increment); - } - - stop(executor); - - // Check counter is reset as expected - Map counters = Metrics.getInstance().getAndResetCounters(); - Assert.assertTrue("size = " + counters.size(), counters.size() == 1); - Assert.assertTrue("counters.values() = " + counters.values(), counters.values().contains(10000)); - - } - - private static void stop(ExecutorService executor) { - try { - executor.shutdown(); - executor.awaitTermination(5, TimeUnit.SECONDS); - } - catch (InterruptedException e) { - System.err.println("termination interrupted"); - } - finally { - if (!executor.isTerminated()) { - System.err.println("killing non-finished tasks"); - } - executor.shutdownNow(); - } - } - } diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/clients/MetricsTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/clients/MetricsTest.java new file mode 100644 index 00000000..f85eb80a --- /dev/null +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/clients/MetricsTest.java @@ -0,0 +1,111 @@ +package org.datadog.jenkins.plugins.datadog.clients; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.datadog.jenkins.plugins.datadog.metrics.MetricKey; +import org.datadog.jenkins.plugins.datadog.metrics.Metrics; +import org.junit.Assert; +import org.junit.Test; + +public class MetricsTest { + + @Test + public void testIncrementCountAndFlushThreadedEnv() { + ExecutorService executor = Executors.newFixedThreadPool(2); + + Runnable increment = () -> { + Map> tags = new HashMap<>(); + DatadogClientStub.addTagToMap(tags, "tag1", "value"); + DatadogClientStub.addTagToMap(tags, "tag2", "value"); + Metrics.getInstance().incrementCounter("metric1", "host1", tags); + }; + + for (int i = 0; i < 10000; i++) { + executor.submit(increment); + } + + stop(executor); + + // Check counter is reset as expected + Map counters = Metrics.getInstance().getAndResetCounters(); + Assert.assertEquals("size = " + counters.size(), 1, counters.size()); + Assert.assertTrue("counters.values() = " + counters.values(), counters.containsValue(10000)); + + } + + @Test + public void testIncrementCountAndFlushThreadedEnvThreadCheck() throws InterruptedException, ExecutionException { + ExecutorService executor = Executors.newFixedThreadPool(2); + Runnable increment = () -> { + Map> tags = new HashMap<>(); + DatadogClientStub.addTagToMap(tags, "tag1", "value"); + DatadogClientStub.addTagToMap(tags, "tag2", "value"); + Metrics.getInstance().incrementCounter("metric1", "host1", tags); + }; + + for (int i = 0; i < 10000; i++) { + executor.submit(increment); + } + + stop(executor); + + // We also check the result in a distinct thread + ExecutorService single = Executors.newSingleThreadExecutor(); + Callable check = () -> { + // Check counter is reset as expected + Map counters = Metrics.getInstance().getAndResetCounters(); + Assert.assertEquals("size = " + counters.size(), 1, counters.size()); + Assert.assertTrue("counters.values() = " + counters.values(), counters.containsValue(10000)); + return true; + }; + + Future value = single.submit(check); + + stop(single); + + Assert.assertTrue(value.get()); + } + + @Test + public void testIncrementCountAndFlushThreadedEnvOneClient() { + ExecutorService executor = Executors.newFixedThreadPool(2); + Runnable increment = () -> { + Map> tags = new HashMap<>(); + DatadogClientStub.addTagToMap(tags, "tag1", "value"); + DatadogClientStub.addTagToMap(tags, "tag2", "value"); + Metrics.getInstance().incrementCounter("metric1", "host1", tags); + }; + + for (int i = 0; i < 10000; i++) { + executor.submit(increment); + } + + stop(executor); + + // Check counter is reset as expected + Map counters = Metrics.getInstance().getAndResetCounters(); + Assert.assertEquals("size = " + counters.size(), 1, counters.size()); + Assert.assertTrue("counters.values() = " + counters.values(), counters.containsValue(10000)); + } + + private static void stop(ExecutorService executor) { + try { + executor.shutdown(); + executor.awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException e) { + System.err.println("termination interrupted"); + } finally { + if (!executor.isTerminated()) { + System.err.println("killing non-finished tasks"); + } + executor.shutdownNow(); + } + } +} diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListenerIT.java b/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListenerIT.java index f160f6a0..80703b66 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListenerIT.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogBuildListenerIT.java @@ -44,7 +44,7 @@ import net.sf.json.JSONObject; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.datadog.jenkins.plugins.datadog.model.PipelineStepData; import org.datadog.jenkins.plugins.datadog.traces.CITags; @@ -99,7 +99,7 @@ public void beforeEach() throws IOException { EnvVars.masterEnvVars.remove("ENV_VAR"); clientStub = new DatadogClientStub(); - ClientFactory.setTestClient(clientStub); + ClientHolder.setClient(clientStub); Jenkins jenkins = jenkinsRule.jenkins; jenkins.getGlobalNodeProperties().remove(EnvironmentVariablesNodeProperty.class); diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogFilteringEventsTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogFilteringEventsTest.java index 21fbc44d..bf3a7cbe 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogFilteringEventsTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogFilteringEventsTest.java @@ -6,15 +6,13 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; -import javax.management.InvalidAttributeValueException; - import org.junit.contrib.java.lang.system.EnvironmentVariables; import org.acegisecurity.userdetails.UserDetails; import org.datadog.jenkins.plugins.datadog.DatadogEvent; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogJobProperty; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.datadog.jenkins.plugins.datadog.events.*; import org.datadog.jenkins.plugins.datadog.stubs.BuildStub; @@ -52,7 +50,7 @@ public class DatadogFilteringEventsTest { @Before public void setUp() throws Exception { this.client = new DatadogClientStub(); - ClientFactory.setTestClient(this.client); + ClientHolder.setClient(this.client); this.datadogBuildListener = new DatadogBuildListener(); this.datadogComputerListener = new DatadogComputerListener(); diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListenerTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListenerTest.java index 69515be4..35c43647 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListenerTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/listeners/DatadogGraphListenerTest.java @@ -53,7 +53,7 @@ import org.apache.commons.io.IOUtils; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.datadog.jenkins.plugins.datadog.model.PipelineStepData; import org.datadog.jenkins.plugins.datadog.publishers.DatadogComputerPublisher; @@ -128,7 +128,7 @@ public void beforeEach() throws IOException { listener = new DatadogGraphListener(); clientStub = new DatadogClientStub(); - ClientFactory.setTestClient(clientStub); + ClientHolder.setClient(clientStub); Jenkins jenkins = jenkinsRule.jenkins; jenkins.getGlobalNodeProperties().remove(EnvironmentVariablesNodeProperty.class); diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/logs/LogCollectionTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/logs/LogCollectionTest.java index 6271bf17..44f3e467 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/logs/LogCollectionTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/logs/LogCollectionTest.java @@ -12,7 +12,7 @@ import net.sf.json.JSONObject; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; @@ -31,7 +31,7 @@ public class LogCollectionTest { @BeforeClass public static void staticSetup() throws Exception { - ClientFactory.setTestClient(stubClient); + ClientHolder.setClient(stubClient); DatadogGlobalConfiguration cfg = DatadogUtilities.getDatadogGlobalDescriptor(); ExtensionList.clearLegacyInstances(); cfg.setCollectBuildLogs(true); diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisherTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisherTest.java index 4cb8ed4b..60dbe494 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisherTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogComputerPublisherTest.java @@ -3,7 +3,7 @@ import java.util.Arrays; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.junit.BeforeClass; import org.junit.ClassRule; @@ -22,7 +22,7 @@ public class DatadogComputerPublisherTest { @BeforeClass public static void setup() throws Exception { - ClientFactory.setTestClient(client); + ClientHolder.setClient(client); } @Test diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisherTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisherTest.java index 6d3e3921..e3da69b9 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisherTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogJenkinsPublisherTest.java @@ -11,7 +11,7 @@ import java.util.LinkedList; import jenkins.model.Jenkins; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.junit.Before; import org.junit.Test; @@ -30,7 +30,7 @@ public class DatadogJenkinsPublisherTest { public void setup() { client = new DatadogClientStub(); queuePublisher = new DatadogJenkinsPublisher(); - ClientFactory.setTestClient(client); + ClientHolder.setClient(client); hostname = DatadogUtilities.getHostname(null); plugins = new LinkedList<>(); failedPlugins = new LinkedList<>(); diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePipelinePublisherTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePipelinePublisherTest.java index ae66441f..2b053eee 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePipelinePublisherTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePipelinePublisherTest.java @@ -10,7 +10,7 @@ import org.apache.commons.io.IOUtils; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; @@ -24,7 +24,7 @@ public class DatadogQueuePipelinePublisherTest { @Test public void testPipelineInQueue() throws Exception { DatadogClientStub client = new DatadogClientStub();; - ClientFactory.setTestClient(client); + ClientHolder.setClient(client); DatadogQueuePublisher queuePublisher = new DatadogQueuePublisher(); String hostname = DatadogUtilities.getHostname(null); WorkflowJob job = jenkins.jenkins.createProject(WorkflowJob.class, "pipelineIntegrationQueue"); diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisherTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisherTest.java index 8fd67b09..16eca555 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisherTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/publishers/DatadogQueuePublisherTest.java @@ -16,7 +16,7 @@ import java.util.stream.Collectors; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.datadog.jenkins.plugins.datadog.clients.DatadogMetric; import org.jenkinsci.plugins.workflow.job.WorkflowJob; @@ -36,7 +36,7 @@ public class DatadogQueuePublisherTest { public void setup() throws Exception { client = new DatadogClientStub(); queuePublisher = new DatadogQueuePublisher(); - ClientFactory.setTestClient(client); + ClientHolder.setClient(client); jenkins.jenkins.getQueue().clear(); } diff --git a/src/test/java/org/datadog/jenkins/plugins/datadog/steps/DatadogOptionsTest.java b/src/test/java/org/datadog/jenkins/plugins/datadog/steps/DatadogOptionsTest.java index 86d33ffb..842a546f 100644 --- a/src/test/java/org/datadog/jenkins/plugins/datadog/steps/DatadogOptionsTest.java +++ b/src/test/java/org/datadog/jenkins/plugins/datadog/steps/DatadogOptionsTest.java @@ -8,7 +8,7 @@ import org.apache.commons.io.IOUtils; import org.datadog.jenkins.plugins.datadog.DatadogGlobalConfiguration; import org.datadog.jenkins.plugins.datadog.DatadogUtilities; -import org.datadog.jenkins.plugins.datadog.clients.ClientFactory; +import org.datadog.jenkins.plugins.datadog.clients.ClientHolder; import org.datadog.jenkins.plugins.datadog.clients.DatadogClientStub; import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition; import org.jenkinsci.plugins.workflow.job.WorkflowJob; @@ -28,7 +28,7 @@ public class DatadogOptionsTest { @BeforeClass public static void setup() throws Exception { - ClientFactory.setTestClient(stubClient); + ClientHolder.setClient(stubClient); DatadogGlobalConfiguration cfg = DatadogUtilities.getDatadogGlobalDescriptor(); ExtensionList.clearLegacyInstances(); cfg.setCollectBuildLogs(false);