diff --git a/src/main/java/in/ashwanthkumar/gocd/slack/GoNotificationPlugin.java b/src/main/java/in/ashwanthkumar/gocd/slack/GoNotificationPlugin.java index bc08729..bfb8d83 100644 --- a/src/main/java/in/ashwanthkumar/gocd/slack/GoNotificationPlugin.java +++ b/src/main/java/in/ashwanthkumar/gocd/slack/GoNotificationPlugin.java @@ -1,13 +1,7 @@ package in.ashwanthkumar.gocd.slack; -import com.google.gson.GsonBuilder; -import com.thoughtworks.go.plugin.api.GoApplicationAccessor; import com.thoughtworks.go.plugin.api.GoPlugin; -import com.thoughtworks.go.plugin.api.GoPluginIdentifier; import com.thoughtworks.go.plugin.api.annotation.Extension; -import com.thoughtworks.go.plugin.api.logging.Logger; -import com.thoughtworks.go.plugin.api.request.GoPluginApiRequest; -import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; import in.ashwanthkumar.gocd.slack.base.AbstractNotificationPlugin; import in.ashwanthkumar.gocd.slack.ruleset.Rules; import in.ashwanthkumar.gocd.slack.ruleset.RulesReader; @@ -15,26 +9,15 @@ import org.apache.commons.io.IOUtils; import java.io.File; -import java.io.IOException; -import java.util.*; +import java.util.Timer; +import java.util.TimerTask; import java.util.concurrent.locks.ReentrantReadWriteLock; -import static java.util.Arrays.asList; - @Extension -public class GoNotificationPlugin extends AbstractNotificationPlugin implements GoPlugin { +public class GoNotificationPlugin extends AbstractNotificationPlugin implements GoPlugin { public static final String CRUISE_SERVER_DIR = "CRUISE_SERVER_DIR"; private static final long CONFIG_REFRESH_INTERVAL = 10 * 1000; // 10 seconds - - public static final String REQUEST_NOTIFICATIONS_INTERESTED_IN = "notifications-interested-in"; - public static final String REQUEST_GET_CONFIGURATION = "go.plugin-settings.get-configuration"; - public static final String REQUEST_GET_VIEW = "go.plugin-settings.get-view"; - public static final String REQUEST_VALIDATE_CONFIGURATION = "go.plugin-settings.validate-configuration"; - - public static final int SUCCESS_RESPONSE_CODE = 200; - public static final int INTERNAL_ERROR_RESPONSE_CODE = 500; - public static final String GO_NOTIFY_CONF = "GO_NOTIFY_CONF"; public static final String CONFIG_FILE_NAME = "go_notify.conf"; public static final String HOME_PLUGIN_CONFIG_PATH = System.getProperty("user.home") + File.separator + CONFIG_FILE_NAME; @@ -48,6 +31,7 @@ public class GoNotificationPlugin extends AbstractNotificationPlugin implements private File pluginConfig; public GoNotificationPlugin() { + super(); pluginConfig = findGoNotifyConfigPath(); timer.scheduleAtFixedRate(new TimerTask() { @Override @@ -70,59 +54,15 @@ public void run() { } } }, 0, CONFIG_REFRESH_INTERVAL); + this.settings = new SlackPluginSettings(); } // used for tests GoNotificationPlugin(GoEnvironment environment) { + super(); this.environment = environment; } - @Override - public void handleStageNotification(GoNotificationMessage notification) throws Exception{ - try { - LOGGER.info(notification.fullyQualifiedJobName() + " has " + notification.getStageState() + "/" + notification.getStageResult()); - lock.readLock().lock(); - rules.getPipelineListener().notify(notification); - } finally { - lock.readLock().unlock(); - } - } - - @Override - public String template() throws Exception { - return IOUtils.toString(getClass().getResourceAsStream("/views/config.template.html"), "UTF-8"); - } - - - public GoPluginApiResponse handle(GoPluginApiRequest goPluginApiRequest) { - String requestName = goPluginApiRequest.requestName(); - switch (requestName) { - case REQUEST_NOTIFICATIONS_INTERESTED_IN: - return handleNotificationsInterestedIn(); - case REQUEST_STAGE_STATUS: - return handleStageNotification(goPluginApiRequest); - case REQUEST_GET_VIEW: - return handleRequestGetView(); - case REQUEST_VALIDATE_CONFIGURATION: - return handleValidateConfig(goPluginApiRequest.requestBody()); - case REQUEST_GET_CONFIGURATION: - return handleRequestGetConfiguration(); - } - return null; - } - - protected GoPluginApiResponse handleValidateConfig(String requestBody) { - List response = Arrays.asList(); - return renderJSON(SUCCESS_RESPONSE_CODE, response); - } - - private GoPluginApiResponse handleRequestGetConfiguration() { - Map response = new TreeMap<>(); - response.put("server-url-external", configField("External GoCD Server URL", "", "1", true, false)); - response.put("pipelineConfig", configField("Pipeline Notification Rules", "", "2", true, false)); - return renderJSON(SUCCESS_RESPONSE_CODE, response); - } - private File findGoNotifyConfigPath() { // case 1: Look for an environment variable by GO_NOTIFY_CONF and if a file identified by the value exist String goNotifyConfPath = environment.getenv(GO_NOTIFY_CONF); @@ -149,4 +89,20 @@ private File findGoNotifyConfigPath() { throw new RuntimeException("Unable to find go_notify.conf. Please make sure you've set it up right."); } + + @Override + public void handleStageNotification(GoNotificationMessage notification) throws Exception { + try { + LOGGER.info(notification.fullyQualifiedJobName() + " has " + notification.getStageState() + "/" + notification.getStageResult()); + lock.readLock().lock(); + rules.getPipelineListener().notify(notification); + } finally { + lock.readLock().unlock(); + } + } + + @Override + public String template() throws Exception { + return IOUtils.toString(getClass().getResourceAsStream("/views/config.template.html"), "UTF-8"); + } } diff --git a/src/main/java/in/ashwanthkumar/gocd/slack/base/AbstractNotificationPlugin.java b/src/main/java/in/ashwanthkumar/gocd/slack/base/AbstractNotificationPlugin.java index 158dd69..f127c26 100644 --- a/src/main/java/in/ashwanthkumar/gocd/slack/base/AbstractNotificationPlugin.java +++ b/src/main/java/in/ashwanthkumar/gocd/slack/base/AbstractNotificationPlugin.java @@ -9,24 +9,33 @@ import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; import in.ashwanthkumar.gocd.slack.GoNotificationMessage; +import in.ashwanthkumar.gocd.slack.base.config.Configurations; +import in.ashwanthkumar.gocd.slack.base.config.ConfigurationsParser; import in.ashwanthkumar.gocd.slack.base.serializer.GsonFactory; import in.ashwanthkumar.utils.collections.Lists; -import org.apache.commons.io.IOUtils; -import java.io.IOException; import java.util.*; -import static in.ashwanthkumar.gocd.slack.GoNotificationPlugin.INTERNAL_ERROR_RESPONSE_CODE; -import static in.ashwanthkumar.gocd.slack.GoNotificationPlugin.SUCCESS_RESPONSE_CODE; import static in.ashwanthkumar.utils.lang.StringUtils.isNotEmpty; -abstract public class AbstractNotificationPlugin implements GoPlugin { +abstract public class AbstractNotificationPlugin implements GoPlugin { public static final String EXTENSION_TYPE = "notification"; + + public static final int SUCCESS_RESPONSE_CODE = 200; + public static final int INTERNAL_ERROR_RESPONSE_CODE = 500; + public static final String REQUEST_STAGE_STATUS = "stage-status"; + public static final String REQUEST_NOTIFICATIONS_INTERESTED_IN = "notifications-interested-in"; + public static final String REQUEST_GET_CONFIGURATION = "go.plugin-settings.get-configuration"; + public static final String REQUEST_GET_VIEW = "go.plugin-settings.get-view"; + public static final String REQUEST_VALIDATE_CONFIGURATION = "go.plugin-settings.validate-configuration"; protected Logger LOGGER = Logger.getLoggerFor(this.getClass()); protected GoApplicationAccessor goApplicationAccessor; + private Configurations configurations; + protected T settings; + /** * StageNotification handler of the plugin. For every notification from the server, we'll call this method. * @@ -41,7 +50,9 @@ abstract public class AbstractNotificationPlugin implements GoPlugin { * @return Entire HTML template as string * @throws Exception In case of any issues while trying to get the template from a local file / URL. */ - abstract public String template() throws Exception; + public String template() throws Exception { + return null; + } public void initializeGoApplicationAccessor(GoApplicationAccessor goApplicationAccessor) { this.goApplicationAccessor = goApplicationAccessor; @@ -51,6 +62,23 @@ public GoPluginIdentifier pluginIdentifier() { return new GoPluginIdentifier(EXTENSION_TYPE, getGoSupportedVersions()); } + public GoPluginApiResponse handle(GoPluginApiRequest goPluginApiRequest) { + String requestName = goPluginApiRequest.requestName(); + switch (requestName) { + case REQUEST_NOTIFICATIONS_INTERESTED_IN: + return handleNotificationsInterestedIn(); + case REQUEST_STAGE_STATUS: + return handleStageNotification(goPluginApiRequest); + case REQUEST_GET_VIEW: + return handleRequestGetView(); + case REQUEST_VALIDATE_CONFIGURATION: + return handleValidateConfig(goPluginApiRequest.requestBody()); + case REQUEST_GET_CONFIGURATION: + return handleRequestGetConfiguration(); + } + return null; + } + /** * List of Go Notification API do we support. */ @@ -65,8 +93,7 @@ protected List subscriptions() { return Lists.of(REQUEST_STAGE_STATUS); } - // TODO - Make me private - protected GoPluginApiResponse handleStageNotification(GoPluginApiRequest goPluginApiRequest) { + private GoPluginApiResponse handleStageNotification(GoPluginApiRequest goPluginApiRequest) { GoNotificationMessage message = parseNotificationMessage(goPluginApiRequest); int responseCode = SUCCESS_RESPONSE_CODE; @@ -90,15 +117,13 @@ protected GoPluginApiResponse handleStageNotification(GoPluginApiRequest goPlugi return renderJSON(responseCode, response); } - // TODO - Make me private - protected GoPluginApiResponse handleNotificationsInterestedIn() { + private GoPluginApiResponse handleNotificationsInterestedIn() { Map response = new HashMap<>(); response.put("notifications", subscriptions()); return renderJSON(SUCCESS_RESPONSE_CODE, response); } - // TODO - Make me private - protected GoPluginApiResponse handleRequestGetView() { + private GoPluginApiResponse handleRequestGetView() { Map response = new HashMap<>(); try { @@ -112,28 +137,21 @@ protected GoPluginApiResponse handleRequestGetView() { return renderJSON(SUCCESS_RESPONSE_CODE, response); } - - /** - * Create a configuration field for the plugin. - * - * @param displayName Name of the configuration - * @param defaultValue Default value if none provided - * @param displayOrder Order in which it should be displayed - * @param required If the field is mandatory. - * @param secure If the data in the field should be stored encrypted. - * @return - */ - protected Map configField(String displayName, String defaultValue, String displayOrder, boolean required, boolean secure) { - return new Configuration() - .setDisplayName(displayName) - .setDefaultValue(defaultValue) - .setDisplayOrder(Integer.parseInt(displayOrder)) - .setRequired(required) - .setSecure(secure) - .asMap(); + private GoPluginApiResponse handleRequestGetConfiguration() { + if(isSettingsConfigured()) { + lazyUpdateConfigurations(); + return renderJSON(SUCCESS_RESPONSE_CODE, this.configurations); + } + return renderJSON(SUCCESS_RESPONSE_CODE, new HashMap()); } + private GoPluginApiResponse handleValidateConfig(String requestBody) { + List response = Arrays.asList(); + // TODO - Implement parsing Configurations back to settings + return renderJSON(SUCCESS_RESPONSE_CODE, response); + } + // TODO - Make private protected GoPluginApiResponse renderJSON(final int responseCode, final Object response) { final String json = response == null ? null : GsonFactory.getGson().toJson(response); DefaultGoPluginApiResponse pluginApiResponse = new DefaultGoPluginApiResponse(responseCode); @@ -144,4 +162,14 @@ protected GoPluginApiResponse renderJSON(final int responseCode, final Object re private GoNotificationMessage parseNotificationMessage(GoPluginApiRequest goPluginApiRequest) { return new GsonBuilder().create().fromJson(goPluginApiRequest.requestBody(), GoNotificationMessage.class); } + + private void lazyUpdateConfigurations() { + if (this.configurations == null) { + this.configurations = ConfigurationsParser.parseConfigurations(settings.getClass()); + } + } + + private boolean isSettingsConfigured() { + return settings != null; + } } diff --git a/src/test/java/in/ashwanthkumar/gocd/slack/base/serializer/ConfigurationsSerializerTest.java b/src/test/java/in/ashwanthkumar/gocd/slack/base/serializer/ConfigurationsSerializerTest.java index ff32b8e..ac84288 100644 --- a/src/test/java/in/ashwanthkumar/gocd/slack/base/serializer/ConfigurationsSerializerTest.java +++ b/src/test/java/in/ashwanthkumar/gocd/slack/base/serializer/ConfigurationsSerializerTest.java @@ -21,9 +21,9 @@ public void shouldSerializeConfigurationsProperly() { )); Gson gson = GsonFactory.getGson(); String configAsJson = gson.toJson(configurations); - Map> expectedMap = new TreeMap<>(); + Map expectedMap = new TreeMap<>(); for (Configuration config : configurations) { - expectedMap.put(config.getId(), config.asMap()); + expectedMap.put(config.getId(), config); } String expectedJson = gson.toJson(expectedMap);