diff --git a/README.md b/README.md index 3e5c05c..4303e20 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,15 @@ gocd-websocket-notifier.conf in the home directory of the user that runs go. port=8888 host=127.0.0.1 ```` +Plugin uses default Go server HTTP port 8153. To edit, add the following to the .conf +```` +goHttpPort=8080 +```` +If basic authenication is required for Go Api, add them to the same .conf file as follows: +```` +goUser=go.user +goPassword=myGoPassword +```` ## Planned Enhancements * Send [a reply](http://www.go.cd/documentation/developer/writing_go_plugins/notification/version_1_0/stage_status_notification.html#response---from-the-plugin) diff --git a/pom.xml b/pom.xml index 1a78482..1fab223 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,13 @@ 1.3.0 + + + commons-codec + commons-codec + 1.10 + + junit diff --git a/src/main/java/com/matt_richardson/gocd/websocket_notifier/GoNotificationPlugin.java b/src/main/java/com/matt_richardson/gocd/websocket_notifier/GoNotificationPlugin.java index 97cf058..fc70af5 100644 --- a/src/main/java/com/matt_richardson/gocd/websocket_notifier/GoNotificationPlugin.java +++ b/src/main/java/com/matt_richardson/gocd/websocket_notifier/GoNotificationPlugin.java @@ -41,7 +41,7 @@ public void initializeGoApplicationAccessor(GoApplicationAccessor goApplicationA } s.start(); LOGGER.info("WebSocket server started on port: " + s.getPort()); - pipelineListener = new WebSocketPipelineListener(s); + pipelineListener = new WebSocketPipelineListener(s, pluginConfig); } catch (UnknownHostException e) { LOGGER.error("Failed to launch WebSocket server on port: " + port, e); } diff --git a/src/main/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulator.java b/src/main/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulator.java index 2e64af9..04453ff 100644 --- a/src/main/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulator.java +++ b/src/main/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulator.java @@ -5,6 +5,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.thoughtworks.go.plugin.api.logging.Logger; +import org.apache.commons.codec.binary.Base64; import java.io.IOException; import java.io.InputStream; @@ -14,14 +15,10 @@ public class PipelineDetailsPopulator { private static Logger LOGGER = Logger.getLoggerFor(GoNotificationPlugin.class); - private int httpPort; + private PluginConfig pluginConfig; - public PipelineDetailsPopulator() { - this.httpPort = 8153; - } - - public PipelineDetailsPopulator(int httpPort) { - this.httpPort = httpPort; + public PipelineDetailsPopulator(PluginConfig pluginConfig) { + this.pluginConfig = pluginConfig; } String mergeInPipelineInstanceDetails(JsonElement notification, JsonElement pipelineInstance) @@ -32,10 +29,19 @@ String mergeInPipelineInstanceDetails(JsonElement notification, JsonElement pipe } JsonElement downloadPipelineInstanceDetails(String pipelineName) throws IOException { - String sURL = "http://localhost:" + httpPort + "/go/api/pipelines/" + pipelineName + "/history"; + int goHttpPort = pluginConfig.getGoHttpPort(); + String sURL = "http://localhost:" + goHttpPort + "/go/api/pipelines/" + pipelineName + "/history"; URL url = new URL(sURL); HttpURLConnection request = (HttpURLConnection) url.openConnection(); + if (pluginConfig.hasBasicAuth()) { + String user = pluginConfig.getGoUser(); + String password = pluginConfig.getGoPassword(); + + String authString = user + ":" + password; + String encoded = new String(Base64.encodeBase64(authString.getBytes())); + request.setRequestProperty("Authorization", "Basic "+encoded); + } request.connect(); JsonParser parser = new JsonParser(); diff --git a/src/main/java/com/matt_richardson/gocd/websocket_notifier/PluginConfig.java b/src/main/java/com/matt_richardson/gocd/websocket_notifier/PluginConfig.java index b852a72..56eea9e 100644 --- a/src/main/java/com/matt_richardson/gocd/websocket_notifier/PluginConfig.java +++ b/src/main/java/com/matt_richardson/gocd/websocket_notifier/PluginConfig.java @@ -9,8 +9,14 @@ public class PluginConfig { private static Logger LOGGER = Logger.getLoggerFor(GoNotificationPlugin.class); private static final String PLUGIN_CONF = "gocd-websocket-notifier.conf"; + private static final int goDefaultHttpPort = 8153; + private int port = 8887; private String host = ""; + + private int goHttpPort = goDefaultHttpPort; + private String goUser; + private String goPassword; public PluginConfig() { String userHome = System.getProperty("user.home"); @@ -26,6 +32,15 @@ public PluginConfig() { if (config.hasPath("host")) { setHost(config.getString("host")); } + if (config.hasPath("goHttpPort")) { + setGoHttpPort(config.getInt("goHttpPort")); + } + if (config.hasPath("goUser")) { + setGoUser(config.getString("goUser")); + } + if (config.hasPath("goPassword")) { + setGoPassword(config.getString("goPassword")); + } } } @@ -35,4 +50,18 @@ public PluginConfig() { public String getHost() { return host; } public void setHost(String host) { this.host = host; } public boolean isHostSet() { return !host.isEmpty(); } + + public int getGoHttpPort() { return goHttpPort; } + public void setGoHttpPort(int port) { this.goHttpPort = port; } + + public String getGoUser() { return goUser; } + public void setGoUser(String user) { this.goUser = user; } + public boolean isGoUserSet() { return goUser != null; } + + public String getGoPassword() { return goPassword; } + public void setGoPassword(String password) { this.goPassword = password; } + public boolean isGoPasswordSet() { return goPassword != null; } + + public boolean hasBasicAuth() { return isGoUserSet() && isGoPasswordSet(); } + } diff --git a/src/main/java/com/matt_richardson/gocd/websocket_notifier/WebSocketPipelineListener.java b/src/main/java/com/matt_richardson/gocd/websocket_notifier/WebSocketPipelineListener.java index 49ae065..d367b04 100644 --- a/src/main/java/com/matt_richardson/gocd/websocket_notifier/WebSocketPipelineListener.java +++ b/src/main/java/com/matt_richardson/gocd/websocket_notifier/WebSocketPipelineListener.java @@ -8,9 +8,9 @@ public class WebSocketPipelineListener { private PipelineWebSocketServer webSocketServer; private Logger LOGGER = Logger.getLoggerFor(WebSocketPipelineListener.class); - public WebSocketPipelineListener(PipelineWebSocketServer webSocketServer) { + public WebSocketPipelineListener(PipelineWebSocketServer webSocketServer, PluginConfig pluginConfig) { this.webSocketServer = webSocketServer; - this.populator = new PipelineDetailsPopulator(); + this.populator = new PipelineDetailsPopulator(pluginConfig); } public void notify(GoPluginApiRequest message) @@ -19,4 +19,4 @@ public void notify(GoPluginApiRequest message) String expandedMessage = populator.extendMessageToIncludePipelineDetails(message.requestBody()); this.webSocketServer.sendToAll(expandedMessage); } -} \ No newline at end of file +} diff --git a/src/test/java/com/matt_richardson/gocd/websocket_notifier/FakeWebSocketPipelineListener.java b/src/test/java/com/matt_richardson/gocd/websocket_notifier/FakeWebSocketPipelineListener.java index 5c38c79..e2ed79b 100644 --- a/src/test/java/com/matt_richardson/gocd/websocket_notifier/FakeWebSocketPipelineListener.java +++ b/src/test/java/com/matt_richardson/gocd/websocket_notifier/FakeWebSocketPipelineListener.java @@ -7,7 +7,7 @@ public class FakeWebSocketPipelineListener extends WebSocketPipelineListener { private GoPluginApiRequest receivedMessage; public FakeWebSocketPipelineListener() { - super(null); + super(null, new PluginConfig()); } @Override diff --git a/src/test/java/com/matt_richardson/gocd/websocket_notifier/GoCDApi.java b/src/test/java/com/matt_richardson/gocd/websocket_notifier/GoCDApi.java index 3ee3a7e..1098584 100644 --- a/src/test/java/com/matt_richardson/gocd/websocket_notifier/GoCDApi.java +++ b/src/test/java/com/matt_richardson/gocd/websocket_notifier/GoCDApi.java @@ -10,9 +10,9 @@ class GoCDApi { - private String httpPort; + private int httpPort; - GoCDApi(String httpPort) { + GoCDApi(int httpPort) { this.httpPort = httpPort; } diff --git a/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationBase.java b/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationBase.java index ad112c8..3895c2d 100644 --- a/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationBase.java +++ b/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationBase.java @@ -23,8 +23,7 @@ public abstract class IntegrationBase { private static DockerClient docker = null; private static String containerId = null; - static String httpPort; - static String websocketsPort; + static PluginConfig pluginConfig = null; static GoCDApi goCdApi; @BeforeClass @@ -34,7 +33,7 @@ public static void BeforeAnyTest() throws Exception { SetupTestFolder(testPath); SetupContainer(); RunContainer(testPath); - goCdApi = new GoCDApi(httpPort); + goCdApi = new GoCDApi(pluginConfig.getGoHttpPort()); } private static String DetermineTestPath() throws UnsupportedEncodingException { @@ -118,13 +117,12 @@ private static void RunContainer(String testPath) throws Exception { } if (message.contains("Go Server has started on port 8153 inside this container")) { final ContainerInfo info = docker.inspectContainer(containerId); - httpPort = info.networkSettings().ports().get("8153/tcp").get(0).hostPort(); - String httpsPort = info.networkSettings().ports().get("8154/tcp").get(0).hostPort(); - websocketsPort = info.networkSettings().ports().get("8887/tcp").get(0).hostPort(); + pluginConfig = new PluginConfig(); + pluginConfig.setGoHttpPort(Integer.parseInt(info.networkSettings().ports().get("8153/tcp").get(0).hostPort())); + pluginConfig.setPort(Integer.parseInt(info.networkSettings().ports().get("8887/tcp").get(0).hostPort())); - System.out.println("HTTP port is " + httpPort); - System.out.println("HTTPS port is " + httpsPort); - System.out.println("WS port is " + websocketsPort); + System.out.println("HTTP port is " + pluginConfig.getGoHttpPort()); + System.out.println("WS port is " + pluginConfig.getGoHttpPort()); return; } Thread.sleep(5000); diff --git a/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationTest.java b/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationTest.java index ea32b9d..279ab9e 100644 --- a/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationTest.java +++ b/src/test/java/com/matt_richardson/gocd/websocket_notifier/IntegrationTest.java @@ -11,7 +11,7 @@ public class IntegrationTest extends IntegrationBase { @Test public void testWebSocketReceivesMessageOnNewPipeline() throws Exception { - GoCdWebSocketClient client = new GoCdWebSocketClient( new URI( "ws://localhost:" + websocketsPort )); + GoCdWebSocketClient client = new GoCdWebSocketClient( new URI( "ws://localhost:" + pluginConfig.getPort() )); System.out.println("Creating pipeline"); String pipelineName = goCdApi.createPipeline(); @@ -32,7 +32,7 @@ public void testWebSocketReceivesMessageOnNewPipeline() throws Exception @Test public void testDownloadPipelineInstanceDetails() throws Exception { - GoCdWebSocketClient client = new GoCdWebSocketClient( new URI( "ws://localhost:" + websocketsPort )); + GoCdWebSocketClient client = new GoCdWebSocketClient( new URI( "ws://localhost:" + pluginConfig.getPort() )); String pipelineName = goCdApi.createPipeline(); goCdApi.unPausePipeline(pipelineName); @@ -46,7 +46,7 @@ public void testDownloadPipelineInstanceDetails() throws Exception { if (client.receivedAtLeastOneMessage()) throw new Exception("Didn't get a message over the websocket."); - PipelineDetailsPopulator populator = new PipelineDetailsPopulator(Integer.parseInt(httpPort)); + PipelineDetailsPopulator populator = new PipelineDetailsPopulator(pluginConfig); JsonObject element = populator.downloadPipelineInstanceDetails(pipelineName).getAsJsonObject(); Assert.assertEquals(element.get("name").getAsString(), pipelineName); } diff --git a/src/test/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulatorTest.java b/src/test/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulatorTest.java index 0de8e8a..6b1f8fe 100644 --- a/src/test/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulatorTest.java +++ b/src/test/java/com/matt_richardson/gocd/websocket_notifier/PipelineDetailsPopulatorTest.java @@ -16,7 +16,8 @@ public void testMergeInPipelineInstanceDetails() throws Exception { JsonElement pipelineInstance = parser.parse(additionalJson); JsonElement notification = parser.parse(originalJson); - PipelineDetailsPopulator populator = new PipelineDetailsPopulator(); + PluginConfig pluginConfig = new PluginConfig(); + PipelineDetailsPopulator populator = new PipelineDetailsPopulator(pluginConfig); String result = populator.mergeInPipelineInstanceDetails(notification, pipelineInstance); assertThat(result, is("{\"pipeline-name\":\"test\",\"pipeline-counter\":13,\"stage-name\":\"defaultStage\",\"stage-counter\":\"1\",\"stage-state\":\"Passed\",\"stage-result\":\"Passed\",\"create-time\":\"2015-02-19T07:41:21.162Z\",\"last-transition-time\":\"2015-02-19T07:41:45.576Z\",\"x-pipeline-instance-details\":{\"build_cause\":{\"approver\":\"\",\"material_revisions\":[{\"modifications\":[{\"email_address\":null,\"id\":10,\"modified_time\":1424331650000,\"user_name\":\"Matt Richardson \",\"comment\":\"Update readme with details about development status\",\"revision\":\"a50098faa112d8324d9acf9ade727f837d7930dd\"}],\"material\":{\"description\":\"URL: /home/vagrant/gocd-websocket-notifier2, Branch: master\",\"fingerprint\":\"f77449ab015e3fd36c3a2088ea6338f4d4e0922f04bdcc4c5104bbacd1a72dbe\",\"type\":\"Git\",\"id\":1},\"changed\":true}],\"trigger_forced\":false,\"trigger_message\":\"modified by Matt Richardson \"},\"name\":\"test\",\"natural_order\":13.0,\"can_run\":true,\"comment\":null,\"stages\":[{\"name\":\"defaultStage\",\"approved_by\":\"changes\",\"jobs\":[{\"name\":\"defaultJob\",\"result\":\"Passed\",\"state\":\"Completed\",\"id\":13,\"scheduled_date\":1424331681162}],\"can_run\":true,\"result\":\"Passed\",\"approval_type\":\"success\",\"counter\":\"1\",\"id\":13,\"operate_permission\":true,\"rerun_of_counter\":null,\"scheduled\":true}],\"counter\":13,\"id\":13,\"preparing_to_schedule\":false,\"label\":\"13\"}}")); }