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

Commit 96292d6

Browse files
committed
Merge branch 'feature/225-db-order' into dev
2 parents 71c2ee4 + 8992f93 commit 96292d6

File tree

10 files changed

+147
-64
lines changed

10 files changed

+147
-64
lines changed

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public class AppConfig {
134134
// Controls whether replicas are deleted or not when undeploying a database
135135
private boolean deleteReplicas = true;
136136

137-
private boolean sortRolesByDependencies = true;
137+
private boolean sortOtherDatabaseByDependencies = true;
138138

139139
// As defined by the REST API
140140
private String modulePermissions = "rest-admin,read,rest-admin,update,rest-extension-user,execute";
@@ -917,14 +917,6 @@ public void setAppServicesPassword(String appServicesPassword) {
917917
this.appServicesPassword = appServicesPassword;
918918
}
919919

920-
public boolean isSortRolesByDependencies() {
921-
return sortRolesByDependencies;
922-
}
923-
924-
public void setSortRolesByDependencies(boolean sortRolesByDependencies) {
925-
this.sortRolesByDependencies = sortRolesByDependencies;
926-
}
927-
928920
public boolean isDeleteTestModules() {
929921
return deleteTestModules;
930922
}
@@ -1186,4 +1178,12 @@ public Pattern getModuleFilenamesIncludePattern() {
11861178
public void setModuleFilenamesIncludePattern(Pattern moduleFilenamesIncludePattern) {
11871179
this.moduleFilenamesIncludePattern = moduleFilenamesIncludePattern;
11881180
}
1181+
1182+
public boolean isSortOtherDatabaseByDependencies() {
1183+
return sortOtherDatabaseByDependencies;
1184+
}
1185+
1186+
public void setSortOtherDatabaseByDependencies(boolean sortOtherDatabaseByDependencies) {
1187+
this.sortOtherDatabaseByDependencies = sortOtherDatabaseByDependencies;
1188+
}
11891189
}

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

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -655,16 +655,6 @@ public AppConfig newAppConfig() {
655655
c.setResourceFilenamesIncludePattern(Pattern.compile(prop));
656656
}
657657

658-
/**
659-
* Version 2.9.0 of ml-app-deployer, by default, sorts role files by reading each file and looking at the role
660-
* dependencies. You can disable this behavior by setting this property to false.
661-
*/
662-
prop = getProperty("mlSortRolesByDependencies");
663-
if (prop != null) {
664-
logger.info("Sort roles by dependencies: " + prop);
665-
c.setSortRolesByDependencies(Boolean.parseBoolean(prop));
666-
}
667-
668658
prop = getProperty("mlExcludeProperties");
669659
if (prop != null) {
670660
String[] values = prop.split(",");

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

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import com.marklogic.appdeployer.command.CommandContext;
44
import com.marklogic.client.ext.helper.LoggingObject;
5+
import com.marklogic.mgmt.api.API;
6+
import com.marklogic.mgmt.api.database.Database;
7+
import com.marklogic.mgmt.mapper.DefaultResourceMapper;
8+
import com.marklogic.mgmt.mapper.ResourceMapper;
59

610
import java.util.Comparator;
711

@@ -11,41 +15,44 @@
1115
*/
1216
public class DeployDatabaseCommandComparator extends LoggingObject implements Comparator<DeployDatabaseCommand> {
1317

14-
private CommandContext context;
15-
private boolean reverseOrder = false;
16-
17-
public DeployDatabaseCommandComparator(CommandContext context, boolean reverseOrder) {
18-
this.context = context;
19-
this.reverseOrder = reverseOrder;
20-
}
21-
22-
@Override
23-
public int compare(DeployDatabaseCommand o1, DeployDatabaseCommand o2) {
24-
String p1 = o1.buildPayload(context);
25-
String p2 = o2.buildPayload(context);
26-
if (p1 == null || p2 == null) {
27-
return 0;
28-
}
29-
30-
boolean b1 = payloadDependsOnOtherDatabase(p1);
31-
boolean b2 = payloadDependsOnOtherDatabase(p2);
32-
if (b1 && !b2) {
33-
return reverseOrder ? -1 : 1;
34-
}
35-
if (b2 && !b1) {
36-
return reverseOrder ? 1 : -1;
37-
}
38-
return 0;
39-
}
40-
41-
/**
42-
* If the payload has a triggers-database or schemas-database, we consider it to depend on some other database. We
43-
* don't check for a security database yet, as it's very rare to use a custom security database.
44-
*
45-
* @param payload
46-
* @return
47-
*/
48-
protected boolean payloadDependsOnOtherDatabase(String payload) {
49-
return payload.contains("triggers-database") || payload.contains("schema-database");
50-
}
18+
private CommandContext context;
19+
private boolean reverseOrder = false;
20+
private ResourceMapper resourceMapper;
21+
22+
public DeployDatabaseCommandComparator(CommandContext context, boolean reverseOrder) {
23+
this.context = context;
24+
this.reverseOrder = reverseOrder;
25+
this.resourceMapper = new DefaultResourceMapper(new API(null));
26+
}
27+
28+
@Override
29+
public int compare(DeployDatabaseCommand o1, DeployDatabaseCommand o2) {
30+
String p1 = o1.buildPayload(context);
31+
String p2 = o2.buildPayload(context);
32+
if (p1 == null || p2 == null) {
33+
return 0;
34+
}
35+
36+
Database db1 = null, db2 = null;
37+
try {
38+
db1 = resourceMapper.readResource(p1, Database.class);
39+
db2 = resourceMapper.readResource(p2, Database.class);
40+
} catch (Exception ex) {
41+
logger.warn("Unable to map database payload to Database object, " +
42+
"will not be able to determine the right order in which to deploy this database; cause: " + ex.getMessage());
43+
return 0;
44+
}
45+
46+
// This should never happen, but just in case
47+
if (db1 == null || db2 == null) {
48+
return 0;
49+
}
50+
51+
if (db1.dependsOnDatabase(db2)) {
52+
return reverseOrder ? -1 : 1;
53+
} else if (db2.dependsOnDatabase(db1)) {
54+
return reverseOrder ? 1 : -1;
55+
}
56+
return 0;
57+
}
5158
}

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
* uncommon to need to create additional databases (and perhaps REST API servers to go with them).
1515
* <p>
1616
* A key aspect of this class is its attempt to deploy/undeploy databases in the correct order. For each database file
17-
* that it finds that's not one of the default ones, a DeployDatabaseCommand will be created. All of those commands will
18-
* then be sorted based on the presence of "triggers-database" or "schema-database" within the payload for the command.
17+
* that it finds that's not one of the default ones, a DeployDatabaseCommand will be created. These commands are then
18+
* sorted based on their dependencies between each other (a database can depend on another database for schemas, triggers,
19+
* or security).
1920
* <p>
2021
* If the above strategy doesn't work for you, you can always resort to naming your database files to control the order
21-
* that they're processed in.
22+
* that they're processed in. Be sure to set "setSortOtherDatabasesByDependencies" to false in the AppConfig object that
23+
* is passed in via a CommandContext to disable the sorting that this command will otherwise perform.
2224
* </p>
2325
*/
2426
public class DeployOtherDatabasesCommand extends AbstractUndoableCommand {
@@ -48,7 +50,12 @@ public void execute(CommandContext context) {
4850
}
4951

5052
protected void sortCommandsBeforeExecute(List<DeployDatabaseCommand> list, CommandContext context) {
51-
Collections.sort(list, new DeployDatabaseCommandComparator(context, false));
53+
if (context.getAppConfig().isSortOtherDatabaseByDependencies()) {
54+
Collections.sort(list, new DeployDatabaseCommandComparator(context, false));
55+
}
56+
else {
57+
logger.info("Not sorting databases by dependencies; they will be sorted based on their filename instead");
58+
}
5259
}
5360

5461
@Override

src/main/java/com/marklogic/mgmt/api/database/Database.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,22 @@ public void detach(String forestName) {
166166
}
167167
}
168168

169+
/**
170+
*
171+
* @param other
172+
* @return true if the name of the other database equals the name of this database object's schema database,
173+
* triggers database, or security database
174+
*/
175+
public boolean dependsOnDatabase(Database other) {
176+
String otherName = other.getDatabaseName();
177+
178+
if (otherName == null) {
179+
return false;
180+
}
181+
182+
return otherName.equals(schemaDatabase) || otherName.equals(triggersDatabase) || otherName.equals(securityDatabase);
183+
}
184+
169185
public String getDatabaseName() {
170186
return databaseName;
171187
}

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,6 @@ public void allProperties() {
172172
p.setProperty("mlDatabaseReplicaFastDataDirectories", "Documents,/fast/replicas,Security,/fast/security/replicas");
173173
p.setProperty("mlDatabaseReplicaLargeDataDirectories", "Documents,/large/replicas,Security,/large/security/replicas");
174174

175-
p.setProperty("mlSortRolesByDependencies", "false");
176-
177175
sut = new DefaultAppConfigFactory(new SimplePropertySource(p));
178176
AppConfig config = sut.newAppConfig();
179177

@@ -314,8 +312,6 @@ public void allProperties() {
314312
map = config.getDatabaseReplicaLargeDataDirectories();
315313
assertEquals("/large/replicas", map.get("Documents"));
316314
assertEquals("/large/security/replicas", map.get("Security"));
317-
318-
assertFalse(config.isSortRolesByDependencies());
319315
}
320316

321317
/**
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.marklogic.appdeployer.command.databases;
2+
3+
import com.marklogic.appdeployer.AbstractAppDeployerTest;
4+
import com.marklogic.appdeployer.ConfigDir;
5+
import com.marklogic.mgmt.resource.databases.DatabaseManager;
6+
import org.junit.After;
7+
import org.junit.Test;
8+
9+
import java.io.File;
10+
11+
public class DeployDatabasesInOrderTest extends AbstractAppDeployerTest {
12+
13+
@After
14+
public void teardown() {
15+
undeploySampleApp();
16+
17+
DatabaseManager mgr = new DatabaseManager(manageClient);
18+
assertFalse(mgr.exists("sample-app-A"));
19+
assertFalse(mgr.exists("sample-app-B"));
20+
assertFalse(mgr.exists("sample-app-C"));
21+
}
22+
23+
/**
24+
* Tests 3 files that have filenames that would lead them to be processed in the wrong order if the command
25+
* doesn't sort them correctly.
26+
*/
27+
@Test
28+
public void test() {
29+
appConfig.setConfigDir(new ConfigDir(new File("src/test/resources/sample-app/databases-in-order")));
30+
initializeAppDeployer(new DeployOtherDatabasesCommand(1));
31+
deploySampleApp();
32+
33+
DatabaseManager mgr = new DatabaseManager(manageClient);
34+
assertTrue(mgr.exists("sample-app-A"));
35+
assertTrue(mgr.exists("sample-app-B"));
36+
assertTrue(mgr.exists("sample-app-C"));
37+
}
38+
39+
@Test
40+
public void notSortingProducesFailure() {
41+
appConfig.setConfigDir(new ConfigDir(new File("src/test/resources/sample-app/databases-in-order")));
42+
appConfig.setSortOtherDatabaseByDependencies(false);
43+
initializeAppDeployer(new DeployOtherDatabasesCommand(1));
44+
45+
try {
46+
deploySampleApp();
47+
fail("Deploy should have failed because the databases were not sorted based on their dependencies");
48+
} catch (Exception ex) {
49+
logger.info("Caught expected exception: " + ex.getMessage());
50+
}
51+
}
52+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"database-name": "%%NAME%%-A",
3+
"schema-database": "%%NAME%%-C",
4+
"triggers-database": "%%NAME%%-B"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"database-name": "%%NAME%%-B",
3+
"schema-database": "%%NAME%%-C",
4+
"triggers-database": "Triggers"
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"database-name": "%%NAME%%-C",
3+
"schema-database": "Schemas",
4+
"triggers-database": "Triggers"
5+
}

0 commit comments

Comments
 (0)