Skip to content

Commit

Permalink
Add NVPairs (x-www-form-urlencoded) template. Fixes issue #120
Browse files Browse the repository at this point in the history
Just put your variables into the body of the template lines in the
format "name=${variable}" (without the quotes).

eg,
				${item3}=${item4}
				bar=foo
				${item5}=${item6}
  • Loading branch information
netwolfuk committed Dec 11, 2018
1 parent 5c997a0 commit 13c366f
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package webhook.teamcity.payload.format;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import webhook.teamcity.payload.PayloadTemplateEngineType;
import webhook.teamcity.payload.WebHookContentObjectSerialiser;
import webhook.teamcity.payload.WebHookPayload;
import webhook.teamcity.payload.WebHookPayloadManager;
import webhook.teamcity.payload.WebHookTemplateContent;
import webhook.teamcity.payload.content.WebHookPayloadContent;
import webhook.teamcity.payload.content.WebHookPayloadContentAssemblyException;
import webhook.teamcity.payload.template.render.WebHookStringRenderer;
import webhook.teamcity.payload.template.render.WwwFormUrlEncodedToHtmlPrettyPrintingRenderer;
import webhook.teamcity.payload.variableresolver.VariableMessageBuilder;
import webhook.teamcity.payload.variableresolver.WebHookVariableResolverManager;

public class WebHookPayloadNameValuePairsTemplate extends WebHookPayloadGeneric implements WebHookPayload, WebHookContentObjectSerialiser {

public static final String FORMAT_SHORT_NAME = "nvpairsTemplate";
public static final String FORMAT_CONTENT_TYPE = "application/x-www-form-urlencoded";

Integer rank = 101;
String charset = "UTF-8";

Gson gson = new GsonBuilder().create();

public WebHookPayloadNameValuePairsTemplate(WebHookPayloadManager manager, WebHookVariableResolverManager variableResolverManager){
super(manager, variableResolverManager);
}

@Override
public void register(){
myManager.registerPayloadFormat(this);
}

@Override
public String getFormatDescription() {
return "Name Value Pairs - urlencoded (standard template)";
}

@Override
public String getFormatShortName() {
return FORMAT_SHORT_NAME;
}

@Override
public String getFormatToolTipText() {
return "Send a x-www-form-urlencoded payload with content from a standard template";
}

@Override
protected String getStatusAsString(WebHookPayloadContent content, WebHookTemplateContent webHookTemplateContent){
VariableMessageBuilder builder = this.myVariableResolverFactory.createVariableMessageBuilder(webHookTemplateContent.getTemplateText(), this.myVariableResolverFactory.buildVariableResolver(this, content, content.getAllParameters()));
try {
return URLEncodedUtils.format(parseToNvPairs(builder.build()), Charset.forName(getCharset()));
} catch (IOException ex) {
throw new WebHookPayloadContentAssemblyException("Failed to parse template input. Check the input is correct");
}
}

@Override
public String getContentType() {
return FORMAT_CONTENT_TYPE;
}

@Override
public Integer getRank() {
return this.rank;
}

@Override
public void setRank(Integer rank) {
this.rank = rank;
}

@Override
public String getCharset() {
return this.charset;
}

@Override
public WebHookStringRenderer getWebHookStringRenderer() {
return new WwwFormUrlEncodedToHtmlPrettyPrintingRenderer();
}

@Override
public Object serialiseObject(Object object) {
return object;
}

@Override
public PayloadTemplateEngineType getTemplateEngineType() {
return PayloadTemplateEngineType.STANDARD;
}

public List<NameValuePair> parseToNvPairs(String s) throws IOException {
List<NameValuePair> nvPairs = new ArrayList<>();
for (String line : s.split("\n")) {
if (! line.trim().isEmpty()) {
String[] item = line.trim().split("=", 2);
nvPairs.add(new BasicNameValuePair(item[0], item[1]));
}
}
return nvPairs;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package webhook.teamcity.payload.template;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.Date;
import java.util.SortedMap;
import java.util.TreeMap;

import jetbrains.buildServer.messages.Status;
import jetbrains.buildServer.serverSide.SBuildServer;
import jetbrains.buildServer.serverSide.SFinishedBuild;

import org.junit.Test;

import webhook.teamcity.BuildStateEnum;
import webhook.teamcity.MockSBuildType;
import webhook.teamcity.MockSProject;
import webhook.teamcity.MockSRunningBuild;
import webhook.teamcity.payload.WebHookPayloadDefaultTemplates;
import webhook.teamcity.payload.WebHookPayloadManager;
import webhook.teamcity.payload.WebHookTemplateManager;
import webhook.teamcity.payload.content.WebHookPayloadContentAssemblyException;
import webhook.teamcity.payload.format.WebHookPayloadNameValuePairsTemplate;
import webhook.teamcity.payload.template.render.WebHookStringRenderer.WebHookHtmlRendererException;
import webhook.teamcity.payload.variableresolver.WebHookVariableResolverManager;
import webhook.teamcity.payload.variableresolver.WebHookVariableResolverManagerImpl;
import webhook.teamcity.payload.variableresolver.standard.WebHooksBeanUtilsVariableResolverFactory;
import webhook.teamcity.settings.entity.WebHookTemplateJaxHelperImpl;
import webhook.teamcity.settings.entity.WebHookTemplateJaxTestHelper;

public class NameValuePairsTemplateRenderingTest {

SBuildServer mockServer = mock(SBuildServer.class);
WebHookTemplateManager wtm;
WebHookPayloadManager wpm = new WebHookPayloadManager(mockServer);
WebHookTemplateJaxHelperImpl webHookTemplateJaxHelper = new WebHookTemplateJaxTestHelper();

@Test
public void TestNvPairsTemplatesWithHtmlRenderer() throws WebHookHtmlRendererException, WebHookPayloadContentAssemblyException {
when(mockServer.getRootUrl()).thenReturn("http://test.url");
wtm = new WebHookTemplateManager(null, null);
AbstractXmlBasedWebHookTemplate wht = new TestNvPairsXmlTemplate(wtm, wpm, webHookTemplateJaxHelper);
wht.register();

MockSBuildType sBuildType = new MockSBuildType("Test Build", "A Test Build", "bt1");
String triggeredBy = "SubVersion";
MockSRunningBuild sRunningBuild = new MockSRunningBuild(sBuildType, triggeredBy, Status.NORMAL, "Running", "TestBuild01");
SFinishedBuild previousBuild = mock(SFinishedBuild.class);
when (previousBuild.getFinishDate()).thenReturn(new Date());
MockSProject sProject = new MockSProject("Test Project", "A test project", "project1", "ATestProject", sBuildType);
sBuildType.setProject(sProject);
SBuildServer mockServer = mock(SBuildServer.class);
when(mockServer.getRootUrl()).thenReturn("http://test.url");

WebHookVariableResolverManager variableResolverManager = new WebHookVariableResolverManagerImpl();
variableResolverManager.registerVariableResolverFactory(new WebHooksBeanUtilsVariableResolverFactory());


WebHookPayloadManager wpm = new WebHookPayloadManager(mockServer);
WebHookPayloadNameValuePairsTemplate whp = new WebHookPayloadNameValuePairsTemplate(wpm, variableResolverManager);
whp.register();
SortedMap<String, String> extraParameters = new TreeMap<>();

extraParameters.put("item1", "content1");
extraParameters.put("item2", "content2");
extraParameters.put("item3", "content3");
extraParameters.put("item4", "content4");
extraParameters.put("item5", "content5");
extraParameters.put("item6", "This is a $weird string with % and ' and # and stuff");



//WebHookPayloadContent content = new WebHookPayloadContent(mockServer, sRunningBuild, previousBuild, BuildStateEnum.BUILD_SUCCESSFUL, extraParameters, extraParameters, WebHookPayloadDefaultTemplates.getDefaultEnabledPayloadTemplates());
String result = whp.buildFinished(sRunningBuild, previousBuild, extraParameters, WebHookPayloadDefaultTemplates.getDefaultEnabledPayloadTemplates(), wht.getBranchTemplateForState(BuildStateEnum.BUILD_SUCCESSFUL));
System.out.println("Template instance: " + wht.getBranchTemplateForState(BuildStateEnum.BUILD_SUCCESSFUL));
System.out.println("Template content: " + whp.getWebHookStringRenderer().render(wht.getBranchTemplateForState(BuildStateEnum.BUILD_SUCCESSFUL).getTemplateText()));
System.out.println("Result: " + result);
System.out.println("Rendered result: " + whp.getWebHookStringRenderer().render(result));

assertEquals(result, "content3=content4&bar=foo&content5=This+is+a+%24weird+string+with+%25+and+%27+and+%23+and+stuff");

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package webhook.teamcity.payload.template;

import webhook.teamcity.payload.WebHookPayloadManager;
import webhook.teamcity.payload.WebHookTemplateManager;
import webhook.teamcity.settings.entity.WebHookTemplateJaxHelper;

public class TestNvPairsXmlTemplate extends AbstractXmlBasedWebHookTemplate {

private static final String CONF_PROPERTIES = "webhook/teamcity/payload/template/TestNVPairsTemplate.xml";


public TestNvPairsXmlTemplate(WebHookTemplateManager templateManager, WebHookPayloadManager payloadManager,
WebHookTemplateJaxHelper webHookTemplateJaxHelper) {
super(templateManager, payloadManager, webHookTemplateJaxHelper);
}

@Override
public String getXmlFileName() {
return CONF_PROPERTIES;
}

@Override
public String getLoggingName() {
return "TestNvPairsXmlTemplate";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<webhook-template id="microsoft-teams-2" enabled="true"
rank="100" format="jsonTemplate">
<template-description>Microsoft Teams (light)</template-description>
<template-tool-tip>A template for Microsoft Teams. Has a different look
and feel.</template-tool-tip>
<preferred-date-format></preferred-date-format>
<templates max-id="3">
<template id="0">
<template-text use-for-branch-template="true">
test=${item1}
${item2}=bar
</template-text>
<branch-template-text></branch-template-text>
<states>
<state type="buildStarted" enabled="true" />
</states>
</template>
<template id="2">
<template-text use-for-branch-template="true">
${item3}=${item4}
bar=foo
${item5}=${item6}
</template-text>
<branch-template-text></branch-template-text>
<states>
<state type="buildSuccessful" enabled="true" />
</states>
</template>
</templates>
</webhook-template>
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@
</property>
</bean>

<bean id="webHookPayloadNameValuePairsTemplate"
class="webhook.teamcity.payload.format.WebHookPayloadNameValuePairsTemplate"
init-method="register">
<property name="rank">
<value>50</value>
</property>
</bean>

<bean id="webHookPayloadJsonVelocityTemplate"
class="webhook.teamcity.payload.format.WebHookPayloadJsonVelocityTemplate"
init-method="register">
Expand Down

0 comments on commit 13c366f

Please sign in to comment.