From 93db117e91ea6f8f274b332d173c97f028beb135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lei=C3=9F?= Date: Sat, 26 Oct 2019 17:32:29 +0200 Subject: [PATCH 1/7] Add logging for chain actitivy log. Log notification related information to BAMBOO-URL/chain/viewChainActivityLog.action?planKey=PLANKEY. --- .../server/ServerNotificationRecipient.java | 14 ++++++- .../server/ServerNotificationTransport.java | 37 +++++++++++++++++-- src/main/resources/atlassian-plugin.xml | 2 + 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationRecipient.java b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationRecipient.java index 258dd00..3cdf50c 100644 --- a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationRecipient.java +++ b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationRecipient.java @@ -1,5 +1,6 @@ package de.tum.in.www1.bamboo.server; +import com.atlassian.bamboo.build.BuildLoggerManager; import com.atlassian.bamboo.deployments.results.DeploymentResult; import com.atlassian.bamboo.notification.NotificationRecipient; import com.atlassian.bamboo.notification.NotificationTransport; @@ -36,6 +37,7 @@ public class ServerNotificationRecipient extends AbstractNotificationRecipient i private ResultsSummary resultsSummary; private DeploymentResult deploymentResult; private CustomVariableContext customVariableContext; + private static BuildLoggerManager buildLoggerManager; // Time in seconds before removing TestResultsContainer private static final int TESTRESULTSCONTAINER_REMOVE_TIME = 60; @@ -132,7 +134,7 @@ public String getViewHtml() public List getTransports() { List list = Lists.newArrayList(); - list.add(new ServerNotificationTransport(webhookUrl, plan, resultsSummary, deploymentResult, customVariableContext)); + list.add(new ServerNotificationTransport(webhookUrl, plan, resultsSummary, deploymentResult, customVariableContext, buildLoggerManager)); return list; } @@ -156,6 +158,16 @@ public void setResultsSummary(@Nullable final ResultsSummary resultsSummary) this.resultsSummary = resultsSummary; } + public void setBuildLoggerManager(@Nullable final BuildLoggerManager buildLoggerManager) + { + this.buildLoggerManager = buildLoggerManager; + } + + public static BuildLoggerManager getBuildLoggerManager() + { + return buildLoggerManager; + } + public static Map getCachedTestResults() { return cachedTestResults; } diff --git a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java index 5791c7c..885eca6 100644 --- a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java +++ b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java @@ -1,5 +1,7 @@ package de.tum.in.www1.bamboo.server; +import com.atlassian.bamboo.build.BuildLoggerManager; +import com.atlassian.bamboo.build.logger.BuildLogger; import com.atlassian.bamboo.chains.ChainResultsSummary; import com.atlassian.bamboo.chains.ChainStageResult; import com.atlassian.bamboo.commit.Commit; @@ -34,7 +36,6 @@ import org.json.JSONObject; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; @@ -56,6 +57,8 @@ public class ServerNotificationTransport implements NotificationTransport private final ResultsSummary resultsSummary; @Nullable private final DeploymentResult deploymentResult; + @Nullable + private final BuildLoggerManager buildLoggerManager; private VariableDefinitionManager variableDefinitionManager = (VariableDefinitionManager) ContainerManager.getComponent("variableDefinitionManager"); // Will be injected by Bamboo @@ -63,12 +66,14 @@ public ServerNotificationTransport(String webhookUrl, @Nullable ImmutablePlan plan, @Nullable ResultsSummary resultsSummary, @Nullable DeploymentResult deploymentResult, - CustomVariableContext customVariableContext) + CustomVariableContext customVariableContext, + BuildLoggerManager buildLoggerManager) { this.webhookUrl = customVariableContext.substituteString(webhookUrl); this.plan = plan; this.resultsSummary = resultsSummary; this.deploymentResult = deploymentResult; + this.buildLoggerManager = buildLoggerManager; URI uri; try @@ -77,6 +82,7 @@ public ServerNotificationTransport(String webhookUrl, } catch (URISyntaxException e) { + logErrorToBuildLog("Unable to set up proxy settings, invalid URI encountered: " + e); log.error("Unable to set up proxy settings, invalid URI encountered: " + e); return; } @@ -96,6 +102,7 @@ public ServerNotificationTransport(String webhookUrl, public void sendNotification(@NotNull Notification notification) { + logToBuildLog("Sending notification"); try { HttpPost method = setupPostMethod(); @@ -104,21 +111,26 @@ public void sendNotification(@NotNull Notification notification) String secret = (String) jsonObject.get("secret"); method.addHeader("Authorization", secret); } catch (JSONException e) { + logErrorToBuildLog("Error while getting secret from JSONObject: " + e.getMessage()); log.error("Error while getting secret from JSONObject: " + e.getMessage(), e); } method.setEntity(new StringEntity(jsonObject.toString(), ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8))); try { + logToBuildLog("Executing call to " + method.getURI().toString()); log.debug(method.getURI().toString()); log.debug(method.getEntity().toString()); client.execute(method); + logToBuildLog("Call executed"); } catch (IOException e) { + logErrorToBuildLog("Error while sending payload: " + e.getMessage()); log.error("Error while sending payload: " + e.getMessage(), e); } } catch(URISyntaxException e) { + logErrorToBuildLog("Error parsing webhook url: " + e.getMessage()); log.error("Error parsing webhook url: " + e.getMessage(), e); } } @@ -131,6 +143,7 @@ private HttpPost setupPostMethod() throws URISyntaxException } private JSONObject createJSONObject(Notification notification) { + logToBuildLog("Creating JSON object"); JSONObject jsonObject = new JSONObject(); try { // Variable name contains "password" to ensure that the secret is hidden in the UI @@ -203,8 +216,10 @@ private JSONObject createJSONObject(Notification notification) { jobDetails.put("id", buildResultsSummary.getId()); + logToBuildLog("Loading cached test results"); TestResultsContainer testResultsContainer = ServerNotificationRecipient.getCachedTestResults().get(buildResultsSummary.getPlanResultKey().toString()); if (testResultsContainer != null) { + logToBuildLog("Tests results found"); JSONArray successfulTestDetails = createTestsResultsJSONArray(testResultsContainer.getSuccessfulTests(), false); jobDetails.put("successfulTests", successfulTestDetails); @@ -213,6 +228,8 @@ private JSONObject createJSONObject(Notification notification) { JSONArray failedTestDetails = createTestsResultsJSONArray(testResultsContainer.getFailedTests(), true); jobDetails.put("failedTests", failedTestDetails); + } else { + logErrorToBuildLog("Could not load cached test results!"); } jobs.put(jobDetails); } @@ -228,13 +245,16 @@ private JSONObject createJSONObject(Notification notification) { } catch (JSONException e) { + logErrorToBuildLog("JSON construction error :" + e.getMessage()); log.error("JSON construction error :" + e.getMessage(), e); } - return jsonObject; + logToBuildLog("JSON object created"); + return jsonObject; } private JSONObject createTestsResultsJSONObject(TestResults testResults, boolean addErrors) throws JSONException { + logToBuildLog("Creating test results JSON object for " + testResults.getActualMethodName()); JSONObject testResultsJSON = new JSONObject(); testResultsJSON.put("name", testResults.getActualMethodName()); testResultsJSON.put("methodName", testResults.getMethodName()); @@ -252,6 +272,7 @@ private JSONObject createTestsResultsJSONObject(TestResults testResults, boolean } private JSONArray createTestsResultsJSONArray(Collection testResultsCollection, boolean addErrors) throws JSONException { + logToBuildLog("Creating test results JSON array"); JSONArray testResultsArray = new JSONArray(); for (TestResults testResults : testResultsCollection) { testResultsArray.put(createTestsResultsJSONObject(testResults, addErrors)); @@ -259,4 +280,14 @@ private JSONArray createTestsResultsJSONArray(Collection testResult return testResultsArray; } + + private void logToBuildLog(String s) { + BuildLogger buildLogger = buildLoggerManager.getLogger(plan.getPlanKey()); + buildLogger.addBuildLogEntry("[BAMBOO-SERVER-NOTIFICATION] " + s); + } + + private void logErrorToBuildLog(String s) { + BuildLogger buildLogger = buildLoggerManager.getLogger(plan.getPlanKey()); + buildLogger.addErrorLogEntry("[BAMBOO-SERVER-NOTIFICATION] " + s); + } } diff --git a/src/main/resources/atlassian-plugin.xml b/src/main/resources/atlassian-plugin.xml index f17ea57..a8a3878 100644 --- a/src/main/resources/atlassian-plugin.xml +++ b/src/main/resources/atlassian-plugin.xml @@ -20,6 +20,8 @@ com.atlassian.bamboo.variable.VariableDefinitionManager + + From 90506c89ae68e9f9b3a522e2ed6c8d3eca89b33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lei=C3=9F?= Date: Sat, 26 Oct 2019 17:35:26 +0200 Subject: [PATCH 2/7] Bump version number to 1.1.2. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 73ff0ba..0f0f83b 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 de.tum.in.www1 bamboo-server - 1.1.1 + 1.1.2 LS1 TUM http://www1.in.tum.de/ From f63413abc0707f6e47ddb7674273339c4f4383ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lei=C3=9F?= Date: Sat, 26 Oct 2019 21:15:56 +0200 Subject: [PATCH 3/7] Add more logging for http request. --- .../server/ServerNotificationTransport.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java index 885eca6..c0b9220 100644 --- a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java +++ b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java @@ -20,7 +20,10 @@ import com.atlassian.bamboo.variable.VariableDefinition; import com.atlassian.bamboo.variable.VariableDefinitionManager; import com.atlassian.spring.container.ContainerManager; +import org.apache.http.HttpEntity; import org.apache.http.HttpHost; +import org.apache.http.StatusLine; +import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; @@ -28,6 +31,7 @@ import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.DefaultProxyRoutePlanner; +import org.apache.http.util.EntityUtils; import org.apache.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +39,6 @@ import org.json.JSONException; import org.json.JSONObject; -import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; @@ -121,9 +124,31 @@ public void sendNotification(@NotNull Notification notification) logToBuildLog("Executing call to " + method.getURI().toString()); log.debug(method.getURI().toString()); log.debug(method.getEntity().toString()); - client.execute(method); + CloseableHttpResponse closeableHttpResponse = client.execute(method); logToBuildLog("Call executed"); - } catch (IOException e) { + if (closeableHttpResponse != null) { + logToBuildLog("Response is not null: " + closeableHttpResponse.toString()); + + StatusLine statusLine = closeableHttpResponse.getStatusLine(); + if (statusLine != null) { + logToBuildLog("StatusLine is not null: " + statusLine.toString()); + logToBuildLog("StatusCode is: " + statusLine.getStatusCode()); + } else { + logErrorToBuildLog("Statusline is null"); + } + + HttpEntity httpEntity = closeableHttpResponse.getEntity(); + if (httpEntity != null) { + String response = EntityUtils.toString(httpEntity); + logToBuildLog("Response from entity is: " + response); + EntityUtils.consume(httpEntity); + } else { + logErrorToBuildLog("Httpentity is null"); + } + } else { + logErrorToBuildLog("Response is null"); + } + } catch (Exception e) { logErrorToBuildLog("Error while sending payload: " + e.getMessage()); log.error("Error while sending payload: " + e.getMessage(), e); } From 1297528b220eac9da16a0034d49be3e6d76c0315 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lei=C3=9F?= Date: Sat, 26 Oct 2019 21:16:25 +0200 Subject: [PATCH 4/7] Bump version number. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0f0f83b..3aead5b 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 de.tum.in.www1 bamboo-server - 1.1.2 + 1.1.3 LS1 TUM http://www1.in.tum.de/ From e3d4efbec604e2dff7be5f43930c9b47baa5f017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lei=C3=9F?= Date: Sat, 26 Oct 2019 21:18:15 +0200 Subject: [PATCH 5/7] Add null checks to logging. --- .../server/ServerNotificationTransport.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java index c0b9220..0897ba2 100644 --- a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java +++ b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java @@ -307,12 +307,20 @@ private JSONArray createTestsResultsJSONArray(Collection testResult } private void logToBuildLog(String s) { - BuildLogger buildLogger = buildLoggerManager.getLogger(plan.getPlanKey()); - buildLogger.addBuildLogEntry("[BAMBOO-SERVER-NOTIFICATION] " + s); + if (buildLoggerManager != null && plan != null) { + BuildLogger buildLogger = buildLoggerManager.getLogger(plan.getPlanKey()); + if (buildLogger != null) { + buildLogger.addBuildLogEntry("[BAMBOO-SERVER-NOTIFICATION] " + s); + } + } } private void logErrorToBuildLog(String s) { - BuildLogger buildLogger = buildLoggerManager.getLogger(plan.getPlanKey()); - buildLogger.addErrorLogEntry("[BAMBOO-SERVER-NOTIFICATION] " + s); + if (buildLoggerManager != null && plan != null) { + BuildLogger buildLogger = buildLoggerManager.getLogger(plan.getPlanKey()); + if (buildLogger != null) { + buildLogger.addErrorLogEntry("[BAMBOO-SERVER-NOTIFICATION] " + s); + } + } } } From 6d0a8bde4658da1216958be7615ead2f0869fba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lei=C3=9F?= Date: Sat, 26 Oct 2019 22:03:02 +0200 Subject: [PATCH 6/7] Truncate error log to 5000 chars. Bump version number. --- pom.xml | 2 +- .../in/www1/bamboo/server/ServerNotificationTransport.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3aead5b..4e35b89 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 de.tum.in.www1 bamboo-server - 1.1.3 + 1.1.4 LS1 TUM http://www1.in.tum.de/ diff --git a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java index 0897ba2..1737120 100644 --- a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java +++ b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java @@ -288,7 +288,9 @@ private JSONObject createTestsResultsJSONObject(TestResults testResults, boolean if (addErrors) { JSONArray testCaseErrorDetails = new JSONArray(); for(TestCaseResultError testCaseResultError : testResults.getErrors()) { - testCaseErrorDetails.put(testCaseResultError.getContent()); + String content = testCaseResultError.getContent(); + content = content.substring(0, Math.min(content.length(), 5000)); + testCaseErrorDetails.put(content); } testResultsJSON.put("errors", testCaseErrorDetails); } From 92cb7e0516e1dd5851f954d2065c316f961775a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lei=C3=9F?= Date: Sat, 26 Oct 2019 22:11:33 +0200 Subject: [PATCH 7/7] Change truncation handling. Bump version number. --- pom.xml | 2 +- .../bamboo/server/ServerNotificationTransport.java | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 4e35b89..3eb1c50 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ 4.0.0 de.tum.in.www1 bamboo-server - 1.1.4 + 1.1.5 LS1 TUM http://www1.in.tum.de/ diff --git a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java index 1737120..256574a 100644 --- a/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java +++ b/src/main/java/de/tum/in/www1/bamboo/server/ServerNotificationTransport.java @@ -65,6 +65,9 @@ public class ServerNotificationTransport implements NotificationTransport private VariableDefinitionManager variableDefinitionManager = (VariableDefinitionManager) ContainerManager.getComponent("variableDefinitionManager"); // Will be injected by Bamboo + // Maximum length for the feedback text. The feedback will be truncated afterwards + private static int FEEDBACK_DETAIL_TEXT_MAX_CHARACTERS = 5000; + public ServerNotificationTransport(String webhookUrl, @Nullable ImmutablePlan plan, @Nullable ResultsSummary resultsSummary, @@ -288,9 +291,11 @@ private JSONObject createTestsResultsJSONObject(TestResults testResults, boolean if (addErrors) { JSONArray testCaseErrorDetails = new JSONArray(); for(TestCaseResultError testCaseResultError : testResults.getErrors()) { - String content = testCaseResultError.getContent(); - content = content.substring(0, Math.min(content.length(), 5000)); - testCaseErrorDetails.put(content); + String errorMessageString = testCaseResultError.getContent(); + if(errorMessageString != null && errorMessageString.length() > FEEDBACK_DETAIL_TEXT_MAX_CHARACTERS) { + errorMessageString = errorMessageString.substring(0, FEEDBACK_DETAIL_TEXT_MAX_CHARACTERS); + } + testCaseErrorDetails.put(errorMessageString); } testResultsJSON.put("errors", testCaseErrorDetails); }