diff --git a/src/main/java/com/linkedplanet/maven/plugin/upm/AbstractUpmMojo.java b/src/main/java/com/linkedplanet/maven/plugin/upm/AbstractUpmMojo.java index 146c594..ad4ba0f 100644 --- a/src/main/java/com/linkedplanet/maven/plugin/upm/AbstractUpmMojo.java +++ b/src/main/java/com/linkedplanet/maven/plugin/upm/AbstractUpmMojo.java @@ -35,6 +35,7 @@ import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.function.Predicate; import java.util.function.Supplier; abstract class AbstractUpmMojo extends AbstractMojo { @@ -72,23 +73,34 @@ BasicHeader getAuthHeader() { "Basic " + Base64.encodeBase64String((username + ":" + password).getBytes(StandardCharsets.UTF_8))); } - void poll(String taskName, long maxWaitMillis, Supplier callback) throws Exception { + Boolean poll(String taskName, long maxWaitMillis, Supplier task) { + return poll(taskName, maxWaitMillis, task, result -> result); + } + + Result pollResult(String taskName, long maxWaitMillis, Supplier task) { + return poll(taskName, maxWaitMillis, task, Result::isSuccess); + } + + T poll(String taskName, long maxWaitMillis, Supplier task, Predicate isCompleted) { long millisWaited = 0; - boolean success = false; - while (!success && millisWaited < maxWaitMillis) { + T taskResult = null; + while (millisWaited < maxWaitMillis) { getLog().info(taskName + ": Waiting for success (" + millisWaited + "/" + maxWaitMillis + " millis waited) ..."); long beginWaitMillis = System.currentTimeMillis(); - success = callback.get(); - Thread.sleep(5000); + taskResult = task.get(); + if (isCompleted.test(taskResult)) { + return taskResult; + } + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); + } millisWaited += System.currentTimeMillis() - beginWaitMillis; } - - if (millisWaited >= maxWaitMillis && !success) { - getLog().info(taskName + ": No longer waiting for success after " + maxWaitMillis + " millis"); - } - if (success) { - getLog().info(taskName + ": Success"); - } + getLog().info(taskName + ": No longer waiting for success after " + maxWaitMillis + " millis"); + return taskResult; } static JsonObject parseResponseAsJsonObject(CloseableHttpResponse response) throws Exception { @@ -96,7 +108,7 @@ static JsonObject parseResponseAsJsonObject(CloseableHttpResponse response) thro throw new Exception(response.getStatusLine().toString()); } String json = EntityUtils.toString(response.getEntity()); - return new JsonParser().parse(json).getAsJsonObject(); + return JsonParser.parseString(json).getAsJsonObject(); } } diff --git a/src/main/java/com/linkedplanet/maven/plugin/upm/Result.java b/src/main/java/com/linkedplanet/maven/plugin/upm/Result.java new file mode 100644 index 0000000..7ae433c --- /dev/null +++ b/src/main/java/com/linkedplanet/maven/plugin/upm/Result.java @@ -0,0 +1,49 @@ +package com.linkedplanet.maven.plugin.upm; + +interface Result { + String toMessage(); + + boolean isSuccess(); + + default boolean isFailure() { + return !isSuccess(); + } + + class Success implements Result { + @Override + public boolean isSuccess() { + return true; + } + + @Override + public String toMessage() { + return "Plugin verification succeeded."; + } + } + + class Failure implements Result { + private final String hint; + private final Throwable cause; + + Failure(String hint, Throwable cause) { + this.hint = hint; + this.cause = cause; + } + + Failure(String hint) { + this(hint, null); + } + + @Override + public boolean isSuccess() { + return false; + } + + @Override + public String toMessage() { + return cause == null + ? hint + : String.format("%s - Caused by: %s", hint, cause.getMessage()); + } + } +} diff --git a/src/main/java/com/linkedplanet/maven/plugin/upm/UploadPluginFileMojo.java b/src/main/java/com/linkedplanet/maven/plugin/upm/UploadPluginFileMojo.java index ce0abe4..1023495 100644 --- a/src/main/java/com/linkedplanet/maven/plugin/upm/UploadPluginFileMojo.java +++ b/src/main/java/com/linkedplanet/maven/plugin/upm/UploadPluginFileMojo.java @@ -33,6 +33,7 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; import java.io.File; @@ -44,6 +45,9 @@ public class UploadPluginFileMojo extends AbstractUpmMojo { private static final String REST_PATH_PLUGINS = "/rest/plugins/1.0"; + @Parameter(defaultValue = "${project}", readonly = true, required = true) + private MavenProject project; + @SuppressWarnings("unused") @Parameter(property = "pluginKey") private String pluginKey; @@ -56,6 +60,7 @@ public class UploadPluginFileMojo extends AbstractUpmMojo { @Parameter(property = "waitForSuccessMillis", defaultValue = "60000") private int waitForSuccessMillis; + @Override public void execute() throws MojoExecutionException { try (CloseableHttpClient httpClient = createHttpClient()) { @@ -64,18 +69,20 @@ public void execute() throws MojoExecutionException { getLog().info("UPM token: " + token); getLog().info("Uploading file: " + pluginFile + " ..."); - uploadFile(httpClient, token); + uploadPluginFile(httpClient, token); // wait for 5 seconds before checking plugin enabled state Thread.sleep(5000); - poll("Plugin installation", waitForSuccessMillis, () -> checkPluginEnabled(httpClient)); - - + Result result = pollResult("Plugin installation", waitForSuccessMillis, () -> verifyInstalledVersion(httpClient)); + if (result.isFailure()) { + throw new RuntimeException("The given plugin wasn't installed properly. Reason: " + result.toMessage()); + } } catch (Exception e) { throw new MojoExecutionException("Plugin installation error", e); } } + private String getUpmToken(CloseableHttpClient httpClient) throws Exception { String url = baseUrl.toString() + REST_PATH_PLUGINS + "/?os_authType=basic"; HttpHead request = new HttpHead(url); @@ -92,7 +99,7 @@ private String getUpmToken(CloseableHttpClient httpClient) throws Exception { } } - private void uploadFile(CloseableHttpClient httpClient, String token) throws Exception { + private void uploadPluginFile(CloseableHttpClient httpClient, String token) throws Exception { String url = baseUrl.toString() + REST_PATH_PLUGINS + "/?token=" + token; HttpPost request = new HttpPost(url); request.setHeader(getAuthHeader()); @@ -107,16 +114,27 @@ private void uploadFile(CloseableHttpClient httpClient, String token) throws Exc } } - private boolean checkPluginEnabled(CloseableHttpClient httpClient) { + private Result verifyInstalledVersion(CloseableHttpClient httpClient) { + String expectedVersion = project.getVersion(); HttpGet request = new HttpGet(baseUrl.toString() + REST_PATH_PLUGINS + '/' + pluginKey + "-key"); request.setHeader(getAuthHeader()); try (CloseableHttpResponse response = httpClient.execute(request)) { - JsonObject jsonObject = parseResponseAsJsonObject(response); - return jsonObject.getAsJsonPrimitive("enabled").getAsBoolean(); - + JsonObject pluginInfo = parseResponseAsJsonObject(response); + String installedVersion = pluginInfo.getAsJsonPrimitive("version").getAsString(); + boolean enabled = pluginInfo.getAsJsonPrimitive("enabled").getAsBoolean(); + if (!enabled) { + return new Result.Failure("The plugin is not enabled. Please check the log for installation errors."); + } + if (!installedVersion.equals(expectedVersion)) { + return new Result.Failure(String.format( + "Expected version %s but currently installed version is %s. Deinstall the currently installed version and try again.", + expectedVersion, + installedVersion)); + } } catch (Exception e) { - throw new RuntimeException(e); + return new Result.Failure("Failed to fetch plugin metadata from the platform. Ensure Confluence is reachable and try again.", e); } + return new Result.Success(); } }