diff --git a/marklogic-data-hub/src/main/java/com/marklogic/hub/deploy/HubAppDeployer.java b/marklogic-data-hub/src/main/java/com/marklogic/hub/deploy/HubAppDeployer.java index 2bbacd7370..8d253e85f9 100644 --- a/marklogic-data-hub/src/main/java/com/marklogic/hub/deploy/HubAppDeployer.java +++ b/marklogic-data-hub/src/main/java/com/marklogic/hub/deploy/HubAppDeployer.java @@ -27,11 +27,9 @@ import com.marklogic.mgmt.ManageClient; import com.marklogic.mgmt.admin.AdminManager; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - +/** + * Extends ml-app-deployer's SimpleAppDeployer to provide progress reporting. + */ public class HubAppDeployer extends SimpleAppDeployer { private ManageClient manageClient; @@ -40,6 +38,9 @@ public class HubAppDeployer extends SimpleAppDeployer { // this is for the telemetry hook to use mlUsername/mlPassword private DatabaseClient databaseClient; + // Keeps track of completion percentage + private int completed = 0; + public HubAppDeployer(ManageClient manageClient, AdminManager adminManager, HubDeployStatusListener listener, DatabaseClient databaseClient) { super(manageClient, adminManager); this.manageClient = manageClient; @@ -50,94 +51,54 @@ public HubAppDeployer(ManageClient manageClient, AdminManager adminManager, HubD @Override public void deploy(AppConfig appConfig) { - logger.info(format("Deploying app %s with config dir of: %s\n", appConfig.getName(), appConfig.getFirstConfigDir() - .getBaseDir().getAbsolutePath())); - - List commands = getCommands(); - Collections.sort(commands, new Comparator() { - @Override - public int compare(Command o1, Command o2) { - return o1.getExecuteSortOrder().compareTo(o2.getExecuteSortOrder()); - } - - @Override - public boolean equals(Object obj) { - return this.equals(obj); - } - }); + this.completed = 0; - CommandContext context = new CommandContext(appConfig, manageClient, adminManager); - - int count = commands.size(); - int completed = 0; onStatusChange(0, "Installing..."); - for (Command command : commands) { - String name = command.getClass().getName(); - logger.info(format("Executing command [%s] with sort order [%d]", name, command.getExecuteSortOrder())); - float percent = ((float)completed / (float)count) * 100; - onStatusChange((int)percent, format("[Step %d of %d] %s", completed + 1, count, name)); - command.execute(context); - logger.info(format("Finished executing command [%s]\n", name)); - completed++; - } + super.deploy(appConfig); onStatusChange(100, "Installation Complete"); - //Below is telemetry metric code for tracking successful dhf installs - //TODO: when more uses of telemetry are defined, change this to a more e-node based method - ServerEvaluationCall eval = databaseClient.newServerEval(); - String query = "xdmp:feature-metric-increment(xdmp:feature-metric-register(\"datahub.core.install.count\"))"; - try { - eval.xquery(query).eval().close(); - } - catch(FailedRequestException e) { - logger.error("Failed to increment feature metric telemetry count: " + query, e); - e.printStackTrace(); + if (databaseClient != null) { + //Below is telemetry metric code for tracking successful dhf installs + //TODO: when more uses of telemetry are defined, change this to a more e-node based method + ServerEvaluationCall eval = databaseClient.newServerEval(); + String query = "xdmp:feature-metric-increment(xdmp:feature-metric-register(\"datahub.core.install.count\"))"; + try { + eval.xquery(query).eval().close(); + } catch (FailedRequestException e) { + logger.error("Failed to increment feature metric telemetry count: " + query, e); + e.printStackTrace(); + } } - logger.info(format("Deployed app %s", appConfig.getName())); } @Override - public void undeploy(AppConfig appConfig) { - logger.info(format("Undeploying app %s with config dir: %s\n", appConfig.getName(), appConfig.getFirstConfigDir() - .getBaseDir().getAbsolutePath())); - - List commands = getCommands(); - - List undoableCommands = new ArrayList<>(); - for (Command command : commands) { - if (command instanceof UndoableCommand) { - undoableCommands.add((UndoableCommand) command); - } - } - - Collections.sort(undoableCommands, new Comparator() { - @Override - public int compare(UndoableCommand o1, UndoableCommand o2) { - return o1.getUndoSortOrder().compareTo(o2.getUndoSortOrder()); - } + protected void executeCommand(Command command, CommandContext context) { + reportStatus(command); + super.executeCommand(command, context); + completed++; + } - @Override - public boolean equals(Object obj) { - return this.equals(obj); - } - }); + @Override + public void undeploy(AppConfig appConfig) { + this.completed = 0; - int count = undoableCommands.size(); - int completed = 0; onStatusChange(0, "Uninstalling..."); - - for (UndoableCommand command : undoableCommands) { - String name = command.getClass().getName(); - logger.info(format("Undoing command [%s] with sort order [%d]", name, command.getUndoSortOrder())); - float percent = ((float)completed / (float)count) * 100; - onStatusChange((int)percent, format("[Step %d of %d] %s", completed + 1, count, name)); - command.undo(new CommandContext(appConfig, manageClient, adminManager)); - logger.info(format("Finished undoing command [%s]\n", name)); - completed++; - } + super.undeploy(appConfig); onStatusChange(100, "Installation Complete"); + } + + @Override + protected void undoCommand(UndoableCommand command, CommandContext context) { + reportStatus(command); + super.undoCommand(command, context); + completed++; + } - logger.info(format("Undeployed app %s", appConfig.getName())); + protected void reportStatus(Command command) { + int count = getCommands().size(); + float percent = ((float) completed / (float) count) * 100; + String name = command.getClass().getName(); + onStatusChange((int) percent, format("[Step %d of %d] %s", completed + 1, count, name)); } private void onStatusChange(int percentComplete, String message) { diff --git a/marklogic-data-hub/src/test/java/com/marklogic/hub/deploy/HubAppDeployerTest.java b/marklogic-data-hub/src/test/java/com/marklogic/hub/deploy/HubAppDeployerTest.java new file mode 100644 index 0000000000..1ba61cc573 --- /dev/null +++ b/marklogic-data-hub/src/test/java/com/marklogic/hub/deploy/HubAppDeployerTest.java @@ -0,0 +1,83 @@ +package com.marklogic.hub.deploy; + +import com.marklogic.appdeployer.AppConfig; +import com.marklogic.appdeployer.command.Command; +import com.marklogic.appdeployer.command.CommandContext; +import com.marklogic.hub.deploy.util.HubDeployStatusListener; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import static org.junit.jupiter.api.Assertions.*; + +public class HubAppDeployerTest { + + @Test + public void test() { + List messages = new ArrayList<>(); + + List commands = new ArrayList<>(); + commands.add(new TestCommand(20, messages)); + commands.add(new TestCommand(30, messages)); + commands.add(new TestCommand(10, messages)); + + TestListener testListener = new TestListener(); + + HubAppDeployer appDeployer = new HubAppDeployer(null, null, testListener, null); + appDeployer.setCommands(commands); + appDeployer.deploy(new AppConfig()); + + // Verify commands were executed in correct order + assertEquals("My sort order: 10", messages.get(0)); + assertEquals("My sort order: 20", messages.get(1)); + assertEquals("My sort order: 30", messages.get(2)); + + // Verify correct status messages were passed to our listener + System.out.println(testListener.getMessages()); + assertEquals("0:Installing...", testListener.getMessages().get(0)); + assertEquals("0:[Step 1 of 3] com.marklogic.hub.deploy.TestCommand", testListener.getMessages().get(1)); + assertEquals("33:[Step 2 of 3] com.marklogic.hub.deploy.TestCommand", testListener.getMessages().get(2)); + assertEquals("66:[Step 3 of 3] com.marklogic.hub.deploy.TestCommand", testListener.getMessages().get(3)); + assertEquals("100:Installation Complete", testListener.getMessages().get(4)); + } +} + +class TestCommand implements Command { + + private int sortOrder; + private List messages; + + public TestCommand(int sortOrder, List messages) { + this.sortOrder = sortOrder; + this.messages = messages; + } + + @Override + public void execute(CommandContext context) { + messages.add("My sort order: " + sortOrder); + } + + @Override + public Integer getExecuteSortOrder() { + return sortOrder; + } +} + +class TestListener implements HubDeployStatusListener { + + private List messages = new ArrayList<>(); + + @Override + public void onStatusChange(int percentComplete, String message) { + messages.add(percentComplete + ":" + message); + } + + @Override + public void onError() { + + } + + public List getMessages() { + return messages; + } +}