-
Notifications
You must be signed in to change notification settings - Fork 334
WPB-28421 add an opt in policy for dropping unsupported federated notifications #5501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add an opt-in policy for dropping queued federation notifications when the target backend supports no compatible API version. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,6 +36,7 @@ import Network.AMQP qualified as Q | |
| import Network.AMQP.Types qualified as Q | ||
| import Servant | ||
| import Servant.Client.Core | ||
| import Test.QuickCheck (Arbitrary (arbitrary), elements) | ||
| import Wire.API.Federation.API.Common | ||
| import Wire.API.Federation.Client | ||
| import Wire.API.Federation.Component | ||
|
|
@@ -75,6 +76,29 @@ instance ToSchema BackendNotification where | |
| <*> bodyVersions .= maybe_ (optField "bodyVersions" schema) | ||
| <*> (.requestId) .= maybe_ (optField "requestId" schema) | ||
|
|
||
| data UnsupportedVersionPolicy | ||
| = KeepQueued | ||
| | DropIfUnsupported | ||
| deriving stock (Eq, Show) | ||
| deriving (A.ToJSON, A.FromJSON) via (Schema UnsupportedVersionPolicy) | ||
|
|
||
| instance Arbitrary UnsupportedVersionPolicy where | ||
| arbitrary = elements [KeepQueued, DropIfUnsupported] | ||
|
|
||
| instance ToSchema UnsupportedVersionPolicy where | ||
| schema = | ||
| enum @Text $ | ||
| mconcat | ||
| [ element "keep_queued" KeepQueued, | ||
| element "drop_if_unsupported" DropIfUnsupported | ||
| ] | ||
|
|
||
| -- Keeping the notification queued is the safe choice if representations | ||
| -- configured with different policies are accidentally combined. | ||
| instance Semigroup UnsupportedVersionPolicy where | ||
| DropIfUnsupported <> DropIfUnsupported = DropIfUnsupported | ||
| _ <> _ = KeepQueued | ||
|
|
||
| -- | Convert a federation endpoint to a backend notification to be enqueued to a | ||
| -- RabbitMQ queue. | ||
| fedNotifToBackendNotif :: | ||
|
|
@@ -104,17 +128,29 @@ fedNotifToBackendNotif rid ownDomain payload = | |
| requestId = Just rid | ||
| } | ||
|
|
||
| newtype PayloadBundle (c :: Component) = PayloadBundle | ||
| { notifications :: NE.NonEmpty BackendNotification | ||
| data PayloadBundle (c :: Component) = PayloadBundle | ||
| { notifications :: NE.NonEmpty BackendNotification, | ||
| unsupportedVersionPolicy :: UnsupportedVersionPolicy | ||
| } | ||
| deriving (A.ToJSON, A.FromJSON) via (Schema (PayloadBundle c)) | ||
| deriving newtype (Semigroup) | ||
| deriving stock (Eq, Show) | ||
|
|
||
| instance Semigroup (PayloadBundle c) where | ||
| bundle1 <> bundle2 = | ||
| PayloadBundle | ||
| { notifications = bundle1.notifications <> bundle2.notifications, | ||
| unsupportedVersionPolicy = bundle1.unsupportedVersionPolicy <> bundle2.unsupportedVersionPolicy | ||
| } | ||
|
|
||
| instance (Typeable c) => ToSchema (PayloadBundle c) where | ||
| schema = | ||
| object $ | ||
| PayloadBundle | ||
| <$> notifications .= field "notifications" (nonEmptyArray schema) | ||
| <*> unsupportedVersionPolicy | ||
| .= fmap | ||
| (fromMaybe KeepQueued) | ||
| (optField "unsupportedVersionPolicy" schema) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why default to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because this is explicitly an opt-in policy. If the default was to ignore/drop we would risk a state drift between remotes. |
||
|
|
||
| toBundle :: | ||
| forall {k} (tag :: k). | ||
|
|
@@ -130,7 +166,10 @@ toBundle :: | |
| PayloadBundle (NotificationComponent k) | ||
| toBundle reqId originDomain payload = | ||
| let notif = fedNotifToBackendNotif @tag reqId originDomain payload | ||
| in PayloadBundle . pure $ notif | ||
| in PayloadBundle | ||
| { notifications = pure notif, | ||
| unsupportedVersionPolicy = KeepQueued | ||
| } | ||
|
|
||
| makeBundle :: | ||
| forall {k} (tag :: k) c. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| -- This file is part of the Wire Server implementation. | ||
| -- | ||
| -- Copyright (C) 2026 Wire Swiss GmbH <opensource@wire.com> | ||
| -- | ||
| -- This program is free software: you can redistribute it and/or modify it under | ||
| -- the terms of the GNU Affero General Public License as published by the Free | ||
| -- Software Foundation, either version 3 of the License, or (at your option) | ||
| -- any later version. | ||
| -- | ||
| -- This program is distributed in the hope that it will be useful, but WITHOUT | ||
| -- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
| -- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more | ||
| -- details. | ||
| -- | ||
| -- You should have received a copy of the GNU Affero General Public License along | ||
| -- with this program. If not, see <https://www.gnu.org/licenses/>. | ||
|
|
||
| module Test.Wire.API.Federation.API.BackendNotificationsSpec where | ||
|
|
||
| import Imports | ||
| import Test.Hspec | ||
| import Test.Wire.API.Federation.API.Util (jsonRoundTrip) | ||
| import Wire.API.Federation.BackendNotifications (UnsupportedVersionPolicy (..)) | ||
|
|
||
| spec :: Spec | ||
| spec = describe "UnsupportedVersionPolicy" $ do | ||
| describe "roundtrip" $ do | ||
| jsonRoundTrip @UnsupportedVersionPolicy |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| -- This file is part of the Wire Server implementation. | ||
| -- | ||
| -- Copyright (C) 2026 Wire Swiss GmbH <opensource@wire.com> | ||
| -- | ||
| -- This program is free software: you can redistribute it and/or modify it under | ||
| -- the terms of the GNU Affero General Public License as published by the Free | ||
| -- Software Foundation, either version 3 of the License, or (at your option) any | ||
| -- later version. | ||
| -- | ||
| -- This program is distributed in the hope that it will be useful, but WITHOUT | ||
| -- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
| -- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more | ||
| -- details. | ||
| -- | ||
| -- You should have received a copy of the GNU Affero General Public License along | ||
| -- with this program. If not, see <https://www.gnu.org/licenses/>. | ||
|
|
||
| module Test.Wire.API.Federation.Golden.UnsupportedVersionPolicy where | ||
|
|
||
| import Wire.API.Federation.BackendNotifications (UnsupportedVersionPolicy (..)) | ||
|
|
||
| testObjectUnsupportedVersionPolicyKeepQueued :: UnsupportedVersionPolicy | ||
| testObjectUnsupportedVersionPolicyKeepQueued = KeepQueued | ||
|
|
||
| testObjectUnsupportedVersionPolicyDropIfUnsupported :: UnsupportedVersionPolicy | ||
| testObjectUnsupportedVersionPolicyDropIfUnsupported = DropIfUnsupported |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| "drop_if_unsupported" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| "keep_queued" |
Uh oh!
There was an error while loading. Please reload this page.