Skip to content

Commit 9314d69

Browse files
committed
Enh 37150884 - [37133338->14.1.2.0.1] Add the ability to run reports from management over REST (14.1.2.0 cl 112538 --> ce/14.1.2.0)
[git-p4: depot-paths = "//dev/coherence-ce/release/coherence-ce-v14.1.2.0/": change = 113176]
1 parent 4d485cb commit 9314d69

File tree

4 files changed

+122
-4
lines changed

4 files changed

+122
-4
lines changed

prj/coherence-core/src/main/java/com/tangosol/internal/management/resources/AbstractManagementResource.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -2312,6 +2312,8 @@ protected boolean isFederatedServiceMemberValid(HttpRequest request)
23122312
public static final String PARTITION = "partition";
23132313
public static final String FEDERATION = "federation";
23142314
public static final String RESET_STATS = "resetStatistics";
2315+
public static final String RUN_REPORT = "runReport";
2316+
public static final String REPORT_NAME = "reportName";
23152317
public static final String PARTITION_STATS = "reportPartitionStats";
23162318
public static final String CHILDREN = "children";
23172319
public static final String NAME = "name";

prj/coherence-core/src/main/java/com/tangosol/internal/management/resources/ReporterMemberResource.java

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/*
2-
* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
5-
* http://oss.oracle.com/licenses/upl.
5+
* https://oss.oracle.com/licenses/upl.
66
*/
77
package com.tangosol.internal.management.resources;
88

@@ -12,11 +12,25 @@
1212

1313
import com.tangosol.internal.management.EntityMBeanResponse;
1414

15+
import com.tangosol.net.CacheFactory;
1516
import com.tangosol.net.management.MBeanAccessor.QueryBuilder;
17+
import com.tangosol.net.management.MBeanHelper;
18+
import com.tangosol.net.management.Registry;
19+
20+
import javax.management.MBeanServerConnection;
21+
import javax.management.ObjectName;
22+
import javax.management.openmbean.CompositeData;
23+
import javax.management.openmbean.TabularData;
1624

1725
import java.net.URI;
1826

27+
import java.util.ArrayList;
28+
import java.util.Collection;
29+
import java.util.HashMap;
30+
import java.util.HashSet;
31+
import java.util.List;
1932
import java.util.Map;
33+
import java.util.Set;
2034

2135
/**
2236
* Handles management API requests for a single Coherence reporter member.
@@ -39,6 +53,7 @@ public void addRoutes(RequestRouter router, String sPathRoot)
3953
router.addPost(sPathRoot + "/start", this::start);
4054
router.addPost(sPathRoot + "/stop", this::stop);
4155
router.addPost(sPathRoot + "/" + RESET_STATS, this::resetStatistics);
56+
router.addGet(sPathRoot + "/" + RUN_REPORT + "/{" + REPORT_NAME + "}", this::runReport);
4257
}
4358

4459
// ----- GET API --------------------------------------------------------
@@ -113,6 +128,60 @@ public Response resetStatistics(HttpRequest request)
113128
return executeMBeanOperation(request, getQuery(request, sMemberKey), RESET_STATS, null, null);
114129
}
115130

131+
/**
132+
* Run a specified report using runTabularReport.
133+
*
134+
* @param request the {@link HttpRequest}
135+
*
136+
* @return the response object
137+
*/
138+
@SuppressWarnings("unchecked")
139+
public Response runReport(HttpRequest request)
140+
{
141+
String sReportName = request.getFirstPathParameter(REPORT_NAME);
142+
MBeanServerConnection mbs = MBeanHelper.findMBeanServer();
143+
String sFullReportName = "reports/" + sReportName + ".xml";
144+
145+
List<Map<String, Object>> results = new ArrayList<>();
146+
147+
try
148+
{
149+
int nMemberId = CacheFactory.ensureCluster().getLocalMember().getId();
150+
Set<ObjectName> setNames = mbs.queryNames(new ObjectName("Coherence:" + Registry.REPORTER_TYPE + "," + Registry.KEY_NODE_ID + nMemberId + ",*"), null);
151+
152+
if (setNames.isEmpty())
153+
{
154+
return Response.status(Response.Status.NOT_FOUND).build();
155+
}
156+
157+
TabularData reportData = (TabularData) mbs.invoke(setNames.iterator().next(),
158+
"runTabularReport", new Object[] {sFullReportName}, new String[] {"java.lang.String"});
159+
160+
//noinspection unchecked
161+
Collection<CompositeData> values = (Collection<CompositeData>) reportData.values();
162+
for (CompositeData compositeData : values)
163+
{
164+
Set<String> keys = compositeData.getCompositeType().keySet();
165+
Map<String, Object> mapValues = new HashMap<>();
166+
167+
keys.forEach((k) -> mapValues.put(k, compositeData.get(k)));
168+
results.add(mapValues);
169+
}
170+
}
171+
catch (Exception e)
172+
{
173+
// any exception should be treated as a 404 not found
174+
e.printStackTrace();
175+
return Response.status(Response.Status.NOT_FOUND).build();
176+
}
177+
178+
EntityMBeanResponse responseEntity = new EntityMBeanResponse();
179+
responseEntity.setEntities(results);
180+
Map<String, Object> mapResponse = responseEntity.toJson();
181+
182+
return response(mapResponse);
183+
}
184+
116185
// ----- ReporterMemberResource methods----------------------------------
117186

118187
/**

prj/coherence-core/src/main/resources/management-swagger.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,30 @@
13731373
}
13741374
}
13751375
},
1376+
"/management/coherence/cluster/reporters/{memberIdentifier}/runReport/{reportName}": {
1377+
"get": {
1378+
"tags": [
1379+
"Reporter"
1380+
],
1381+
"summary": "Run a report",
1382+
"description": "Use this endpoint to run a report and return the output in JSON format",
1383+
"operationId": "/management/coherence/cluster/reporters/{memberIdentifier}/runReport/{reportName} GET",
1384+
"produces": [
1385+
"application/json"
1386+
],
1387+
"parameters": [
1388+
{
1389+
"$ref": "#/parameters/memberIdentifier",
1390+
"$ref": "#/parameters/reportName"
1391+
}
1392+
],
1393+
"responses": {
1394+
"200": {
1395+
"description": "Command invocation is successful"
1396+
}
1397+
}
1398+
}
1399+
},
13761400
"/management/coherence/cluster/reporters/{memberIdentifier}/resetStatistics": {
13771401
"post": {
13781402
"tags": [
@@ -10488,6 +10512,13 @@
1048810512
"required": true,
1048910513
"type": "string"
1049010514
},
10515+
"reportName": {
10516+
"name": "reportName",
10517+
"in": "path",
10518+
"description": "An identifier of the report to run without the xml extension.",
10519+
"required": true,
10520+
"type": "string"
10521+
},
1049110522
"destinationMemberId": {
1049210523
"name": "destinationMemberId",
1049310524
"in": "path",

prj/test/functional/management/src/main/java/management/BaseManagementInfoResourceTests.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2024, Oracle and/or its affiliates.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates.
33
*
44
* Licensed under the Universal Permissive License v 1.0 as shown at
55
* https://oss.oracle.com/licenses/upl.
@@ -1922,6 +1922,22 @@ public void testMembersStartAndStopReporter()
19221922
}
19231923
}
19241924

1925+
@Test
1926+
public void testMembersRunReport()
1927+
throws IOException
1928+
{
1929+
WebTarget target = getBaseTarget().path(REPORTERS).path("1").path("runReport").path("report-node");
1930+
Response response = target.request(MediaType.APPLICATION_JSON_TYPE).get();
1931+
MatcherAssert.assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
1932+
1933+
Map mapEntity = new LinkedHashMap();
1934+
Entity entity = Entity.entity(mapEntity, MediaType.APPLICATION_JSON_TYPE);
1935+
1936+
Map mapResponse = readEntity(target, response, entity);
1937+
assertThat(mapResponse.size(), is(1));
1938+
assertThat(mapResponse.containsKey("items"), is(true));
1939+
}
1940+
19251941
@Test
19261942
public void testCacheMemberResetStats()
19271943
{

0 commit comments

Comments
 (0)