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

Commit 3b51c76

Browse files
authored
Fix get federation status of destination if no error occured (#11593)
1 parent d8f94ee commit 3b51c76

File tree

4 files changed

+88
-25
lines changed

4 files changed

+88
-25
lines changed

changelog.d/11593.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix an error in to get federation status of a destination server even if no error has occurred. This admin API was new introduced in Synapse 1.49.0.

synapse/rest/admin/federation.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,25 +111,37 @@ async def on_GET(
111111
) -> Tuple[int, JsonDict]:
112112
await assert_requester_is_admin(self._auth, request)
113113

114+
if not await self._store.is_destination_known(destination):
115+
raise NotFoundError("Unknown destination")
116+
114117
destination_retry_timings = await self._store.get_destination_retry_timings(
115118
destination
116119
)
117120

118-
if not destination_retry_timings:
119-
raise NotFoundError("Unknown destination")
120-
121121
last_successful_stream_ordering = (
122122
await self._store.get_destination_last_successful_stream_ordering(
123123
destination
124124
)
125125
)
126126

127-
response = {
127+
response: JsonDict = {
128128
"destination": destination,
129-
"failure_ts": destination_retry_timings.failure_ts,
130-
"retry_last_ts": destination_retry_timings.retry_last_ts,
131-
"retry_interval": destination_retry_timings.retry_interval,
132129
"last_successful_stream_ordering": last_successful_stream_ordering,
133130
}
134131

132+
if destination_retry_timings:
133+
response = {
134+
**response,
135+
"failure_ts": destination_retry_timings.failure_ts,
136+
"retry_last_ts": destination_retry_timings.retry_last_ts,
137+
"retry_interval": destination_retry_timings.retry_interval,
138+
}
139+
else:
140+
response = {
141+
**response,
142+
"failure_ts": None,
143+
"retry_last_ts": 0,
144+
"retry_interval": 0,
145+
}
146+
135147
return HTTPStatus.OK, response

synapse/storage/databases/main/transactions.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,3 +560,14 @@ def get_destinations_paginate_txn(
560560
return await self.db_pool.runInteraction(
561561
"get_destinations_paginate_txn", get_destinations_paginate_txn
562562
)
563+
564+
async def is_destination_known(self, destination: str) -> bool:
565+
"""Check if a destination is known to the server."""
566+
result = await self.db_pool.simple_select_one_onecol(
567+
table="destinations",
568+
keyvalues={"destination": destination},
569+
retcol="1",
570+
allow_none=True,
571+
desc="is_destination_known",
572+
)
573+
return bool(result)

tests/rest/admin/test_federation.py

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,12 @@ def _order_test(
314314
retry_interval,
315315
last_successful_stream_ordering,
316316
) in dest:
317-
self.get_success(
318-
self.store.set_destination_retry_timings(
319-
destination, failure_ts, retry_last_ts, retry_interval
320-
)
321-
)
322-
self.get_success(
323-
self.store.set_destination_last_successful_stream_ordering(
324-
destination, last_successful_stream_ordering
325-
)
317+
self._create_destination(
318+
destination,
319+
failure_ts,
320+
retry_last_ts,
321+
retry_interval,
322+
last_successful_stream_ordering,
326323
)
327324

328325
# order by default (destination)
@@ -413,11 +410,9 @@ def _search_test(
413410
_search_test(None, "foo")
414411
_search_test(None, "bar")
415412

416-
def test_get_single_destination(self) -> None:
417-
"""
418-
Get one specific destinations.
419-
"""
420-
self._create_destinations(5)
413+
def test_get_single_destination_with_retry_timings(self) -> None:
414+
"""Get one specific destination which has retry timings."""
415+
self._create_destinations(1)
421416

422417
channel = self.make_request(
423418
"GET",
@@ -432,6 +427,53 @@ def test_get_single_destination(self) -> None:
432427
# convert channel.json_body into a List
433428
self._check_fields([channel.json_body])
434429

430+
def test_get_single_destination_no_retry_timings(self) -> None:
431+
"""Get one specific destination which has no retry timings."""
432+
self._create_destination("sub0.example.com")
433+
434+
channel = self.make_request(
435+
"GET",
436+
self.url + "/sub0.example.com",
437+
access_token=self.admin_user_tok,
438+
)
439+
440+
self.assertEqual(HTTPStatus.OK, channel.code, msg=channel.json_body)
441+
self.assertEqual("sub0.example.com", channel.json_body["destination"])
442+
self.assertEqual(0, channel.json_body["retry_last_ts"])
443+
self.assertEqual(0, channel.json_body["retry_interval"])
444+
self.assertIsNone(channel.json_body["failure_ts"])
445+
self.assertIsNone(channel.json_body["last_successful_stream_ordering"])
446+
447+
def _create_destination(
448+
self,
449+
destination: str,
450+
failure_ts: Optional[int] = None,
451+
retry_last_ts: int = 0,
452+
retry_interval: int = 0,
453+
last_successful_stream_ordering: Optional[int] = None,
454+
) -> None:
455+
"""Create one specific destination
456+
457+
Args:
458+
destination: the destination we have successfully sent to
459+
failure_ts: when the server started failing (ms since epoch)
460+
retry_last_ts: time of last retry attempt in unix epoch ms
461+
retry_interval: how long until next retry in ms
462+
last_successful_stream_ordering: the stream_ordering of the most
463+
recent successfully-sent PDU
464+
"""
465+
self.get_success(
466+
self.store.set_destination_retry_timings(
467+
destination, failure_ts, retry_last_ts, retry_interval
468+
)
469+
)
470+
if last_successful_stream_ordering is not None:
471+
self.get_success(
472+
self.store.set_destination_last_successful_stream_ordering(
473+
destination, last_successful_stream_ordering
474+
)
475+
)
476+
435477
def _create_destinations(self, number_destinations: int) -> None:
436478
"""Create a number of destinations
437479
@@ -440,10 +482,7 @@ def _create_destinations(self, number_destinations: int) -> None:
440482
"""
441483
for i in range(0, number_destinations):
442484
dest = f"sub{i}.example.com"
443-
self.get_success(self.store.set_destination_retry_timings(dest, 50, 50, 50))
444-
self.get_success(
445-
self.store.set_destination_last_successful_stream_ordering(dest, 100)
446-
)
485+
self._create_destination(dest, 50, 50, 50, 100)
447486

448487
def _check_fields(self, content: List[JsonDict]) -> None:
449488
"""Checks that the expected destination attributes are present in content

0 commit comments

Comments
 (0)