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

Commit 9d36ea8

Browse files
committed
#255 Can now assign hosts to groups
1 parent 9a426ee commit 9d36ea8

File tree

13 files changed

+366
-21
lines changed

13 files changed

+366
-21
lines changed

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ public class AppConfig {
154154

155155
private Map<String, Set<String>> databaseHosts;
156156
private Map<String, Set<String>> databaseGroups;
157-
157+
private Map<String, String> hostGroups;
158+
158159
// Data/fast/large directories for default forests
159160
private String forestDataDirectory;
160161
private String forestFastDataDirectory;
@@ -1126,16 +1127,24 @@ public void setIncludeProperties(String... includeProperties) {
11261127

11271128
public String[] getIncludeProperties() {
11281129
return this.includeProperties;
1129-
}
1130+
}
11301131

1131-
public Map<String, Set<String>> getDatabaseGroups() {
1132+
public Map<String, Set<String>> getDatabaseGroups() {
11321133
return databaseGroups;
11331134
}
11341135

11351136
public void setDatabaseGroups(Map<String, Set<String>> databaseGroups) {
11361137
this.databaseGroups = databaseGroups;
11371138
}
11381139

1140+
public Map<String, String> getHostGroups() {
1141+
return hostGroups;
1142+
}
1143+
1144+
public void setHostGroups(Map<String, String> hostGroups) {
1145+
this.hostGroups = hostGroups;
1146+
}
1147+
11391148
public List<ConfigDir> getConfigDirs() {
11401149
return configDirs;
11411150
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,12 @@ public AppConfig newAppConfig() {
323323
c.setDatabaseGroups(buildSetMapFromDelimitedString(prop));
324324
}
325325

326+
prop = getProperty("mlHostGroups");
327+
if (prop != null) {
328+
logger.info("Hosts will be assigned to Groups: " + prop);
329+
c.setHostGroups(buildMapFromCommaDelimitedString(prop));
330+
}
331+
326332
prop = getProperty("mlDatabaseHosts");
327333
if (prop != null) {
328334
logger.info("Databases and the hosts that their forests will be created on: " + prop);

src/main/java/com/marklogic/appdeployer/command/CommandMapBuilder.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package com.marklogic.appdeployer.command;
22

3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
38
import com.marklogic.appdeployer.command.alert.DeployAlertActionsCommand;
49
import com.marklogic.appdeployer.command.alert.DeployAlertConfigsCommand;
510
import com.marklogic.appdeployer.command.alert.DeployAlertRulesCommand;
@@ -19,12 +24,22 @@
1924
import com.marklogic.appdeployer.command.forests.ConfigureForestReplicasCommand;
2025
import com.marklogic.appdeployer.command.forests.DeployCustomForestsCommand;
2126
import com.marklogic.appdeployer.command.groups.DeployGroupsCommand;
27+
import com.marklogic.appdeployer.command.hosts.AssignHostsToGroupsCommand;
2228
import com.marklogic.appdeployer.command.mimetypes.DeployMimetypesCommand;
2329
import com.marklogic.appdeployer.command.modules.DeleteTestModulesCommand;
2430
import com.marklogic.appdeployer.command.modules.LoadModulesCommand;
2531
import com.marklogic.appdeployer.command.restapis.DeployRestApiServersCommand;
2632
import com.marklogic.appdeployer.command.schemas.LoadSchemasCommand;
27-
import com.marklogic.appdeployer.command.security.*;
33+
import com.marklogic.appdeployer.command.security.DeployAmpsCommand;
34+
import com.marklogic.appdeployer.command.security.DeployCertificateAuthoritiesCommand;
35+
import com.marklogic.appdeployer.command.security.DeployCertificateTemplatesCommand;
36+
import com.marklogic.appdeployer.command.security.DeployExternalSecurityCommand;
37+
import com.marklogic.appdeployer.command.security.DeployPrivilegesCommand;
38+
import com.marklogic.appdeployer.command.security.DeployProtectedCollectionsCommand;
39+
import com.marklogic.appdeployer.command.security.DeployProtectedPathsCommand;
40+
import com.marklogic.appdeployer.command.security.DeployQueryRolesetsCommand;
41+
import com.marklogic.appdeployer.command.security.DeployRolesCommand;
42+
import com.marklogic.appdeployer.command.security.DeployUsersCommand;
2843
import com.marklogic.appdeployer.command.tasks.DeployScheduledTasksCommand;
2944
import com.marklogic.appdeployer.command.taskservers.UpdateTaskServerCommand;
3045
import com.marklogic.appdeployer.command.temporal.DeployTemporalAxesCommand;
@@ -33,11 +48,6 @@
3348
import com.marklogic.appdeployer.command.triggers.DeployTriggersCommand;
3449
import com.marklogic.appdeployer.command.viewschemas.DeployViewSchemasCommand;
3550

36-
import java.util.ArrayList;
37-
import java.util.HashMap;
38-
import java.util.List;
39-
import java.util.Map;
40-
4151
/**
4252
* The intent of this class is to construct a map of commonly used commands that can used in a variety of contexts - i.e.
4353
* ml-gradle or the Data Hub Framework - thus preventing those clients from having to duplicate this code.
@@ -130,6 +140,11 @@ public Map<String, List<Command>> buildCommandMap() {
130140
mimetypeCommands.add(new DeployMimetypesCommand());
131141
map.put("mlMimetypeCommands", mimetypeCommands);
132142

143+
// Hosts
144+
List<Command> hostCommands = new ArrayList<Command>();
145+
hostCommands.add(new AssignHostsToGroupsCommand());
146+
map.put("mlAssignHostsToGroups", hostCommands);
147+
133148
// Forests
134149
List<Command> forestCommands = new ArrayList<Command>();
135150
forestCommands.add(new DeployCustomForestsCommand());

src/main/java/com/marklogic/appdeployer/command/SortOrderConstants.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
public abstract class SortOrderConstants {
44

55
public static Integer DEPLOY_GROUPS = 5;
6-
6+
77
public static Integer DEPLOY_PRIVILEGES = 10;
88
public static Integer DEPLOY_ROLES = 20;
99
public static Integer DEPLOY_USERS = 30;
@@ -15,6 +15,11 @@ public abstract class SortOrderConstants {
1515
public static Integer DEPLOY_MIMETYPES = 90;
1616
public static Integer DEPLOY_PROTECTED_PATHS = 95;
1717
public static Integer DEPLOY_QUERY_ROLESETS = 97;
18+
19+
// Hosts need to be assigned to their group before databases are created.
20+
// This is so that when forests are created based on the mlDatabaseGroups
21+
// then the forests will be created on the correct hosts.
22+
public static Integer ASSIGN_HOSTS_TO_GROUPS = 98;
1823

1924
public static Integer DEPLOY_TRIGGERS_DATABASE = 100;
2025
public static Integer DEPLOY_SCHEMAS_DATABASE = 100;
@@ -79,6 +84,7 @@ public abstract class SortOrderConstants {
7984
public static Integer DELETE_PROTECTED_PATHS = 9080;
8085

8186
public static Integer DELETE_GROUPS = 8600;
87+
public static Integer UNASSIGN_HOSTS_FROM_GROUPS = 8590;
8288

8389
public static Integer DELETE_MIMETYPES = 8500;
8490

src/main/java/com/marklogic/appdeployer/command/groups/DeployGroupsCommand.java

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,38 @@
11
package com.marklogic.appdeployer.command.groups;
22

3+
import java.io.File;
4+
35
import com.marklogic.appdeployer.command.AbstractResourceCommand;
46
import com.marklogic.appdeployer.command.CommandContext;
57
import com.marklogic.appdeployer.command.SortOrderConstants;
6-
import com.marklogic.mgmt.resource.ResourceManager;
8+
import com.marklogic.mgmt.PayloadParser;
79
import com.marklogic.mgmt.SaveReceipt;
10+
import com.marklogic.mgmt.api.server.AppServicesServer;
11+
import com.marklogic.mgmt.api.server.ManageServer;
12+
import com.marklogic.mgmt.api.server.Server;
13+
import com.marklogic.mgmt.resource.ResourceManager;
14+
import com.marklogic.mgmt.resource.appservers.ServerManager;
815
import com.marklogic.mgmt.resource.groups.GroupManager;
916

10-
import java.io.File;
11-
1217
public class DeployGroupsCommand extends AbstractResourceCommand {
1318

14-
public DeployGroupsCommand() {
19+
private Server adminServerTemplate;
20+
private Server manageServerTemplate;
21+
private Server appServicesServerTemplate;
22+
23+
private boolean fixAdminServerRewriter = true;
24+
private boolean createManageServer = true;
25+
private boolean createAppServicesServer = true;
26+
27+
public DeployGroupsCommand() {
1528
setExecuteSortOrder(SortOrderConstants.DEPLOY_GROUPS);
1629
setUndoSortOrder(SortOrderConstants.DELETE_GROUPS);
30+
31+
adminServerTemplate = new Server(null, "Admin");
32+
adminServerTemplate.setUrlRewriter("rewriter.xqy");
33+
34+
manageServerTemplate = new ManageServer();
35+
appServicesServerTemplate = new AppServicesServer();
1736
}
1837

1938
@Override
@@ -35,11 +54,105 @@ protected ResourceManager getResourceManager(CommandContext context) {
3554
protected void afterResourceSaved(ResourceManager mgr, CommandContext context, File resourceFile,
3655
SaveReceipt receipt) {
3756
String payload = receipt.getPayload();
38-
if (payload != null && payload.contains("cache-size") && context.getAdminManager() != null) {
39-
if (logger.isDebugEnabled()) {
40-
logger.info("Group payload contains cache-size parameter, so waiting for ML to restart");
41-
}
42-
context.getAdminManager().waitForRestart();
57+
if (payload != null) {
58+
if (payload.contains("cache-size") && context.getAdminManager() != null) {
59+
if (logger.isDebugEnabled()) {
60+
logger.info("Group payload contains cache-size parameter, so waiting for ML to restart");
61+
}
62+
context.getAdminManager().waitForRestart();
63+
}
64+
65+
// When new groups are created, an Admin server is automatically created in that group.
66+
// However, the Admin server's rewrite property is empty - causing problems with reading the timestamp
67+
String groupName = new PayloadParser().getPayloadFieldValue(payload, "group-name", true);
68+
ServerManager serverMgr = new ServerManager(context.getManageClient(), groupName);
69+
if (fixAdminServerRewriter) {
70+
if (logger.isInfoEnabled()) {
71+
logger.info(format("Updating admin server in group %s to ensure that its url-rewriter is correct", groupName));
72+
}
73+
serverMgr.save(adminServerTemplate.getJson());
74+
}
75+
76+
ensureGroupServersExist(serverMgr, groupName);
4377
}
4478
}
79+
80+
/**
81+
* Prior to 9.0-3 of MarkLogic, a Manage server isn't created by default for a new group. So this ensures that the
82+
* Manage server will be created if such a version of ML is being used (see bug 46909).
83+
*
84+
* An App-Services server is created in the new group too. MarkLogic does not do this automatically, but it's done
85+
* here because it's likely that modules will need to be loaded into one or more hosts within the new group. And
86+
* the App-Services server on port 8000 is used by default for this.
87+
*
88+
* @param serverMgr
89+
* @param groupName
90+
*/
91+
protected void ensureGroupServersExist(ServerManager serverMgr, String groupName) {
92+
if (createManageServer) {
93+
ensureServerExists(serverMgr, manageServerTemplate, groupName);
94+
}
95+
if (createAppServicesServer) {
96+
ensureServerExists(serverMgr, appServicesServerTemplate, groupName);
97+
}
98+
}
99+
100+
protected void ensureServerExists(ServerManager serverMgr, Server server, String groupName) {
101+
final String name = server.getServerName();
102+
if (serverMgr.exists(name)) {
103+
logger.info(format("%s server already exists in group %s", name, groupName));
104+
} else {
105+
server.setGroupName(groupName);
106+
serverMgr.save(server.getJson());
107+
logger.info(format("Created the %s server in group %s", name, groupName));
108+
}
109+
}
110+
111+
public Server getAdminServerTemplate() {
112+
return adminServerTemplate;
113+
}
114+
115+
public void setAdminServerTemplate(Server adminServerTemplate) {
116+
this.adminServerTemplate = adminServerTemplate;
117+
}
118+
119+
public Server getManageServerTemplate() {
120+
return manageServerTemplate;
121+
}
122+
123+
public void setManageServerTemplate(Server manageServerTemplate) {
124+
this.manageServerTemplate = manageServerTemplate;
125+
}
126+
127+
public Server getAppServicesServerTemplate() {
128+
return appServicesServerTemplate;
129+
}
130+
131+
public void setAppServicesServerTemplate(Server appServicesServerTemplate) {
132+
this.appServicesServerTemplate = appServicesServerTemplate;
133+
}
134+
135+
public boolean isFixAdminServerRewriter() {
136+
return fixAdminServerRewriter;
137+
}
138+
139+
public void setFixAdminServerRewriter(boolean fixAdminServerRewriter) {
140+
this.fixAdminServerRewriter = fixAdminServerRewriter;
141+
}
142+
143+
public boolean isCreateManageServer() {
144+
return createManageServer;
145+
}
146+
147+
public void setCreateManageServer(boolean createManageServer) {
148+
this.createManageServer = createManageServer;
149+
}
150+
151+
public boolean isCreateAppServicesServer() {
152+
return createAppServicesServer;
153+
}
154+
155+
public void setCreateAppServicesServer(boolean createAppServicesServer) {
156+
this.createAppServicesServer = createAppServicesServer;
157+
}
45158
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.marklogic.appdeployer.command.hosts;
2+
3+
import java.util.Map;
4+
5+
import com.marklogic.appdeployer.command.AbstractUndoableCommand;
6+
import com.marklogic.appdeployer.command.CommandContext;
7+
import com.marklogic.appdeployer.command.SortOrderConstants;
8+
import com.marklogic.mgmt.api.server.AppServicesServer;
9+
import com.marklogic.mgmt.api.server.ManageServer;
10+
import com.marklogic.mgmt.api.server.Server;
11+
import com.marklogic.mgmt.resource.appservers.ServerManager;
12+
import com.marklogic.mgmt.resource.hosts.HostManager;
13+
14+
public class AssignHostsToGroupsCommand extends AbstractUndoableCommand {
15+
16+
private static final String DEFAULT_GROUP_NAME = "Default";
17+
18+
public AssignHostsToGroupsCommand() {
19+
setExecuteSortOrder(SortOrderConstants.ASSIGN_HOSTS_TO_GROUPS);
20+
setUndoSortOrder(SortOrderConstants.UNASSIGN_HOSTS_FROM_GROUPS);
21+
}
22+
23+
@Override
24+
public void execute(CommandContext context) {
25+
context.getAdminManager().invokeActionRequiringRestart(() -> assignHostsToGroups(context));
26+
}
27+
28+
protected boolean assignHostsToGroups(CommandContext context) {
29+
boolean requiresRestart = false;
30+
31+
Map<String, String> hostGroups = context.getAppConfig().getHostGroups();
32+
HostManager hostMgr = new HostManager(context.getManageClient());
33+
if (hostGroups != null) {
34+
for (Map.Entry<String, String> entry : hostGroups.entrySet()) {
35+
String hostName = entry.getKey();
36+
String groupName = entry.getValue();
37+
38+
if (!groupName.equals(hostMgr.getAssignedGroupName(hostName))) {
39+
if (logger.isInfoEnabled()) {
40+
logger.info(format("Assigning host %s to group %s", hostName, groupName));
41+
}
42+
hostMgr.setHostToGroup(hostName, groupName);
43+
requiresRestart = true;
44+
}
45+
}
46+
}
47+
48+
return requiresRestart;
49+
}
50+
51+
@Override
52+
public void undo(CommandContext context) {
53+
context.getAdminManager().invokeActionRequiringRestart(() -> assignHostsToDefault(context));
54+
}
55+
56+
protected boolean assignHostsToDefault(CommandContext context) {
57+
boolean requiresRestart = false;
58+
59+
Map<String, String> hostGroups = context.getAppConfig().getHostGroups();
60+
if (hostGroups != null) {
61+
HostManager hostMgr = new HostManager(context.getManageClient());
62+
for (Map.Entry<String, String> entry : hostGroups.entrySet()) {
63+
String hostName = entry.getKey();
64+
if (!DEFAULT_GROUP_NAME.equals(hostMgr.getAssignedGroupName(hostName))) {
65+
if (logger.isInfoEnabled()) {
66+
logger.info(format("Assigning host %s to group %s", hostName, DEFAULT_GROUP_NAME));
67+
}
68+
hostMgr.setHostToGroup(hostName, DEFAULT_GROUP_NAME);
69+
requiresRestart = true;
70+
}
71+
}
72+
}
73+
74+
return requiresRestart;
75+
}
76+
}

src/main/java/com/marklogic/mgmt/api/API.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,15 @@ public Forest getForest() {
234234
}
235235

236236
public Server server(String name) {
237-
return server(name, null);
237+
return server(name, (Integer)null);
238238
}
239239

240-
public Server server(String name, Integer port) {
240+
public Server server(String name, String groupName) {
241+
Server s = new Server(this, name);
242+
return name != null && s.exists() ? getResource(name, new ServerManager(getManageClient(), groupName), Server.class) : s;
243+
}
244+
245+
public Server server(String name, Integer port) {
241246
Server s = new Server(this, name);
242247
s.setPort(port);
243248
return name != null && s.exists() ? getResource(name, new ServerManager(getManageClient()), Server.class) : s;

0 commit comments

Comments
 (0)