Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit f532cae

Browse files
committed
#205 New properties for ignoring errors on deploy/undeploy
1 parent 4725718 commit f532cae

File tree

5 files changed

+172
-26
lines changed

5 files changed

+172
-26
lines changed

src/main/java/com/marklogic/appdeployer/AppConfig.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ public class AppConfig {
6565
private String name = DEFAULT_APP_NAME;
6666
private String host = DEFAULT_HOST;
6767

68+
private boolean catchDeployExceptions = false;
69+
private boolean catchUndeployExceptions = false;
70+
6871
// Used to construct DatabaseClient instances based on inputs defined in this class
6972
private ConfiguredDatabaseClientFactory configuredDatabaseClientFactory = new DefaultConfiguredDatabaseClientFactory();
7073

@@ -1027,4 +1030,20 @@ public Map<String, String> getDatabaseReplicaLargeDataDirectories() {
10271030
public void setDatabaseReplicaLargeDataDirectories(Map<String, String> databaseReplicaLargeDataDirectories) {
10281031
this.databaseReplicaLargeDataDirectories = databaseReplicaLargeDataDirectories;
10291032
}
1033+
1034+
public boolean isCatchDeployExceptions() {
1035+
return catchDeployExceptions;
1036+
}
1037+
1038+
public void setCatchDeployExceptions(boolean catchDeployExceptions) {
1039+
this.catchDeployExceptions = catchDeployExceptions;
1040+
}
1041+
1042+
public boolean isCatchUndeployExceptions() {
1043+
return catchUndeployExceptions;
1044+
}
1045+
1046+
public void setCatchUndeployExceptions(boolean catchUndeployExceptions) {
1047+
this.catchUndeployExceptions = catchUndeployExceptions;
1048+
}
10301049
}

src/main/java/com/marklogic/appdeployer/DefaultAppConfigFactory.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ public AppConfig newAppConfig() {
2525

2626
String prop = null;
2727

28+
prop = getProperty("mlCatchDeployExceptions");
29+
if (prop != null) {
30+
logger.info("Catch deploy exceptions: " + prop);
31+
c.setCatchDeployExceptions(Boolean.parseBoolean(prop));
32+
}
33+
34+
prop = getProperty("mlCatchUndeployExceptions");
35+
if (prop != null) {
36+
logger.info("Catch undeploy exceptions: " + prop);
37+
c.setCatchUndeployExceptions(Boolean.parseBoolean(prop));
38+
}
39+
2840
/**
2941
* mlUsername and mlPassword are used as the default username/password for the admin, rest-admin, and manage-admin
3042
* roles when there isn't a specific username/password combo for those roles.

src/main/java/com/marklogic/appdeployer/impl/AbstractAppDeployer.java

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,12 @@ public AbstractAppDeployer(ManageClient manageClient, AdminManager adminManager)
4545
*/
4646
protected abstract List<Command> getCommands();
4747

48-
public void deploy(AppConfig appConfig) {
48+
/**
49+
* Calls execute on each of the configured commands.
50+
*
51+
* @param appConfig
52+
*/
53+
public void deploy(AppConfig appConfig) {
4954
logger.info(format("Deploying app %s with config dir of: %s\n", appConfig.getName(), appConfig.getConfigDir()
5055
.getBaseDir().getAbsolutePath()));
5156

@@ -54,35 +59,67 @@ public void deploy(AppConfig appConfig) {
5459

5560
CommandContext context = new CommandContext(appConfig, manageClient, adminManager);
5661

57-
String[] filenamesToIgnore = appConfig.getResourceFilenamesToIgnore();
58-
Pattern excludePattern = appConfig.getResourceFilenamesExcludePattern();
59-
Pattern includePattern = appConfig.getResourceFilenamesIncludePattern();
60-
6162
for (Command command : commands) {
6263
String name = command.getClass().getName();
6364
logger.info(format("Executing command [%s] with sort order [%d]", name, command.getExecuteSortOrder()));
64-
65-
if (command instanceof AbstractCommand) {
66-
AbstractCommand abstractCommand = (AbstractCommand)command;
67-
if (filenamesToIgnore != null) {
68-
abstractCommand.setFilenamesToIgnore(filenamesToIgnore);
69-
}
70-
if (excludePattern != null) {
71-
abstractCommand.setResourceFilenamesExcludePattern(excludePattern);
72-
}
73-
if (includePattern != null) {
74-
abstractCommand.setResourceFilenamesIncludePattern(includePattern);
75-
}
76-
}
77-
78-
command.execute(context);
65+
prepareCommand(command, context);
66+
executeCommand(command, context);
7967
logger.info(format("Finished executing command [%s]\n", name));
8068
}
8169

8270
logger.info(format("Deployed app %s", appConfig.getName()));
8371
}
8472

85-
public void undeploy(AppConfig appConfig) {
73+
/**
74+
* Prepare the given command before either execute or undo is called on it.
75+
*
76+
* @param command
77+
* @param context
78+
*/
79+
protected void prepareCommand(Command command, CommandContext context) {
80+
if (command instanceof AbstractCommand) {
81+
AppConfig appConfig = context.getAppConfig();
82+
String[] filenamesToIgnore = appConfig.getResourceFilenamesToIgnore();
83+
Pattern excludePattern = appConfig.getResourceFilenamesExcludePattern();
84+
Pattern includePattern = appConfig.getResourceFilenamesIncludePattern();
85+
86+
AbstractCommand abstractCommand = (AbstractCommand)command;
87+
if (filenamesToIgnore != null) {
88+
abstractCommand.setFilenamesToIgnore(filenamesToIgnore);
89+
}
90+
if (excludePattern != null) {
91+
abstractCommand.setResourceFilenamesExcludePattern(excludePattern);
92+
}
93+
if (includePattern != null) {
94+
abstractCommand.setResourceFilenamesIncludePattern(includePattern);
95+
}
96+
}
97+
}
98+
99+
/**
100+
* Executes the command, catching an exception if desired.
101+
*
102+
* @param command
103+
* @param context
104+
*/
105+
protected void executeCommand(Command command, CommandContext context) {
106+
try {
107+
command.execute(context);
108+
} catch (RuntimeException ex) {
109+
if (context.getAppConfig().isCatchDeployExceptions()) {
110+
logger.error(format("Command [%s] threw exception that was caught; cause: %s", command.getClass().getName(), ex.getMessage()), ex);
111+
} else {
112+
throw ex;
113+
}
114+
}
115+
}
116+
117+
/**
118+
* Calls undo on each of the configured commands that implements the UndoableCommand interface.
119+
*
120+
* @param appConfig
121+
*/
122+
public void undeploy(AppConfig appConfig) {
86123
logger.info(format("Undeploying app %s with config dir: %s\n", appConfig.getName(), appConfig.getConfigDir()
87124
.getBaseDir().getAbsolutePath()));
88125

@@ -96,16 +133,36 @@ public void undeploy(AppConfig appConfig) {
96133
}
97134

98135
Collections.sort(undoableCommands, new UndoComparator());
136+
CommandContext context = new CommandContext(appConfig, manageClient, adminManager);
99137

100138
for (UndoableCommand command : undoableCommands) {
101139
String name = command.getClass().getName();
102140
logger.info(format("Undoing command [%s] with sort order [%d]", name, command.getUndoSortOrder()));
103-
command.undo(new CommandContext(appConfig, manageClient, adminManager));
141+
prepareCommand(command, context);
142+
undoCommand(command, context);
104143
logger.info(format("Finished undoing command [%s]\n", name));
105144
}
106145

107146
logger.info(format("Undeployed app %s", appConfig.getName()));
108147
}
148+
149+
/**
150+
* Calls undo on the command, catching an exception if desired.
151+
*
152+
* @param command
153+
* @param context
154+
*/
155+
protected void undoCommand(UndoableCommand command, CommandContext context) {
156+
try {
157+
command.undo(context);
158+
} catch (RuntimeException ex) {
159+
if (context.getAppConfig().isCatchUndeployExceptions()) {
160+
logger.error(format("Command [%s] threw exception that was caught; cause: %s", command.getClass().getName(), ex.getMessage()), ex);
161+
} else {
162+
throw ex;
163+
}
164+
}
165+
}
109166
}
110167

111168
class ExecuteComparator implements Comparator<Command> {

src/test/java/com/marklogic/appdeployer/DefaultAppConfigFactoryTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,14 @@ public void appServicesDiffersFromRestAdmin() {
7272
assertEquals("appword", config.getAppServicesPassword());
7373
}
7474

75-
/**
76-
* As of 2.2.0.
77-
*/
7875
@Test
7976
public void allProperties() {
8077
Properties p = new Properties();
81-
p.setProperty("mlHost", "prophost");
78+
79+
p.setProperty("mlCatchDeployExceptions", "true");
80+
p.setProperty("mlCatchUndeployExceptions", "true");
81+
82+
p.setProperty("mlHost", "prophost");
8283
p.setProperty("mlAppName", "propname");
8384
p.setProperty("mlNoRestServer", "true");
8485
p.setProperty("mlUsername", "propuser1");
@@ -160,6 +161,9 @@ public void allProperties() {
160161
sut = new DefaultAppConfigFactory(new SimplePropertySource(p));
161162
AppConfig config = sut.newAppConfig();
162163

164+
assertTrue(config.isCatchDeployExceptions());
165+
assertTrue(config.isCatchUndeployExceptions());
166+
163167
assertEquals("prophost", config.getHost());
164168
assertEquals("propname", config.getName());
165169
assertTrue(config.isNoRestServer());
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.marklogic.appdeployer.impl;
2+
3+
import com.marklogic.appdeployer.AbstractAppDeployerTest;
4+
import com.marklogic.appdeployer.command.databases.DeployContentDatabasesCommand;
5+
import com.marklogic.appdeployer.command.restapis.DeployRestApiServersCommand;
6+
import org.junit.Test;
7+
8+
import java.io.File;
9+
10+
public class IgnoreCommandErrorTest extends AbstractAppDeployerTest {
11+
12+
@Test
13+
public void ignoreErrorOnUndeploy() {
14+
appConfig.getConfigDir().setBaseDir(new File("src/test/resources/sample-app/db-only-config"));
15+
16+
initializeAppDeployer(new DeployRestApiServersCommand(true), new DeployContentDatabasesCommand(1));
17+
deploySampleApp();
18+
19+
try {
20+
try {
21+
initializeAppDeployer(new DeployContentDatabasesCommand());
22+
appDeployer.undeploy(appConfig);
23+
fail("Undeploying should have failed because the database is attached to the REST server");
24+
} catch (RuntimeException ex) {
25+
logger.info("Caught expected exception: " + ex.getMessage());
26+
}
27+
28+
appConfig.setCatchUndeployExceptions(true);
29+
// This should just log the error and not throw one
30+
appDeployer.undeploy(appConfig);
31+
} finally {
32+
initializeAppDeployer(new DeployRestApiServersCommand(true), new DeployContentDatabasesCommand());
33+
appDeployer.undeploy(appConfig);
34+
}
35+
}
36+
37+
@Test
38+
public void ignoreErrorOnDeploy() {
39+
initializeAppDeployer(new DeployContentDatabasesCommand(1));
40+
41+
try {
42+
deploySampleApp();
43+
fail("Deploying should have failed because the content database refers to a non-existent schemas database");
44+
} catch (Exception ex) {
45+
logger.info("Caught expected exception: " + ex.getMessage());
46+
}
47+
48+
appConfig.setCatchDeployExceptions(true);
49+
// The error should just be logged
50+
deploySampleApp();
51+
52+
// Nothing to undeploy!
53+
}
54+
}

0 commit comments

Comments
 (0)