Skip to content

Commit 979f39b

Browse files
api-clients-generation-pipeline[bot]therveci.datadog-api-spec
authored
Add pagination extension to monitors (#1296)
* Add support for page param * Regenerate client from commit fee86b40 of spec repo --------- Co-authored-by: Thomas Hervé <[email protected]> Co-authored-by: api-clients-generation-pipeline[bot] <54105614+api-clients-generation-pipeline[bot]@users.noreply.github.com> Co-authored-by: ci.datadog-api-spec <[email protected]>
1 parent de4874b commit 979f39b

File tree

9 files changed

+214
-5
lines changed

9 files changed

+214
-5
lines changed

.apigentools-info

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
"spec_versions": {
55
"v1": {
66
"apigentools_version": "1.6.5",
7-
"regenerated": "2023-08-30 07:29:16.616488",
8-
"spec_repo_commit": "febdee32"
7+
"regenerated": "2023-08-30 08:42:52.003609",
8+
"spec_repo_commit": "fee86b40"
99
},
1010
"v2": {
1111
"apigentools_version": "1.6.5",
12-
"regenerated": "2023-08-30 07:29:16.629575",
13-
"spec_repo_commit": "febdee32"
12+
"regenerated": "2023-08-30 08:42:52.016771",
13+
"spec_repo_commit": "fee86b40"
1414
}
1515
}
1616
}

.generator/schemas/v1/openapi.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24896,6 +24896,7 @@ paths:
2489624896
name: page_size
2489724897
required: false
2489824898
schema:
24899+
default: 100
2489924900
example: 20
2490024901
format: int32
2490124902
maximum: 1000
@@ -24931,6 +24932,9 @@ paths:
2493124932
summary: Get all monitor details
2493224933
tags:
2493324934
- Monitors
24935+
x-pagination:
24936+
limitParam: page_size
24937+
pageParam: page
2493424938
post:
2493524939
description: 'Create a monitor using the specified options.
2493624940

.generator/src/generator/openapi.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ def get_api_models(operations):
492492
seen.add(name)
493493
yield name
494494
if "x-pagination" in operation:
495-
name = get_type_at_path(operation, operation["x-pagination"]["resultsPath"])
495+
name = get_type_at_path(operation, operation["x-pagination"].get("resultsPath"))
496496
if name and name not in seen:
497497
seen.add(name)
498498
yield name
@@ -562,6 +562,8 @@ def get_type_at_path(operation, attribute_path):
562562
if content is None:
563563
raise RuntimeError("Default response not found")
564564
content = content["schema"]
565+
if not attribute_path:
566+
return get_name(content.get("items"))
565567
for attr in attribute_path.split("."):
566568
content = content["properties"][attr]
567569
return get_name(content.get("items"))

.generator/src/generator/templates/api/api.j2

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,16 @@ export class {{ className }} {
328328
pageSize = {{ get_container(operation, pagination.limitParam) }};
329329
}
330330
{%- endfor %}
331+
{%- if pagination.pageParam %}
332+
{{ get_container(operation, pagination.pageParam) }} = 0;
333+
{%- endif %}
331334
while (true) {
332335
const requestContext = await this.requestFactory.{{ operationId }}({%- for name, parameter in requiredParams %}param.{{ name|attribute_name }}, {%- endfor %}{%- for name, parameter in optionalParams %}param.{{ name|attribute_name }}, {%- endfor %}options);
333336
const responseContext = await this.configuration.httpApi.send(requestContext);
334337

335338
const response = await this.responseProcessor.{{ operationId }}(responseContext);
336339
{%- set previous = {"part": ""} %}
340+
{%- if pagination.resultsPath %}
337341
{%- for part in pagination.resultsPath.split(".") %}
338342
const response{{ previous["part"] + (part|camel_case) }} = response{{ previous["part"] }}.{{ part|attribute_name }};
339343
if (response{{ previous["part"] + (part|camel_case) }} === undefined) {
@@ -344,6 +348,9 @@ export class {{ className }} {
344348
const results = response{{ previous["part"] }};
345349
{%- endif %}
346350
{%- endfor %}
351+
{%- else %}
352+
const results = response;
353+
{%- endif %}
347354
for (const item of results) {
348355
yield item;
349356
}
@@ -377,6 +384,10 @@ export class {{ className }} {
377384
{%- set _ = previous.update({"cursor": previous["cursor"] + (part|camel_case)}) %}
378385
{%- endfor %}
379386

387+
{%- endif %}
388+
{%- if pagination.pageParam %}
389+
{{ get_container(operation, pagination.pageParam) }} = {{ get_container(operation, pagination.pageParam) }} + 1;
390+
380391
{%- endif %}
381392
}
382393
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"2023-08-28T07:51:42.436Z"
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
{
2+
"log": {
3+
"_recordingName": "Monitors/Get all monitor details returns \"OK\" response with pagination",
4+
"creator": {
5+
"comment": "persister:fs",
6+
"name": "Polly.JS",
7+
"version": "6.0.5"
8+
},
9+
"entries": [
10+
{
11+
"_id": "c6754986240a436bb7706bed3095d41b",
12+
"_order": 0,
13+
"cache": {},
14+
"request": {
15+
"bodySize": 0,
16+
"cookies": [],
17+
"headers": [
18+
{
19+
"_fromType": "array",
20+
"name": "accept",
21+
"value": "application/json"
22+
}
23+
],
24+
"headersSize": 519,
25+
"httpVersion": "HTTP/1.1",
26+
"method": "GET",
27+
"queryString": [
28+
{
29+
"name": "page_size",
30+
"value": "2"
31+
},
32+
{
33+
"name": "page",
34+
"value": "0"
35+
}
36+
],
37+
"url": "https://api.datadoghq.com/api/v1/monitor?page_size=2&page=0"
38+
},
39+
"response": {
40+
"bodySize": 1998,
41+
"content": {
42+
"mimeType": "application/json",
43+
"size": 1998,
44+
"text": "[{\"id\":34822915,\"org_id\":321813,\"type\":\"query alert\",\"name\":\"SLO Monitor: aws_alb_latency_p95 for splunk\",\"message\":\"Latency SLO violation for splunk load balancer(s)\",\"tags\":[\"environment:test\",\"generator:slops\",\"release:e6a2686\",\"sli:latency\",\"slotype:alb\",\"systemid:splunk\",\"team:developer_insights\"],\"query\":\"avg(last_1m):avg:aws.applicationelb.target_response_time.p95{systemid:splunk,aws_account_type:production} by {region} > 0.2\",\"options\":{\"notify_audit\":false,\"locked\":false,\"include_tags\":true,\"thresholds\":{\"critical\":0.2},\"new_host_delay\":300,\"require_full_window\":true,\"notify_no_data\":false,\"silenced\":{}},\"multi\":true,\"created_at\":1620047024000,\"created\":\"2021-05-03T13:03:44.905085+00:00\",\"modified\":\"2021-05-03T13:03:44.905085+00:00\",\"deleted\":null,\"restricted_roles\":null,\"priority\":null,\"overall_state_modified\":\"2021-05-03T13:06:23+00:00\",\"overall_state\":\"No Data\",\"creator\":{\"name\":null,\"handle\":\"[email protected]\",\"email\":\"[email protected]\",\"id\":1445416},\"matching_downtimes\":[]},{\"id\":34822916,\"org_id\":321813,\"type\":\"query alert\",\"name\":\"SLO Monitor: aws_classic_elb_latency_p99 for splunk\",\"message\":\"Latency SLO violation for splunk load balancer(s)\",\"tags\":[\"environment:test\",\"generator:slops\",\"release:e6a2686\",\"sli:latency\",\"slotype:elb\",\"systemid:splunk\",\"team:developer_insights\"],\"query\":\"avg(last_1m):avg:aws.elb.latency.p99{systemid:splunk,aws_account_type:production} by {region} > 0.2\",\"options\":{\"notify_audit\":false,\"locked\":false,\"include_tags\":true,\"thresholds\":{\"critical\":0.2},\"new_host_delay\":300,\"require_full_window\":true,\"notify_no_data\":false,\"silenced\":{}},\"multi\":true,\"created_at\":1620047024000,\"created\":\"2021-05-03T13:03:44.909928+00:00\",\"modified\":\"2021-05-03T13:03:44.909928+00:00\",\"deleted\":null,\"restricted_roles\":null,\"priority\":null,\"overall_state_modified\":\"2021-05-03T13:06:18+00:00\",\"overall_state\":\"No Data\",\"creator\":{\"name\":null,\"handle\":\"[email protected]\",\"email\":\"[email protected]\",\"id\":1445416},\"matching_downtimes\":[]}]\n"
45+
},
46+
"cookies": [],
47+
"headers": [
48+
{
49+
"name": "content-type",
50+
"value": "application/json"
51+
}
52+
],
53+
"headersSize": 697,
54+
"httpVersion": "HTTP/1.1",
55+
"redirectURL": "",
56+
"status": 200,
57+
"statusText": "OK"
58+
},
59+
"startedDateTime": "2023-08-28T07:51:42.446Z",
60+
"time": 503
61+
},
62+
{
63+
"_id": "2a1839fd3a6231a5644a16a6bc96ce71",
64+
"_order": 0,
65+
"cache": {},
66+
"request": {
67+
"bodySize": 0,
68+
"cookies": [],
69+
"headers": [
70+
{
71+
"_fromType": "array",
72+
"name": "accept",
73+
"value": "application/json"
74+
}
75+
],
76+
"headersSize": 519,
77+
"httpVersion": "HTTP/1.1",
78+
"method": "GET",
79+
"queryString": [
80+
{
81+
"name": "page_size",
82+
"value": "2"
83+
},
84+
{
85+
"name": "page",
86+
"value": "1"
87+
}
88+
],
89+
"url": "https://api.datadoghq.com/api/v1/monitor?page_size=2&page=1"
90+
},
91+
"response": {
92+
"bodySize": 2014,
93+
"content": {
94+
"mimeType": "application/json",
95+
"size": 2014,
96+
"text": "[{\"id\":34822917,\"org_id\":321813,\"type\":\"query alert\",\"name\":\"SLO Monitor: aws_alb_latency_p50 for splunk\",\"message\":\"Latency SLO violation for splunk load balancer(s)\",\"tags\":[\"environment:test\",\"generator:slops\",\"release:e6a2686\",\"sli:latency\",\"slotype:alb\",\"systemid:splunk\",\"team:developer_insights\"],\"query\":\"avg(last_1m):avg:aws.applicationelb.target_response_time.p50{systemid:splunk,aws_account_type:production} by {region} > 0.2\",\"options\":{\"notify_audit\":false,\"locked\":false,\"include_tags\":true,\"thresholds\":{\"critical\":0.2},\"new_host_delay\":300,\"require_full_window\":true,\"notify_no_data\":false,\"silenced\":{}},\"multi\":true,\"created_at\":1620047024000,\"created\":\"2021-05-03T13:03:44.920644+00:00\",\"modified\":\"2021-05-03T13:03:44.920644+00:00\",\"deleted\":null,\"restricted_roles\":null,\"priority\":null,\"overall_state_modified\":\"2021-05-03T13:06:37+00:00\",\"overall_state\":\"No Data\",\"creator\":{\"name\":null,\"handle\":\"[email protected]\",\"email\":\"[email protected]\",\"id\":1445416},\"matching_downtimes\":[]}]\n"
97+
},
98+
"cookies": [],
99+
"headers": [
100+
{
101+
"name": "content-type",
102+
"value": "application/json"
103+
}
104+
],
105+
"headersSize": 697,
106+
"httpVersion": "HTTP/1.1",
107+
"redirectURL": "",
108+
"status": 200,
109+
"statusText": "OK"
110+
},
111+
"startedDateTime": "2023-08-28T07:51:42.957Z",
112+
"time": 450
113+
}
114+
],
115+
"pages": [],
116+
"version": "1.2"
117+
}
118+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Get all monitor details returns "OK" response with pagination
3+
*/
4+
5+
import { client, v1 } from "@datadog/datadog-api-client";
6+
7+
const configuration = client.createConfiguration();
8+
const apiInstance = new v1.MonitorsApi(configuration);
9+
10+
const params: v1.MonitorsApiListMonitorsRequest = {
11+
pageSize: 2,
12+
};
13+
14+
(async () => {
15+
try {
16+
for await (const item of apiInstance.listMonitorsWithPagination(params)) {
17+
console.log(item);
18+
}
19+
} catch (error) {
20+
console.error(error);
21+
}
22+
})();

features/v1/monitors.feature

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,14 @@ Feature: Monitors
227227
When the request is sent
228228
Then the response status is 200 OK
229229

230+
@replay-only @skip-validation @team:DataDog/monitor-app @with-pagination
231+
Scenario: Get all monitor details returns "OK" response with pagination
232+
Given new "ListMonitors" request
233+
And request contains "page_size" parameter with value 2
234+
When the request with pagination is sent
235+
Then the response status is 200 OK
236+
And the response has 3 items
237+
230238
@skip @team:DataDog/monitor-app
231239
Scenario: Get all monitor details with tags
232240
Given there is a valid "monitor" in the system

packages/datadog-api-client-v1/apis/MonitorsApi.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,6 +1681,49 @@ export class MonitorsApi {
16811681
});
16821682
}
16831683

1684+
/**
1685+
* Provide a paginated version of listMonitors returning a generator with all the items.
1686+
*/
1687+
public async *listMonitorsWithPagination(
1688+
param: MonitorsApiListMonitorsRequest = {},
1689+
options?: Configuration
1690+
): AsyncGenerator<Monitor> {
1691+
let pageSize = 100;
1692+
if (param.pageSize !== undefined) {
1693+
pageSize = param.pageSize;
1694+
}
1695+
param.pageSize = pageSize;
1696+
param.page = 0;
1697+
while (true) {
1698+
const requestContext = await this.requestFactory.listMonitors(
1699+
param.groupStates,
1700+
param.name,
1701+
param.tags,
1702+
param.monitorTags,
1703+
param.withDowntimes,
1704+
param.idOffset,
1705+
param.page,
1706+
param.pageSize,
1707+
options
1708+
);
1709+
const responseContext = await this.configuration.httpApi.send(
1710+
requestContext
1711+
);
1712+
1713+
const response = await this.responseProcessor.listMonitors(
1714+
responseContext
1715+
);
1716+
const results = response;
1717+
for (const item of results) {
1718+
yield item;
1719+
}
1720+
if (results.length < pageSize) {
1721+
break;
1722+
}
1723+
param.page = param.page + 1;
1724+
}
1725+
}
1726+
16841727
/**
16851728
* Search and filter your monitor groups details.
16861729
* @param param The request object

0 commit comments

Comments
 (0)