From 7161c0bfdf56b9471b72e7f1ad4042393fbc0d24 Mon Sep 17 00:00:00 2001 From: Phoenix616 Date: Thu, 18 Jun 2020 21:19:35 +0100 Subject: [PATCH] Add Jenkins test build notifier This will only send a notification into the log once for each new build and can be disabled in the config or the new jenkinsBuildNotifier.yml --- .../java/com/Acrobot/ChestShop/ChestShop.java | 12 ++ .../ChestShop/Configuration/Properties.java | 3 + .../Updater/JenkinsBuildsNotifier.java | 123 ++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 src/main/java/com/Acrobot/ChestShop/Updater/JenkinsBuildsNotifier.java diff --git a/src/main/java/com/Acrobot/ChestShop/ChestShop.java b/src/main/java/com/Acrobot/ChestShop/ChestShop.java index ac856ee..90f4bae 100644 --- a/src/main/java/com/Acrobot/ChestShop/ChestShop.java +++ b/src/main/java/com/Acrobot/ChestShop/ChestShop.java @@ -38,6 +38,7 @@ import com.Acrobot.ChestShop.Logging.FileFormatter; import com.Acrobot.ChestShop.Metadata.ItemDatabase; import com.Acrobot.ChestShop.Signs.RestrictedSign; import com.Acrobot.ChestShop.UUIDs.NameManager; +import com.Acrobot.ChestShop.Updater.JenkinsBuildsNotifier; import com.Acrobot.ChestShop.Updater.Updater; import com.google.common.io.ByteArrayDataOutput; @@ -142,6 +143,7 @@ public class ChestShop extends JavaPlugin { } startStatistics(); + startBuildNotificatier(); startUpdater(); } @@ -414,6 +416,16 @@ public class ChestShop extends JavaPlugin { new Updater(this, PROJECT_BUKKITDEV_ID, this.getFile(), Updater.UpdateType.DEFAULT, true); } + private static final String PROJECT_JENKINS_JOB_URL = "https://ci.minebench.de/job/ChestShop-3/"; + + private void startBuildNotificatier() { + if (Properties.TURN_OFF_DEV_UPDATE_NOTIFIER) { + return; + } + + new JenkinsBuildsNotifier(this, PROJECT_JENKINS_JOB_URL); + } + /////////////////////////////////////////////////////////////////////////////// public static ItemDatabase getItemDatabase() { diff --git a/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java b/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java index a051ef3..c4b6c3b 100644 --- a/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java +++ b/src/main/java/com/Acrobot/ChestShop/Configuration/Properties.java @@ -102,6 +102,9 @@ public class Properties { @ConfigurationComment("Do you want to turn off the automatic updates of ChestShop?") public static boolean TURN_OFF_UPDATES = true; + @ConfigurationComment("Do you want to turn off the automatic notifications for new development builds?") + public static boolean TURN_OFF_DEV_UPDATE_NOTIFIER = false; + @PrecededBySpace @ConfigurationComment("How large should the internal caches be?") public static int CACHE_SIZE = 1000; diff --git a/src/main/java/com/Acrobot/ChestShop/Updater/JenkinsBuildsNotifier.java b/src/main/java/com/Acrobot/ChestShop/Updater/JenkinsBuildsNotifier.java new file mode 100644 index 0000000..b5a736c --- /dev/null +++ b/src/main/java/com/Acrobot/ChestShop/Updater/JenkinsBuildsNotifier.java @@ -0,0 +1,123 @@ +package com.Acrobot.ChestShop.Updater; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.logging.Level; + +public class JenkinsBuildsNotifier implements Runnable { + private final Plugin plugin; + + private final File configFile; + private final FileConfiguration config; + + private int build; + private URL apiUrl; + + public JenkinsBuildsNotifier(Plugin plugin, String jenkinsJobUrl) { + this.plugin = plugin; + + configFile = new File(plugin.getDataFolder(), "jenkinsBuildsNotifier.yml"); + if (configFile.exists()) { + config = YamlConfiguration.loadConfiguration(configFile); + } else { + config = new YamlConfiguration(); + config.addDefault("disabled", false); + config.addDefault("jenkins-job-url-override", ""); + config.options().copyDefaults(true); + saveConfig(); + } + + if (config.getBoolean("disabled")) { + return; + } + + build = getBuildNumber(); + if (build < 1) { + plugin.getLogger().log(Level.WARNING, "Unable to parse plugin build from version string! (" + plugin.getDescription().getVersion() + ")"); + return; + } + + String jenkinsJobUrlOverride = config.getString("jenkins-job-url-override"); + if (jenkinsJobUrlOverride != null && !jenkinsJobUrlOverride.isEmpty()) { + jenkinsJobUrl = jenkinsJobUrlOverride; + } + + try { + apiUrl = new URL(jenkinsJobUrl + "api/json"); + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, this); + } catch (MalformedURLException e) { + plugin.getLogger().log(Level.WARNING, "Can not check for new dev builds as " + jenkinsJobUrl + "api/json is not a valid url!", e); + } + } + + private void saveConfig() { + try { + config.save(configFile); + } catch (IOException e) { + plugin.getLogger().log(Level.WARNING, "Error while saving " + configFile.getName() + "! " + e.getMessage()); + } + } + + private int getBuildNumber() { + String tag = "(build "; + String versionStr = plugin.getDescription().getVersion(); + int start = versionStr.indexOf(tag); + int end = versionStr.indexOf(')', start); + if (start > 0 && end > start) { + try { + return Integer.parseInt(versionStr.substring(start + tag.length(), end)); + } catch (NumberFormatException ignored) {} + } + return -1; + } + + @Override + public void run() { + try { + JsonObject responseJson = queryJson(); + if (responseJson.has("lastStableBuild") && responseJson.get("lastStableBuild").isJsonObject()) { + JsonObject lastStable = responseJson.getAsJsonObject("lastStableBuild"); + int lastStableBuild = lastStable.get("number").getAsInt(); + if (lastStableBuild > build && config.getInt("last-announced-build", 0) < lastStableBuild) { + String url = lastStable.get("url").getAsString(); + plugin.getLogger().log(Level.INFO, "A new development build is available for testing: " + url); + + config.set("last-announced-build", lastStableBuild); + saveConfig(); + } + } + + } catch (Exception e) { + plugin.getLogger().log(Level.WARNING, "Error while trying to query Jenkins API", e); + } + } + + private JsonObject queryJson() throws IOException { + HttpURLConnection con = (HttpURLConnection) apiUrl.openConnection(); + con.setRequestProperty("User-Agent", plugin.getName() + " " + plugin.getDescription().getVersion() + " Jenkins Builds Notifier"); + con.setRequestMethod("GET"); + StringBuilder msg = new StringBuilder(); + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String line; + while((line = in.readLine()) != null) { + if(msg.length() != 0) { + msg.append("\n"); + } + msg.append(line); + } + in.close(); + + return new JsonParser().parse(msg.toString()).getAsJsonObject(); + } +}