From 4f8a9892990861f7f4f402975d3bc19800f7be96 Mon Sep 17 00:00:00 2001 From: Net Wolf UK Date: Mon, 15 May 2017 09:45:12 +1200 Subject: [PATCH] Set HTTP timeouts for webhooks. Performance fix for get previous build. - Uses a more efficient method for determining previous non-personal build. This is used to determine if the build has changed state from the previous build. eg, Fixed or Broken since the last buid. - Add ability to configure timeouts for http connect and response. - Defaults to 120 seconds for connect timeout and response timeout - Values can be overridden by adding a block similar to the following in the main-config.xml file. Timeouts are specified in seconds. --- .../src/main/java/webhook/WebHook.java | 4 ++ .../src/main/java/webhook/WebHookImpl.java | 15 +++++++- .../webhook/teamcity/WebHookListener.java | 22 ++++++----- .../teamcity/settings/WebHookMainConfig.java | 38 ++++++++++++++++++- .../settings/WebHookMainSettings.java | 25 +++++++++++- 5 files changed, 91 insertions(+), 13 deletions(-) diff --git a/tcwebhooks-core/src/main/java/webhook/WebHook.java b/tcwebhooks-core/src/main/java/webhook/WebHook.java index fc58cf30..88370aa6 100644 --- a/tcwebhooks-core/src/main/java/webhook/WebHook.java +++ b/tcwebhooks-core/src/main/java/webhook/WebHook.java @@ -88,6 +88,10 @@ public interface WebHook { public abstract void setAuthentication(WebHookAuthenticator authenticator); + public abstract void setConnectionTimeOut(int httpConnectionTimeout); + + public abstract void setResponseTimeOut(int httpResponseTimeout); + } \ No newline at end of file diff --git a/tcwebhooks-core/src/main/java/webhook/WebHookImpl.java b/tcwebhooks-core/src/main/java/webhook/WebHookImpl.java index 6f5041ac..85aa6a29 100644 --- a/tcwebhooks-core/src/main/java/webhook/WebHookImpl.java +++ b/tcwebhooks-core/src/main/java/webhook/WebHookImpl.java @@ -5,7 +5,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -18,7 +17,7 @@ import org.apache.commons.httpclient.methods.StringRequestEntity; import webhook.teamcity.BuildState; -import webhook.teamcity.auth.WebHookAuthConfig; +import webhook.teamcity.Loggers; import webhook.teamcity.auth.WebHookAuthenticator; @@ -130,6 +129,8 @@ public void post() throws FileNotFoundException, IOException{ } try { + Loggers.SERVER.debug("WebHookImpl:: Connect timeout(millis): " + this.client.getHttpConnectionManager().getParams().getConnectionTimeout()); + Loggers.SERVER.debug("WebHookImpl:: Response timeout(millis): " + this.client.getHttpConnectionManager().getParams().getSoTimeout()); client.executeMethod(httppost); this.resultCode = httppost.getStatusCode(); this.content = httppost.getResponseBodyAsString(); @@ -320,4 +321,14 @@ public void setBuildStates(BuildState states) { public void setAuthentication(WebHookAuthenticator authenticator) { this.authenticator = authenticator; } + + @Override + public void setConnectionTimeOut(int httpConnectionTimeout) { + this.client.getHttpConnectionManager().getParams().setConnectionTimeout(httpConnectionTimeout * 1000); + } + + @Override + public void setResponseTimeOut(int httpResponseTimeout) { + this.client.getHttpConnectionManager().getParams().setSoTimeout(httpResponseTimeout * 1000); + } } diff --git a/tcwebhooks-core/src/main/java/webhook/teamcity/WebHookListener.java b/tcwebhooks-core/src/main/java/webhook/teamcity/WebHookListener.java index ae0724b0..1aba9f54 100644 --- a/tcwebhooks-core/src/main/java/webhook/teamcity/WebHookListener.java +++ b/tcwebhooks-core/src/main/java/webhook/teamcity/WebHookListener.java @@ -84,6 +84,9 @@ public void getFromConfig(WebHook webHook, WebHookConfig webHookConfig){ webHook.setAuthentication(auth); } webHook.setProxy(myMainSettings.getProxyConfigForUrl(webHookConfig.getUrl())); + webHook.setConnectionTimeOut(myMainSettings.getHttpConnectionTimeout()); + webHook.setResponseTimeOut(myMainSettings.getHttpResponseTimeout()); + Loggers.ACTIVITIES.debug("WebHookListener :: Webhook proxy set to " + webHook.getProxyHost() + " for " + webHookConfig.getUrl()); } @@ -330,15 +333,16 @@ private void doPost(WebHook wh, String payloadFormat) { } } - @Nullable - private SFinishedBuild getPreviousNonPersonalBuild(SRunningBuild paramSRunningBuild) - { - List localList = this.myBuildServer.getHistory().getEntriesBefore(paramSRunningBuild, false); - - for (SFinishedBuild localSFinishedBuild : localList) - if (!(localSFinishedBuild.isPersonal())) return localSFinishedBuild; - return null; - } + @Nullable + private SFinishedBuild getPreviousNonPersonalBuild(SBuild paramSBuild) { + SFinishedBuild localSFinishedBuild = paramSBuild.getPreviousFinished(); + if (localSFinishedBuild == null) { // There was not a previous build. + return localSFinishedBuild; + } else if (localSFinishedBuild.isPersonal()){ + localSFinishedBuild = getPreviousNonPersonalBuild(localSFinishedBuild); + } + return localSFinishedBuild; + } private boolean hasBuildChangedHistoricalState(SRunningBuild sRunningBuild){ SFinishedBuild previous = getPreviousNonPersonalBuild(sRunningBuild); diff --git a/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainConfig.java b/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainConfig.java index 26da742a..e08bc129 100644 --- a/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainConfig.java +++ b/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainConfig.java @@ -12,6 +12,10 @@ public class WebHookMainConfig { + + final static int HTTP_CONNECT_TIMEOUT_DEFAULT = 120; + final static int HTTP_RESPONSE_TIMEOUT_DEFAULT = 120; + private String webhookInfoUrl = null; private String webhookInfoText = null; private Boolean webhookShowFurtherReading = true; @@ -22,6 +26,8 @@ public class WebHookMainConfig { private Boolean proxyShortNames = false; private List noProxyUrls; private List noProxyPatterns; + private Integer httpConnectionTimeout; + private Integer httpResponseTimeout; public final String SINGLE_HOST_REGEX = "^[^./~`'\"]+(?:/.*)?$"; public final String HOSTNAME_ONLY_REGEX = "^([^/]+)(?:/.*)?$"; @@ -176,6 +182,15 @@ public Element getProxyAsElement(){ return el; } + public Element getTimeoutsAsElement () { + if (this.httpConnectionTimeout == null && this.httpResponseTimeout == null) { + return null; + } + Element el = new Element("http-timeout") + .setAttribute("connect", String.valueOf(getHttpConnectionTimeout())) + .setAttribute("response", String.valueOf(this.getHttpResponseTimeout())); + return el; + } public Integer getProxyPort() { return proxyPort; @@ -248,6 +263,27 @@ public void setWebhookShowFurtherReading(Boolean webhookShowFurtherReading) { public Boolean getWebhookShowFurtherReading() { return webhookShowFurtherReading; } - + + public Integer getHttpConnectionTimeout() { + if (this.httpConnectionTimeout != null) { + return httpConnectionTimeout; + } + return HTTP_CONNECT_TIMEOUT_DEFAULT; + } + + public void setHttpConnectionTimeout(Integer httpConnectionTimeout) { + this.httpConnectionTimeout = httpConnectionTimeout; + } + + public Integer getHttpResponseTimeout() { + if (this.httpResponseTimeout != null) { + return httpResponseTimeout; + } + return HTTP_RESPONSE_TIMEOUT_DEFAULT; + } + + public void setHttpResponseTimeout(Integer httpResponseimeout) { + this.httpResponseTimeout = httpResponseimeout; + } } \ No newline at end of file diff --git a/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainSettings.java b/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainSettings.java index 7b1637b3..05151277 100644 --- a/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainSettings.java +++ b/tcwebhooks-core/src/main/java/webhook/teamcity/settings/WebHookMainSettings.java @@ -57,6 +57,17 @@ public void readFrom(Element rootElement) Loggers.SERVER.debug(NAME + ":readFrom :: show reading " + tempConfig.getWebhookShowFurtherReading().toString()); } } + + Element timeoutsElement = webhooksElement.getChild("http-timeout"); + if (timeoutsElement != null) { + if (timeoutsElement.getAttribute("connect") != null) { + tempConfig.setHttpConnectionTimeout(Integer.valueOf(timeoutsElement.getAttributeValue("connect"))); + } + if (timeoutsElement.getAttribute("response") != null) { + tempConfig.setHttpResponseTimeout(Integer.valueOf(timeoutsElement.getAttributeValue("response"))); + } + } + Element proxyElement = webhooksElement.getChild("proxy"); if(proxyElement != null) { @@ -112,6 +123,9 @@ public void writeTo(Element parentElement) Loggers.SERVER.debug(NAME + "writeTo :: proxyPort " + webHookMainConfig.getProxyPort().toString()); } + if(webHookMainConfig != null && webHookMainConfig.getTimeoutsAsElement() != null) { + el.addContent(webHookMainConfig.getTimeoutsAsElement()); + } if(webHookMainConfig != null && webHookMainConfig.getInfoUrlAsElement() != null){ el.addContent(webHookMainConfig.getInfoUrlAsElement()); @@ -144,5 +158,14 @@ public void dispose() { } public WebHookProxyConfig getProxyConfigForUrl(String url) { - return this.webHookMainConfig.getProxyConfigForUrl(url); } + return this.webHookMainConfig.getProxyConfigForUrl(url); + } + + public int getHttpConnectionTimeout() { + return this.webHookMainConfig.getHttpConnectionTimeout(); + } + + public int getHttpResponseTimeout() { + return this.webHookMainConfig.getHttpResponseTimeout(); + } }