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

Commit b14147e

Browse files
author
Rob Rudin
committed
#139 Deleting replicas first before deleting a database
1 parent 6daecf9 commit b14147e

File tree

6 files changed

+68
-0
lines changed

6 files changed

+68
-0
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ public class AppConfig {
9797
// Allows for creating a triggers database without a config file for one
9898
private boolean createTriggersDatabase = true;
9999

100+
// Controls whether replicas are deleted or not when undeploying a database
101+
private boolean deleteReplicas = true;
102+
100103
// As defined by the REST API
101104
private String modulePermissions = "rest-admin,read,rest-admin,update,rest-extension-user,execute";
102105

@@ -706,4 +709,12 @@ public String[] getResourceFilenamesToIgnore() {
706709
public void setResourceFilenamesToIgnore(String... resourceFilenamesToIgnore) {
707710
this.resourceFilenamesToIgnore = resourceFilenamesToIgnore;
708711
}
712+
713+
public boolean isDeleteReplicas() {
714+
return deleteReplicas;
715+
}
716+
717+
public void setDeleteReplicas(boolean deleteReplicas) {
718+
this.deleteReplicas = deleteReplicas;
719+
}
709720
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ public AppConfig newAppConfig() {
142142
c.setDatabaseNamesAndReplicaCounts(prop);
143143
}
144144

145+
/**
146+
* When undo is invoked on DeployDatabaseCommand (such as via mlUndeploy in ml-gradle), this controls whether
147+
* or not replicas are deleted first. Most of the time, you want this set to true (the default) as otherwise,
148+
* the database can't be deleted and the Management REST API will throw an error.
149+
*/
150+
prop = getProperty("mlDeleteReplicas");
151+
if (prop != null) {
152+
logger.info("Delete replicas when a database is deleted: " + prop);
153+
c.setDeleteReplicas(Boolean.parseBoolean(prop));
154+
}
155+
145156
/**
146157
* When a REST API server is created, the content database name will default to mlAppName-content. This property
147158
* can be used to override that name.

src/main/java/com/marklogic/appdeployer/command/databases/DeployDatabaseCommand.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public class DeployDatabaseCommand extends AbstractCommand implements UndoableCo
5757
*/
5858
private String forestDelete = "data";
5959

60+
private boolean deleteReplicas = true;
61+
6062
private int undoSortOrder;
6163

6264
public DeployDatabaseCommand() {
@@ -95,6 +97,7 @@ public void undo(CommandContext context) {
9597
if (payload != null) {
9698
DatabaseManager dbMgr = new DatabaseManager(context.getManageClient());
9799
dbMgr.setForestDelete(forestDelete);
100+
dbMgr.setDeleteReplicas(deleteReplicas);
98101
dbMgr.delete(payload);
99102
}
100103
}
@@ -244,4 +247,12 @@ public boolean isCreateForestsOnEachHost() {
244247
public void setCreateForestsOnEachHost(boolean createForestsOnEachHost) {
245248
this.createForestsOnEachHost = createForestsOnEachHost;
246249
}
250+
251+
public boolean isDeleteReplicas() {
252+
return deleteReplicas;
253+
}
254+
255+
public void setDeleteReplicas(boolean deleteReplicas) {
256+
this.deleteReplicas = deleteReplicas;
257+
}
247258
}

src/main/java/com/marklogic/mgmt/AbstractResourceManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,19 @@ public DeleteReceipt delete(String payload, String... resourceUrlParams) {
135135
} else {
136136
String path = getResourcePath(resourceId, resourceUrlParams);
137137
path = appendParamsAndValuesToPath(path, getDeleteResourceParams(payload));
138+
beforeDelete(resourceId, path, resourceUrlParams);
138139
deleteAtPath(path);
139140
return new DeleteReceipt(resourceId, path, true);
140141
}
141142
}
142143

144+
/**
145+
* Can be overridden by subclass to perform processing before deleteAtPath is invoked.
146+
*/
147+
protected void beforeDelete(String resourceId, String path, String... resourceUrlParams) {
148+
149+
}
150+
143151
/**
144152
* Convenience method for performing a delete once the correct path for the resource has been constructed.
145153
*

src/main/java/com/marklogic/mgmt/databases/DatabaseManager.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44

55
import com.marklogic.mgmt.AbstractResourceManager;
66
import com.marklogic.mgmt.ManageClient;
7+
import com.marklogic.mgmt.ManageConfig;
78
import com.marklogic.mgmt.forests.ForestManager;
9+
import com.marklogic.mgmt.forests.ForestStatus;
810
import com.marklogic.rest.util.Fragment;
911

1012
public class DatabaseManager extends AbstractResourceManager {
1113

1214
private String forestDelete = "data";
15+
private boolean deleteReplicas = true;
1316

1417
public DatabaseManager(ManageClient manageClient) {
1518
super(manageClient);
@@ -57,6 +60,20 @@ public void deleteByName(String databaseName) {
5760
delete(json);
5861
}
5962

63+
@Override
64+
protected void beforeDelete(String resourceId, String path, String... resourceUrlParams) {
65+
if (deleteReplicas) {
66+
logger.info("Deleting any replicas that exist for database: " + resourceId);
67+
ForestManager forestManager = new ForestManager(getManageClient());
68+
for (String forestId : getPrimaryForestIds(resourceId)) {
69+
ForestStatus status = forestManager.getForestStatus(forestId);
70+
if (status.isPrimary() && status.hasReplicas()) {
71+
forestManager.deleteReplicas(forestId);
72+
}
73+
}
74+
}
75+
}
76+
6077
/**
6178
* @param databaseNameOrId
6279
* @return the IDs of all forests - primary and replica - related to the database
@@ -115,4 +132,12 @@ protected String[] getDeleteResourceParams(String payload) {
115132
public void setForestDelete(String forestDelete) {
116133
this.forestDelete = forestDelete;
117134
}
135+
136+
public boolean isDeleteReplicas() {
137+
return deleteReplicas;
138+
}
139+
140+
public void setDeleteReplicas(boolean deleteReplicas) {
141+
this.deleteReplicas = deleteReplicas;
142+
}
118143
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public void allProperties() {
5858
p.setProperty("mlSimpleSsl", "anyvalue");
5959
p.setProperty("mlContentDatabaseName", "my-content-db");
6060
p.setProperty("mlModulesDatabaseName", "my-modules");
61+
p.setProperty("mlDeleteReplicas", "false");
6162
p.setProperty("mlGroupName", "other-group");
6263
p.setProperty("mlAppServicesPort", "8123");
6364
p.setProperty("mlReplaceTokensInModules", "false");
@@ -93,6 +94,7 @@ public void allProperties() {
9394
assertNotNull(config.getRestSslHostnameVerifier());
9495
assertEquals("my-content-db", config.getContentDatabaseName());
9596
assertEquals("my-modules", config.getModulesDatabaseName());
97+
assertFalse(config.isDeleteReplicas());
9698
assertEquals("other-group", config.getGroupName());
9799
assertEquals((Integer) 8123, config.getAppServicesPort());
98100
assertFalse(config.isReplaceTokensInModules());

0 commit comments

Comments
 (0)