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

Commit b767c6e

Browse files
committed
#172 Sorting roles multiple times if needed
1 parent 5389668 commit b767c6e

File tree

11 files changed

+99
-9
lines changed

11 files changed

+99
-9
lines changed

src/main/java/com/marklogic/appdeployer/command/security/DeployRolesCommand.java

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
public class DeployRolesCommand extends AbstractResourceCommand {
1818

19+
private int maxSortAttempts = 100;
20+
1921
public DeployRolesCommand() {
2022
setExecuteSortOrder(SortOrderConstants.DEPLOY_ROLES);
2123
setUndoSortOrder(SortOrderConstants.DELETE_ROLES);
@@ -72,7 +74,27 @@ protected List<RoleFile> sortFilesBasedOnRoleDependencies(File[] files, CommandC
7274
roleFiles.add(rf);
7375
}
7476

75-
return sortRoleFiles(roleFiles);
77+
return keepSortingRoleFilesUntilOrderDoesntChange(roleFiles);
78+
}
79+
80+
/**
81+
* Some sets of role files require multiple sorts until the order no longer changes. The maxSortAttempts class
82+
* attribute controls how many times this command will try to sort the roles.
83+
*
84+
* @param roleFiles
85+
* @return
86+
*/
87+
protected List<RoleFile> keepSortingRoleFilesUntilOrderDoesntChange(List<RoleFile> roleFiles) {
88+
List<RoleFile> previousRoleFiles;
89+
int counter = 0;
90+
do {
91+
previousRoleFiles = roleFiles;
92+
roleFiles = new ArrayList<>();
93+
roleFiles.addAll(previousRoleFiles);
94+
roleFiles = sortRoleFiles(roleFiles);
95+
counter++;
96+
} while (!previousRoleFiles.equals(roleFiles) && counter < maxSortAttempts);
97+
return roleFiles;
7698
}
7799

78100
protected List<RoleFile> sortRoleFiles(List<RoleFile> roleFiles) {
@@ -90,8 +112,15 @@ protected ResourceManager getResourceManager(CommandContext context) {
90112
return new RoleManager(context.getManageClient());
91113
}
92114

115+
public void setMaxSortAttempts(int maxSortAttempts) {
116+
this.maxSortAttempts = maxSortAttempts;
117+
}
93118
}
94119

120+
/**
121+
* Simple data structure for associating a File that defines a role, and the parsed Role that is used for
122+
* sorting the role files.
123+
*/
95124
class RoleFile {
96125

97126
File file;
@@ -103,6 +132,15 @@ public RoleFile(File file) {
103132
this.role.setRole(new ArrayList<String>());
104133
}
105134

135+
@Override
136+
public int hashCode() {
137+
return role.getRoleName().hashCode();
138+
}
139+
140+
@Override
141+
public boolean equals(Object obj) {
142+
return role.getRoleName().equals(((RoleFile)obj).role.getRoleName());
143+
}
106144
}
107145

108146
/**
@@ -139,16 +177,13 @@ public RoleFileComparator(List<RoleFile> roleFiles) {
139177

140178
@Override
141179
public int compare(RoleFile o1, RoleFile o2) {
142-
if (o1 == null && o2 != null) {
143-
return 1;
144-
}
145-
if (o2 == null) {
146-
return -1;
180+
if (o1.role.getRole().isEmpty() && o2.role.getRole().isEmpty()) {
181+
return 0;
147182
}
148-
if (o1.role.getRole() == null || o1.role.getRole().isEmpty()) {
183+
if (o1.role.getRole().isEmpty()) {
149184
return -1;
150185
}
151-
if (o2.role.getRole() == null || o2.role.getRole().isEmpty()) {
186+
if (o2.role.getRole().isEmpty()) {
152187
return 1;
153188
}
154189
if (o2.role.getRole().contains(o1.role.getRoleName())) {

src/test/java/com/marklogic/appdeployer/command/security/DeployRolesWithDependenciesTest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.marklogic.appdeployer.AbstractAppDeployerTest;
44
import com.marklogic.appdeployer.command.CommandContext;
55
import com.marklogic.mgmt.security.RoleManager;
6-
import org.junit.Before;
76
import org.junit.Test;
87

98
import java.io.File;
@@ -29,6 +28,29 @@ public void testSorting() {
2928
assertEquals("role0.json", files[5].getName());
3029
}
3130

31+
/**
32+
* This scenario features role files that must be sorted multiple times in order for them to be in the correct
33+
* order.
34+
*/
35+
@Test
36+
public void testEvenMoreRoles() {
37+
appConfig.getConfigDir().setBaseDir(new File("src/test/resources/sample-app/even-more-roles-with-dependencies"));
38+
39+
DeployRolesCommand command = new DeployRolesCommand();
40+
File[] files = command.listFilesInDirectory(appConfig.getConfigDir().getRolesDir(),
41+
new CommandContext(appConfig, manageClient, null));
42+
43+
assertEquals("abc-login-role.json", files[0].getName());
44+
assertEquals("abc-ui-developer.json", files[1].getName());
45+
assertEquals("xyz-reader.json", files[2].getName());
46+
assertEquals("xyz-writer.json", files[3].getName());
47+
assertEquals("xyz-admin.json", files[4].getName());
48+
assertEquals("abc-sss-ui-role.json", files[5].getName());
49+
assertEquals("abc-ui-offline-user.json", files[6].getName());
50+
assertEquals("abc-ui-offline-admin.json", files[7].getName());
51+
assertEquals("abc-ui-admin.json", files[8].getName());
52+
}
53+
3254
/**
3355
* This scenario tests that when two roles are next to each other with different dependencies - role1 and role2 -
3456
* that we figure out that role1 has a dependency on a role closest to the end of the current list of files.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"role-name" : "abc-login-role"
3+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"role-name" : "abc-sss-ui-role",
3+
"role" : [ "xyz-reader", "xyz-writer" ]
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"role-name" : "abc-ui-admin",
3+
"role" : [ "abc-ui-offline-admin", "flexrep-admin" ]
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"role-name" : "abc-ui-developer"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"role-name" : "abc-ui-offline-admin",
3+
"role" : [ "abc-ui-offline-user" ]
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"role-name" : "abc-ui-offline-user",
3+
"role" : [ "abc-sss-ui-role" ]
4+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"role-name" : "xyz-admin",
3+
"role" : [ "xyz-reader", "xyz-writer", "qconsole-user" ]
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"role-name" : "xyz-reader"
3+
}

0 commit comments

Comments
 (0)