Skip to content

Commit 6d13e8c

Browse files
GEODE-5010: Introduce *ResultModel objects to replace *ResultData (apache#1870)
- The changes here are intended to allow for support of both the old and new model for producing results. As such the interface structures are a mess but will be cleaned up once all commands have been converted. - Not all types of return values are supported but will be added as commands are converted. In particular commands that return actual result data in the form of files or file content. - Sub-sections are not supported anymore. - All commands should now return a ResultModel object
1 parent 2a02923 commit 6d13e8c

File tree

45 files changed

+1993
-1551
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1993
-1551
lines changed

geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java

+8-3
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@
9898
import org.apache.geode.management.GemFireProperties;
9999
import org.apache.geode.management.JVMMetrics;
100100
import org.apache.geode.management.OSMetrics;
101-
import org.apache.geode.management.cli.Result;
102101
import org.apache.geode.management.internal.ManagementConstants;
103102
import org.apache.geode.management.internal.ManagementStrings;
104103
import org.apache.geode.management.internal.SystemManagementService;
@@ -115,6 +114,7 @@
115114
import org.apache.geode.management.internal.cli.CommandResponseBuilder;
116115
import org.apache.geode.management.internal.cli.remote.OnlineCommandProcessor;
117116
import org.apache.geode.management.internal.cli.result.CommandResult;
117+
import org.apache.geode.management.internal.cli.result.model.ResultModel;
118118

119119
/**
120120
* This class acts as an Bridge between MemberMBean and GemFire Cache and Distributed System
@@ -1511,8 +1511,13 @@ public String processCommand(String commandString, Map<String, String> env,
15111511
+ commandServiceInitError);
15121512
}
15131513

1514-
Result result = commandProcessor.executeCommand(commandString, env, stagedFilePaths);
1515-
return CommandResponseBuilder.createCommandResponseJson(getMember(), (CommandResult) result);
1514+
Object result = commandProcessor.executeCommand(commandString, env, stagedFilePaths);
1515+
1516+
if (result instanceof CommandResult) {
1517+
return CommandResponseBuilder.createCommandResponseJson(getMember(), (CommandResult) result);
1518+
} else {
1519+
return CommandResponseBuilder.createCommandResponseJson(getMember(), (ResultModel) result);
1520+
}
15161521
}
15171522

15181523
public long getTotalDiskUsage() {

geode-core/src/main/java/org/apache/geode/management/internal/cli/CliAroundInterceptor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public interface CliAroundInterceptor {
3232
/**
3333
* called by the OperationInvoker before the command is executed
3434
*/
35-
default Result preExecution(GfshParseResult parseResult) {
35+
default Object preExecution(GfshParseResult parseResult) {
3636
return ResultBuilder.createInfoResult("");
3737
}
3838

geode-core/src/main/java/org/apache/geode/management/internal/cli/CommandResponse.java

+16-56
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import org.apache.geode.internal.GemFireVersion;
2121
import org.apache.geode.management.internal.cli.json.GfJsonObject;
22+
import org.apache.geode.management.internal.cli.result.ResultData;
2223

2324
/**
2425
* @since GemFire 7.0
@@ -33,16 +34,10 @@ public class CommandResponse {
3334
private final String when;
3435
private final String tokenAccessor;
3536
private final String debugInfo;
36-
private final Data data;
37+
private final ResultData data;
3738
private final boolean failedToPersist;
3839
private final String fileToDownload;
39-
40-
CommandResponse(String sender, String contentType, int status, String page, String tokenAccessor,
41-
String debugInfo, String header, GfJsonObject content, String footer,
42-
boolean failedToPersist) {
43-
this(sender, contentType, status, page, tokenAccessor, debugInfo, header, content, footer,
44-
failedToPersist, null);
45-
}
40+
private final boolean isLegacy;
4641

4742
CommandResponse(String sender, String contentType, int status, String page, String tokenAccessor,
4843
String debugInfo, String header, GfJsonObject content, String footer, boolean failedToPersist,
@@ -53,7 +48,7 @@ public class CommandResponse {
5348
this.page = page;
5449
this.tokenAccessor = tokenAccessor;
5550
this.debugInfo = debugInfo;
56-
this.data = new Data(header, content, footer);
51+
this.data = new LegacyData(header, content, footer);
5752
this.when = DateFormat.getInstance().format(new java.util.Date());
5853
this.version = GemFireVersion.getGemFireVersion();
5954
this.failedToPersist = failedToPersist;
@@ -62,6 +57,7 @@ public class CommandResponse {
6257
} else {
6358
this.fileToDownload = null;
6459
}
60+
this.isLegacy = true;
6561
}
6662

6763
// For de-serializing
@@ -72,11 +68,12 @@ public class CommandResponse {
7268
this.page = jsonObject.getString("page");
7369
this.tokenAccessor = jsonObject.getString("tokenAccessor");
7470
this.debugInfo = jsonObject.getString("debugInfo");
75-
this.data = new Data(jsonObject.getJSONObject("data"));
71+
this.data = new LegacyData(jsonObject.getJSONObject("data"));
7672
this.when = jsonObject.getString("when");
7773
this.version = jsonObject.getString("version");
7874
this.failedToPersist = jsonObject.getBoolean("failedToPersist");
7975
this.fileToDownload = jsonObject.getString("fileToDownload");
76+
this.isLegacy = true;
8077
}
8178

8279
/**
@@ -135,7 +132,7 @@ public String getTokenAccessor() {
135132
/**
136133
* @return the data
137134
*/
138-
public Data getData() {
135+
public ResultData getData() {
139136
return data;
140137
}
141138

@@ -150,18 +147,22 @@ public boolean isFailedToPersist() {
150147
return failedToPersist;
151148
}
152149

153-
public static class Data {
150+
public boolean isLegacy() {
151+
return isLegacy;
152+
}
153+
154+
public static class LegacyData implements ResultData {
154155
private String header;
155156
private GfJsonObject content;
156157
private String footer;
157158

158-
public Data(String header, GfJsonObject content, String footer) {
159+
public LegacyData(String header, GfJsonObject content, String footer) {
159160
this.header = header;
160161
this.content = content;
161162
this.footer = footer;
162163
}
163164

164-
public Data(GfJsonObject dataJsonObject) {
165+
public LegacyData(GfJsonObject dataJsonObject) {
165166
this.header = dataJsonObject.getString("header");
166167
this.content = dataJsonObject.getJSONObject("content");
167168
this.footer = dataJsonObject.getString("footer");
@@ -195,46 +196,5 @@ public String toString() {
195196
return builder.toString();
196197
}
197198
}
198-
}
199-
200199

201-
/*
202-
** TABLE
203-
*
204-
* { "sender": "member1", "version": "gemfire70", "contentType": "table", "page": "1/1",
205-
* "tokenAccessor": "__NULL__", "status": "OK", "when": "January 12 2012", "debugData": [ "val1",
206-
* "val2" ], "data": { "header": [ "Header1", "Header2", "Header3", "Header4" ], "content": [ [
207-
* "val00", "val01", "val02", "val03" ], [ "val10", "val11", "val12", "val13" ], [ "val20", "val21",
208-
* "val22", "val23" ] ] } }
209-
**
210-
* TABLE SCROLLABLE
211-
*
212-
* { "sender": "member1", "version": "gemfire70", "contentType": "table", "page": "1/5",
213-
* "tokenHolder": "TOKEN12345", "status": "OK", "when": "January 12 2012", "debugData": [ "val1",
214-
* "val2" ], "data": { "header": [ "Header1", "Header2", "Header3", "Header4" ], "content": [ [
215-
* "val00", "val01", "val02", "val03" ], [ "val10", "val11", "val12", "val13" ], [ "val20", "val21",
216-
* "val22", "val23" ] ] } }
217-
**
218-
*
219-
* CATALOG
220-
*
221-
* { "sender": "member1", "version": "gemfire70", "contentType": "catalog", "page": "1/1",
222-
* "tokenHolder": "__NULL__", "status": "OK", "when": "January 12 2012", "debugData": [ "val1",
223-
* "val2" ], "data": { "content": [ { "key1": "val1", "key2": "val2", "key3": "val3", "key4":
224-
* "val4", "key5": "val5", "key6": "val6", "key7": "val7" } ] } }
225-
**
226-
*
227-
* CATALOG SCROLLABLE
228-
*
229-
* { "sender": "member1", "version": "gemfire70", "contentType": "catalog", "page": "1/10",
230-
* "tokenHolder": "TOKEN1265765", "status": "OK", "when": "January 12 2012", "debugData": [ "val1",
231-
* "val2" ], "data": { "content": [ { "key1": "val1", "key2": "val2", "key3": "val3", "key4":
232-
* "val4", "key5": "val5", "key6": "val6", "key7": "val7" } ] } }
233-
**
234-
*
235-
* Object as argument
236-
*
237-
* { "com.foo.bar.Employee": { "id": 1234, "name": "Foo BAR", "department": { "id": 456, "name":
238-
* "support" } } }
239-
*
240-
*/
200+
}

geode-core/src/main/java/org/apache/geode/management/internal/cli/CommandResponseBuilder.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,28 @@
1414
*/
1515
package org.apache.geode.management.internal.cli;
1616

17+
import com.fasterxml.jackson.core.JsonProcessingException;
18+
import com.fasterxml.jackson.databind.ObjectMapper;
1719
import org.apache.commons.lang.exception.ExceptionUtils;
1820

1921
import org.apache.geode.management.cli.CliMetaData;
2022
import org.apache.geode.management.internal.cli.json.GfJsonException;
2123
import org.apache.geode.management.internal.cli.json.GfJsonObject;
2224
import org.apache.geode.management.internal.cli.remote.CommandExecutionContext;
2325
import org.apache.geode.management.internal.cli.result.CommandResult;
26+
import org.apache.geode.management.internal.cli.result.model.ResultModel;
2427

2528
/**
2629
*
2730
* @since GemFire 7.0
2831
*/
2932
public class CommandResponseBuilder {
3033

31-
public static CommandResponse prepareCommandResponse(String memberName, CommandResult result) {
34+
private static CommandResponse prepareCommandResponse(String memberName, CommandResult result) {
3235
GfJsonObject content;
3336
content = result.getContent();
3437
return new CommandResponse(memberName, getType(result), result.getStatus().getCode(), "1/1",
35-
CliMetaData.ANNOTATION_NULL_VALUE, getDebugInfo(result), result.getHeader(), content,
38+
CliMetaData.ANNOTATION_NULL_VALUE, getDebugInfo(), result.getHeader(), content,
3639
result.getFooter(), result.failedToPersist(), result.getFileToDownload());
3740
}
3841

@@ -47,19 +50,30 @@ public static CommandResponse prepareCommandResponseFromJson(String jsonString)
4750
return new CommandResponse(jsonObject);
4851
}
4952

50-
public static String getCommandResponseJson(CommandResponse commandResponse) {
53+
private static String getCommandResponseJson(CommandResponse commandResponse) {
5154
return new GfJsonObject(commandResponse).toString();
5255
}
5356

5457
public static String createCommandResponseJson(String memberName, CommandResult result) {
5558
return getCommandResponseJson(prepareCommandResponse(memberName, result));
5659
}
5760

61+
public static String createCommandResponseJson(String memberName, ResultModel result) {
62+
ObjectMapper mapper = new ObjectMapper();
63+
64+
try {
65+
String json = mapper.writeValueAsString(result);
66+
return json;
67+
} catch (JsonProcessingException e) {
68+
throw new RuntimeException(e);
69+
}
70+
}
71+
5872
private static String getType(CommandResult result) {
5973
return result.getType();
6074
}
6175

62-
private static String getDebugInfo(CommandResult result) {
76+
private static String getDebugInfo() {
6377
String debugInfo = "";
6478
if (CommandExecutionContext.isSetWrapperThreadLocal()) {
6579
CommandResponseWriter responseWriter = CommandExecutionContext.getCommandResponseWriter();

geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/AlterAsyncEventQueueCommand.java

+16-14
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,11 @@
3636
import org.apache.geode.cache.Region;
3737
import org.apache.geode.distributed.internal.InternalClusterConfigurationService;
3838
import org.apache.geode.management.cli.CliMetaData;
39-
import org.apache.geode.management.cli.Result;
4039
import org.apache.geode.management.internal.cli.AbstractCliAroundInterceptor;
4140
import org.apache.geode.management.internal.cli.GfshParseResult;
4241
import org.apache.geode.management.internal.cli.exceptions.EntityNotFoundException;
43-
import org.apache.geode.management.internal.cli.result.ResultBuilder;
44-
import org.apache.geode.management.internal.cli.result.TabularResultData;
42+
import org.apache.geode.management.internal.cli.result.model.ResultModel;
43+
import org.apache.geode.management.internal.cli.result.model.TabularResultModel;
4544
import org.apache.geode.management.internal.configuration.domain.Configuration;
4645
import org.apache.geode.management.internal.configuration.utils.XmlUtils;
4746
import org.apache.geode.management.internal.security.ResourceOperation;
@@ -74,7 +73,7 @@ public class AlterAsyncEventQueueCommand extends InternalGfshCommand {
7473
interceptor = "org.apache.geode.management.internal.cli.commands.AlterAsyncEventQueueCommand$Interceptor")
7574
@ResourceOperation(resource = ResourcePermission.Resource.CLUSTER,
7675
operation = ResourcePermission.Operation.MANAGE, target = ResourcePermission.Target.DEPLOY)
77-
public Result execute(@CliOption(key = ID, mandatory = true, help = ID_HELP) String id,
76+
public ResultModel execute(@CliOption(key = ID, mandatory = true, help = ID_HELP) String id,
7877
@CliOption(key = BATCH_SIZE, help = BATCH_SIZE_HELP) Integer batchSize,
7978
@CliOption(key = BATCH_TIME_INTERVAL,
8079
help = BATCH_TIME_INTERVAL_HELP) Integer batchTimeInterval,
@@ -83,22 +82,25 @@ public Result execute(@CliOption(key = ID, mandatory = true, help = ID_HELP) Str
8382
unspecifiedDefaultValue = "false") boolean ifExists)
8483
throws IOException, SAXException, ParserConfigurationException, TransformerException {
8584

85+
ResultModel result = new ResultModel();
86+
8687
// need not check if any running servers has this async-event-queue. A server with this queue id
8788
// may be shutdown, but we still need to update Cluster Configuration.
8889
InternalClusterConfigurationService service =
8990
(InternalClusterConfigurationService) getConfigurationService();
9091

9192
if (service == null) {
92-
return ResultBuilder.createUserErrorResult("Cluster Configuration Service is not available. "
93+
return result.createError("Cluster Configuration Service is not available. "
9394
+ "Please connect to a locator with running Cluster Configuration Service.");
9495
}
9596

9697
boolean locked = service.lockSharedConfiguration();
9798
if (!locked) {
98-
return ResultBuilder.createGemFireErrorResult("Unable to lock the cluster configuration.");
99+
return result.createCommandProcessingError("Unable to lock the cluster configuration.");
99100
}
100101

101-
TabularResultData tableData = ResultBuilder.createTabularResultData();
102+
TabularResultModel tableData = result.addTable();
103+
boolean xmlUpdated = false;
102104
try {
103105
Region<String, Configuration> configRegion = service.getConfigurationRegion();
104106
for (String group : configRegion.keySet()) {
@@ -108,7 +110,6 @@ public Result execute(@CliOption(key = ID, mandatory = true, help = ID_HELP) Str
108110
continue;
109111
}
110112

111-
boolean xmlUpdated = false;
112113
Document document = XmlUtils.createDocumentFromXml(config.getCacheXmlContent());
113114
NodeList nodeList = document.getElementsByTagName("async-event-queue");
114115
for (int i = 0; i < nodeList.getLength(); i++) {
@@ -145,7 +146,7 @@ public Result execute(@CliOption(key = ID, mandatory = true, help = ID_HELP) Str
145146
service.unlockSharedConfiguration();
146147
}
147148

148-
if (tableData.rowSize("Group") == 0) {
149+
if (!xmlUpdated) {
149150
String message = String.format("Can not find an async event queue with id '%s'.", id);
150151
throw new EntityNotFoundException(message, ifExists);
151152
}
@@ -154,21 +155,22 @@ public Result execute(@CliOption(key = ID, mandatory = true, help = ID_HELP) Str
154155
tableData.setFooter(System.lineSeparator()
155156
+ "These changes won't take effect on the running servers. " + System.lineSeparator()
156157
+ "Please restart the servers in these groups for the changes to take effect.");
157-
return ResultBuilder.buildResult(tableData);
158+
159+
return result;
158160
}
159161

160162
public static class Interceptor extends AbstractCliAroundInterceptor {
161163
@Override
162-
public Result preExecution(GfshParseResult parseResult) {
164+
public ResultModel preExecution(GfshParseResult parseResult) {
163165
Object batchSize = parseResult.getParamValue(BATCH_SIZE);
164166
Object batchTimeInterval = parseResult.getParamValue(BATCH_TIME_INTERVAL);
165167
Object maxQueueMemory = parseResult.getParamValue(MAX_QUEUE_MEMORY);
166168

169+
ResultModel resultModel = new ResultModel();
167170
if (batchSize == null && batchTimeInterval == null && maxQueueMemory == null) {
168-
return ResultBuilder
169-
.createUserErrorResult("need to specify at least one option to modify.");
171+
resultModel.createError("need to specify at least one option to modify.");
170172
}
171-
return ResultBuilder.createInfoResult("");
173+
return resultModel;
172174
}
173175
}
174176
}

0 commit comments

Comments
 (0)