Skip to content

Commit 0e8d76e

Browse files
Update check-api script to support new event feed format.
1 parent ea9246e commit 0e8d76e

File tree

5 files changed

+124
-25
lines changed

5 files changed

+124
-25
lines changed

contest-api/check-api-consistency.php

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ function warning($msg)
3636

3737
foreach ($feed_json as $row) {
3838
$endpoint = $row['type'];
39+
if ($endpoint === 'contest') {
40+
// New feed format uses singular for contest
41+
$endpoint = 'contests';
42+
}
3943
$id = isset($row['data']['id']) ? $row['data']['id'] : '_single_';
4044
$feed_data[$endpoint][$id][] = $row;
4145
}
@@ -62,30 +66,39 @@ function array_diff_keys($a, $b)
6266
error("'state' cannot have ID '$id' set.");
6367
}
6468
for ($i=0; $i<count($rows); $i++) {
65-
if ($rows[$i]['op']!=='update') {
69+
if (isset($rows[$i]['op']) && $rows[$i]['op']!=='update') {
6670
error("'state' operation '$rows[$i][op]' not allowed.");
71+
} elseif (!isset($rows[$i]['data'])) { // isset also checks for null
72+
error("'state' can not be deleted.");
6773
}
6874
}
6975
}
7076
} else {
7177
foreach ($elements as $id => $rows) {
72-
if ($rows[0]['op']!=='create') {
78+
if (isset($rows[0]['op']) && $rows[0]['op']!=='create') {
7379
error("'$endpoint/$id' not created first.");
7480
}
7581
for ($i=1; $i<count($rows); $i++) {
76-
switch ($rows[$i]['op']) {
77-
case 'create':
78-
warning("'$endpoint/$id' created again.");
79-
break;
80-
case 'update':
81-
break;
82-
case 'delete':
82+
if (isset($rows[$i]['op'])) {
83+
switch ($rows[$i]['op']) {
84+
case 'create':
85+
warning("'$endpoint/$id' created again.");
86+
break;
87+
case 'update':
88+
break;
89+
case 'delete':
90+
if ($i<count($rows)-1) {
91+
error("'$endpoint/$id' deleted before last change.");
92+
}
93+
break;
94+
default:
95+
error("'$endpoint/$id' unknown operation '$rows[$i][op]'.");
96+
}
97+
} elseif (!isset($rows[$i]['data']) && $i<count($rows)-1) {
8398
if ($i<count($rows)-1) {
8499
error("'$endpoint/$id' deleted before last change.");
85100
}
86101
break;
87-
default:
88-
error("'$endpoint/$id' unknown operation '$rows[$i][op]'.");
89102
}
90103
}
91104
}
@@ -111,7 +124,7 @@ function array_diff_keys($a, $b)
111124
foreach ($feed_data as $endpoint => $elements) {
112125
foreach ($elements as $id => $rows) {
113126
$last = end($rows);
114-
if ($last['op']!=='delete') {
127+
if ((isset($last['op']) && $last['op']!=='delete') || (!isset($last['op']) && isset($last['data'])) ) {
115128
if (!isset($endpoint_data[$endpoint][$id])) {
116129
error("'$endpoint".($id==='_single_' ? '' : "/$id")."' not found in REST endpoint.");
117130
} elseif ($last['data']!==$endpoint_data[$endpoint][$id]) {

contest-api/json-schema/common.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,30 @@
2727
]
2828
},
2929

30+
"endpointssingularcontest": {
31+
"enum": [
32+
"contest",
33+
"judgement-types",
34+
"languages",
35+
"problems",
36+
"groups",
37+
"organizations",
38+
"persons",
39+
"team-members",
40+
"accounts",
41+
"teams",
42+
"state",
43+
"submissions",
44+
"judgements",
45+
"runs",
46+
"clarifications",
47+
"awards",
48+
"commentary",
49+
"scoreboard",
50+
"event-feed"
51+
]
52+
},
53+
3054
"abstime": {
3155
"type": "string",
3256
"pattern": "^[12][0-9]{3}-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-6][0-9]:[0-6][0-9](\\.[0-9]{3})?([+-][0-1][0-9](:[0-5][0-9])?|Z)$"

contest-api/json-schema/event-feed-array.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
"description": "JSON array of responses of this NDJSON API call",
55

66
"type": "array",
7-
"uniqueItems": true,
87
"$ref": "common.json#/nonemptyarray",
98
"items": {
10-
"$ref": "event-feed.json#"
9+
"$comment": "Use anyOf since the event type fields overlap between the current and legacy format.",
10+
"anyOf": [
11+
{ "$ref": "event-feed.json#" },
12+
{ "$ref": "legacy-event-feed.json#" }
13+
]
1114
}
1215
}

contest-api/json-schema/event-feed.json

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,23 @@
55

66
"type": "object",
77
"properties": {
8-
"id": { "$ref": "common.json#/identifier" },
9-
"type": { "$ref": "common.json#/endpoints" }
8+
"id": {
9+
"oneOf": [
10+
{ "$ref": "common.json#/identifier" },
11+
{ "type": "null" }
12+
]
13+
},
14+
"token": {
15+
"oneOf": [
16+
{ "type": "string" },
17+
{ "type": "null" }
18+
]
19+
},
20+
"type": { "$ref": "common.json#/endpointssingularcontest" }
1021
},
1122
"oneOf": [
1223
{
1324
"properties": {
14-
"op": { "enum": [ "create", "update" ] },
1525
"data": {
1626
"$comment": "Use anyOf since some types match others without strict attribute checking.",
1727
"anyOf": [
@@ -38,18 +48,12 @@
3848
},
3949
{
4050
"properties": {
41-
"op": { "enum": [ "delete" ] },
4251
"data": {
43-
"type": "object",
44-
"properties": {
45-
"id": { "$ref": "common.json#/identifier" }
46-
},
47-
"required": ["id"],
48-
"$ref": "common.json#/strictproperties"
52+
"type": "null"
4953
}
5054
}
5155
}
5256
],
53-
"required": ["id", "type", "op", "data"],
57+
"required": ["id", "type", "data"],
5458
"$ref": "common.json#/strictproperties"
5559
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"title": "CLICS Contest API: event-feed",
4+
"description": "Single line response of this NDJSON API call",
5+
6+
"type": "object",
7+
"properties": {
8+
"id": { "$ref": "common.json#/identifier" },
9+
"type": { "$ref": "common.json#/endpoints" }
10+
},
11+
"oneOf": [
12+
{
13+
"properties": {
14+
"op": { "enum": [ "create", "update" ] },
15+
"data": {
16+
"$comment": "Use anyOf since some types match others without strict attribute checking.",
17+
"anyOf": [
18+
{ "$ref": "contest.json#" },
19+
{ "$ref": "judgement-type.json#" },
20+
{ "$ref": "language.json#" },
21+
{ "$ref": "problem.json#" },
22+
{ "$ref": "group.json#" },
23+
{ "$ref": "organization.json#" },
24+
{ "$ref": "team.json#" },
25+
{ "$ref": "person.json#" },
26+
{ "$ref": "team-member.json#" },
27+
{ "$ref": "account.json#" },
28+
{ "$ref": "state.json#" },
29+
{ "$ref": "submission.json#" },
30+
{ "$ref": "judgement.json#" },
31+
{ "$ref": "run.json#" },
32+
{ "$ref": "clarification.json#" },
33+
{ "$ref": "award.json#" },
34+
{ "$ref": "commentary.json#" }
35+
]
36+
}
37+
}
38+
},
39+
{
40+
"properties": {
41+
"op": { "enum": [ "delete" ] },
42+
"data": {
43+
"type": "object",
44+
"properties": {
45+
"id": { "$ref": "common.json#/identifier" }
46+
},
47+
"required": ["id"],
48+
"$ref": "common.json#/strictproperties"
49+
}
50+
}
51+
}
52+
],
53+
"required": ["id", "type", "op", "data"],
54+
"$ref": "common.json#/strictproperties"
55+
}

0 commit comments

Comments
 (0)