Skip to content

Commit

Permalink
Better handling of the case where webhook.body is empty or missing for
Browse files Browse the repository at this point in the history
the tailored_json format. Resolves issue #24
  • Loading branch information
netwolfuk committed Aug 31, 2016
1 parent d10feae commit 077b848
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import webhook.teamcity.payload.WebHookTemplateContent;
import webhook.teamcity.payload.WebHookTemplateResolver;
import webhook.teamcity.payload.content.WebHookPayloadContent;
import webhook.teamcity.payload.content.WebHookPayloadContentAssemblyException;
import webhook.teamcity.payload.util.TemplateMatcher.VariableResolver;
import webhook.teamcity.payload.util.VariableMessageBuilder;
import webhook.teamcity.payload.util.WebHooksBeanUtilsVariableResolver;
Expand All @@ -35,7 +36,7 @@ public WebHookContentBuilder(SBuildServer server, WebHookPayloadManager manager,
this.buildServer = server;
}

public WebHook buildWebHookContent(WebHook wh, WebHookConfig whc, SBuild sBuild, BuildStateEnum state, boolean isOverrideEnabled){
public WebHook buildWebHookContent(WebHook wh, WebHookConfig whc, SBuild sBuild, BuildStateEnum state, boolean isOverrideEnabled) throws WebHookPayloadContentAssemblyException{
WebHookPayload payloadFormat = payloadManager.getFormat(whc.getPayloadFormat());
WebHookTemplateContent templateForThisBuild;
wh.setContentType(payloadFormat.getContentType());
Expand Down
47 changes: 32 additions & 15 deletions tcwebhooks-core/src/main/java/webhook/teamcity/WebHookListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import webhook.teamcity.payload.WebHookPayloadManager;
import webhook.teamcity.payload.WebHookTemplateContent;
import webhook.teamcity.payload.WebHookTemplateResolver;
import webhook.teamcity.payload.content.WebHookPayloadContentAssemblyException;
import webhook.teamcity.settings.WebHookConfig;
import webhook.teamcity.settings.WebHookMainSettings;
import webhook.teamcity.settings.WebHookProjectSettings;
Expand Down Expand Up @@ -73,12 +74,18 @@ private void processBuildEvent(SRunningBuild sRunningBuild, BuildStateEnum state

Loggers.SERVER.debug("About to process WebHooks for " + sRunningBuild.getProjectId() + " at buildState " + state.getShortName());
for (WebHookConfig whc : getListOfEnabledWebHooks(sRunningBuild.getProjectId())){
WebHook wh = webHookFactory.getWebHook(whc, myMainSettings.getProxyConfigForUrl(whc.getUrl()));

wh = webHookContentBuilder.buildWebHookContent(wh, whc, sRunningBuild, state, overrideIsEnabled);
try {
WebHook wh = webHookFactory.getWebHook(whc, myMainSettings.getProxyConfigForUrl(whc.getUrl()));
wh = webHookContentBuilder.buildWebHookContent(wh, whc, sRunningBuild, state, overrideIsEnabled);

doPost(wh, whc.getPayloadFormat());
Loggers.ACTIVITIES.debug("WebHookListener :: " + myManager.getFormat(whc.getPayloadFormat()).getFormatDescription());

doPost(wh, whc.getPayloadFormat());
Loggers.ACTIVITIES.debug("WebHookListener :: " + myManager.getFormat(whc.getPayloadFormat()).getFormatDescription());
} catch (WebHookPayloadContentAssemblyException ex){
Loggers.SERVER.error(ex.getMessage());
Loggers.SERVER.debug(ex);
}
}
}

Expand Down Expand Up @@ -166,18 +173,23 @@ public void responsibleChanged(@NotNull SBuildType sBuildType,
}
Loggers.SERVER.debug("About to process WebHooks for " + sBuildType.getProjectId() + " at buildState responsibilityChanged");
for (WebHookConfig whc : getListOfEnabledWebHooks(sBuildType.getProjectId())){
WebHook wh = webHookFactory.getWebHook(whc, myMainSettings.getProxyConfigForUrl(whc.getUrl()));
WebHookPayload payloadFormat = myManager.getFormat(whc.getPayloadFormat());
WebHookTemplateContent templateForThisBuild = webHookTemplateResolver.findWebHookTemplate(BuildStateEnum.RESPONSIBILITY_CHANGED, sBuildType, payloadFormat.getFormatShortName(), whc.getPayloadTemplate());
wh.setContentType(payloadFormat.getContentType());
wh.setPayload(payloadFormat.responsibleChanged(sBuildType,
responsibilityInfoOld,
responsibilityInfoNew,
isUserAction,
WebHookContentBuilder.mergeParameters(whc.getParams(),sBuildType, templateForThisBuild.getPreferredDateTimeFormat()), whc.getEnabledTemplates(), templateForThisBuild));
wh.setEnabled(whc.isEnabledForBuildType(sBuildType) && wh.getBuildStates().enabled(BuildStateEnum.RESPONSIBILITY_CHANGED));
doPost(wh, whc.getPayloadFormat());
try {
WebHook wh = webHookFactory.getWebHook(whc, myMainSettings.getProxyConfigForUrl(whc.getUrl()));
WebHookPayload payloadFormat = myManager.getFormat(whc.getPayloadFormat());
WebHookTemplateContent templateForThisBuild = webHookTemplateResolver.findWebHookTemplate(BuildStateEnum.RESPONSIBILITY_CHANGED, sBuildType, payloadFormat.getFormatShortName(), whc.getPayloadTemplate());
wh.setContentType(payloadFormat.getContentType());
wh.setPayload(payloadFormat.responsibleChanged(sBuildType,
responsibilityInfoOld,
responsibilityInfoNew,
isUserAction,
WebHookContentBuilder.mergeParameters(whc.getParams(),sBuildType, templateForThisBuild.getPreferredDateTimeFormat()), whc.getEnabledTemplates(), templateForThisBuild));
wh.setEnabled(whc.isEnabledForBuildType(sBuildType) && wh.getBuildStates().enabled(BuildStateEnum.RESPONSIBILITY_CHANGED));
doPost(wh, whc.getPayloadFormat());
Loggers.ACTIVITIES.debug("WebHookListener :: " + myManager.getFormat(whc.getPayloadFormat()).getFormatDescription());
} catch (WebHookPayloadContentAssemblyException ex){
Loggers.SERVER.error(ex.getMessage());
Loggers.SERVER.debug(ex);
}
}
}

Expand Down Expand Up @@ -238,6 +250,7 @@ public void responsibleChanged(@NotNull SBuildType sBuildType,

Loggers.SERVER.debug("About to process WebHooks for " + sBuildType.getProjectId() + " at buildState responsibilityChanged");
for (WebHookConfig whc : getListOfEnabledWebHooks(sBuildType.getProjectId())){
try {
WebHook wh = webHookFactory.getWebHook(whc, myMainSettings.getProxyConfigForUrl(whc.getUrl()));
WebHookPayload payloadFormat = myManager.getFormat(whc.getPayloadFormat());
WebHookTemplateContent templateForThisBuild = webHookTemplateResolver.findWebHookTemplate(BuildStateEnum.RESPONSIBILITY_CHANGED, sBuildType, payloadFormat.getFormatShortName(), whc.getPayloadTemplate());
Expand All @@ -252,6 +265,10 @@ public void responsibleChanged(@NotNull SBuildType sBuildType,
wh.setEnabled(whc.isEnabledForBuildType(sBuildType) && wh.getBuildStates().enabled(BuildStateEnum.RESPONSIBILITY_CHANGED));
doPost(wh, whc.getPayloadFormat());
Loggers.ACTIVITIES.debug("WebHookListener :: " + myManager.getFormat(whc.getPayloadFormat()).getFormatDescription());
} catch (WebHookPayloadContentAssemblyException ex){
Loggers.SERVER.error(ex.getMessage());
Loggers.SERVER.debug(ex);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.Map;
import java.util.SortedMap;

import org.jetbrains.annotations.NotNull;

import jetbrains.buildServer.messages.Status;
import jetbrains.buildServer.responsibility.ResponsibilityEntry;
import jetbrains.buildServer.responsibility.TestNameResponsibilityEntry;
Expand All @@ -13,9 +15,7 @@
import jetbrains.buildServer.serverSide.SFinishedBuild;
import jetbrains.buildServer.serverSide.SProject;
import jetbrains.buildServer.tests.TestName;

import org.jetbrains.annotations.NotNull;

import webhook.teamcity.payload.content.WebHookPayloadContentAssemblyException;
import webhook.teamcity.payload.template.render.WebHookStringRenderer;

public interface WebHookPayload {
Expand Down Expand Up @@ -79,7 +79,7 @@ public interface WebHookPayload {
* @param extraParameters
* @return Formatted payload for the WebHook to send for the buildStarted event.
*/
String buildStarted(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate);
String buildStarted(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

/**
* Extracts the required information from the sRunningBuild and extraParameters configured in the webhook
Expand All @@ -89,7 +89,7 @@ public interface WebHookPayload {
* @param extraParameters
* @return Formatted payload for the WebHook to send for the changesLoaded event.
*/
String changesLoaded(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate);
String changesLoaded(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

/**
* Extracts the required information from the sRunningBuild and extraParameters configured in the webhook
Expand All @@ -99,7 +99,7 @@ public interface WebHookPayload {
* @param extraParameters
* @return Formatted payload for the WebHook to send for the buildFinished event.
*/
String buildFinished(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate);
String buildFinished(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

/**
* Extracts the required information from the sRunningBuild and extraParameters configured in the webhook
Expand All @@ -109,7 +109,7 @@ public interface WebHookPayload {
* @param extraParameters
* @return Formatted payload for the WebHook to send for the buildInterrupted event.
*/
String buildInterrupted(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate);
String buildInterrupted(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

/**
* Extracts the required information from the sRunningBuild and extraParameters configured in the webhook
Expand All @@ -119,7 +119,7 @@ public interface WebHookPayload {
* @param extraParameters
* @return Formatted payload for the WebHook to send for the beforeBuildFinish event.
*/
String beforeBuildFinish(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate);
String beforeBuildFinish(SBuild sRunningBuild, SFinishedBuild previousBuild, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

/**
* buildChangedStatus has been deprecated because it alluded to build history status, which was incorrect.
Expand All @@ -144,7 +144,7 @@ String buildChangedStatus(SBuild sRunningBuild, SFinishedBuild previousBuild,
String responsibleChanged(@NotNull SBuildType sBuildType,
@NotNull ResponsibilityInfo responsibilityInfoOld,
@NotNull ResponsibilityInfo responsibilityInfoNew,
boolean isUserAction, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate);
boolean isUserAction, SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

/**
* Used by TC 7.x and above
Expand All @@ -157,7 +157,7 @@ String responsibleChanged(@NotNull SBuildType sBuildType,
String responsibleChanged(SBuildType sBuildType,
ResponsibilityEntry responsibilityEntryOld,
ResponsibilityEntry responsibilityEntryNew,
SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate);
SortedMap<String,String> extraParameters, Map<String, String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

/**
* Gets the content type of the format.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package webhook.teamcity.payload.content;

public class WebHookPayloadContentAssemblyException extends Exception {

/**
*
*/
private static final long serialVersionUID = 1L;


public WebHookPayloadContentAssemblyException() {
super();
}


public WebHookPayloadContentAssemblyException(String message) {
super(message);
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import webhook.teamcity.payload.WebHookPayloadManager;
import webhook.teamcity.payload.WebHookTemplateContent;
import webhook.teamcity.payload.content.WebHookPayloadContent;
import webhook.teamcity.payload.content.WebHookPayloadContentAssemblyException;

public abstract class WebHookPayloadGeneric implements WebHookPayload {

Expand All @@ -40,7 +41,7 @@ public void setPayloadManager(WebHookPayloadManager manager){

@Override
public String beforeBuildFinish(SBuild runningBuild, SFinishedBuild previousBuild,
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) {
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException {
WebHookPayloadContent content = new WebHookPayloadContent(myManager.getServer(), runningBuild, previousBuild, BuildStateEnum.BEFORE_BUILD_FINISHED, extraParameters, runningBuild.getParametersProvider().getAll(), templates);
return getStatusAsString(content, webHookTemplate);
}
Expand All @@ -59,39 +60,40 @@ public String buildChangedStatus(SBuild runningBuild, SFinishedBuild previousBui

@Override
public String buildFinished(SBuild runningBuild, SFinishedBuild previousBuild,
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) {
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException {
WebHookPayloadContent content = new WebHookPayloadContent(myManager.getServer(), runningBuild, previousBuild, BuildStateEnum.BUILD_FINISHED, extraParameters, runningBuild.getParametersProvider().getAll(), templates);
return getStatusAsString(content, webHookTemplate);
}

@Override
public String buildInterrupted(SBuild runningBuild, SFinishedBuild previousBuild,
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) {
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException {
WebHookPayloadContent content = new WebHookPayloadContent(myManager.getServer(), runningBuild, previousBuild, BuildStateEnum.BUILD_INTERRUPTED, extraParameters, runningBuild.getParametersProvider().getAll(), templates);
return getStatusAsString(content, webHookTemplate);
}

@Override
public String changesLoaded(SBuild runningBuild, SFinishedBuild previousBuild,
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) {
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException {
WebHookPayloadContent content = new WebHookPayloadContent(myManager.getServer(), runningBuild, previousBuild, BuildStateEnum.CHANGES_LOADED, extraParameters, runningBuild.getParametersProvider().getAll(), templates);
return getStatusAsString(content, webHookTemplate);
}

@Override
public String buildStarted(SBuild runningBuild, SFinishedBuild previousBuild,
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) {
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException {
WebHookPayloadContent content = new WebHookPayloadContent(myManager.getServer(), runningBuild, previousBuild, BuildStateEnum.BUILD_STARTED, extraParameters, runningBuild.getParametersProvider().getAll(), templates);
return getStatusAsString(content, webHookTemplate);
}

/** Used by versions of TeamCity less than 7.0
* @throws WebHookPayloadContentAssemblyException
*/
@Override
public String responsibleChanged(SBuildType buildType,
ResponsibilityInfo responsibilityInfoOld,
ResponsibilityInfo responsibilityInfoNew, boolean isUserAction,
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) {
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException {

WebHookPayloadContent content = new WebHookPayloadContent(myManager.getServer(), buildType, BuildStateEnum.RESPONSIBILITY_CHANGED, extraParameters, templates);
String oldUser = "Nobody";
Expand Down Expand Up @@ -126,12 +128,13 @@ public String responsibleChanged(SBuildType buildType,
}

/** Used by versions of TeamCity 7.0 and above
* @throws WebHookPayloadContentAssemblyException
*/
@Override
public String responsibleChanged(SBuildType buildType,
ResponsibilityEntry responsibilityEntryOld,
ResponsibilityEntry responsibilityEntryNew,
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) {
SortedMap<String,String> extraParameters, Map<String,String> templates, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException {

WebHookPayloadContent content = new WebHookPayloadContent(myManager.getServer(), buildType, BuildStateEnum.RESPONSIBILITY_CHANGED, extraParameters, templates);
String oldUser = "Nobody";
Expand Down Expand Up @@ -183,7 +186,7 @@ public String responsibleChanged(SProject project,
return null;
}

protected abstract String getStatusAsString(WebHookPayloadContent content, WebHookTemplateContent webHookTemplate);
protected abstract String getStatusAsString(WebHookPayloadContent content, WebHookTemplateContent webHookTemplate) throws WebHookPayloadContentAssemblyException;

public abstract String getContentType();

Expand Down
Loading

0 comments on commit 077b848

Please sign in to comment.