diff --git a/config/http/notifications/websockets/handler.json b/config/http/notifications/websockets/handler.json index 63014ca43..09cdfdc71 100644 --- a/config/http/notifications/websockets/handler.json +++ b/config/http/notifications/websockets/handler.json @@ -2,21 +2,21 @@ "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^6.0.0/components/context.jsonld", "@graph": [ { - "comment": "Handles the generation and serialization of notifications for WebSocketSubscription2021.", - "@id": "urn:solid-server:default:WebSocket2021NotificationHandler", + "comment": "Handles the generation and serialization of notifications for WebSocketChannel2023.", + "@id": "urn:solid-server:default:WebSocket2023NotificationHandler", "@type": "TypedNotificationHandler", - "type": "http://www.w3.org/ns/solid/notifications#WebSocketSubscription2021", + "type": "http://www.w3.org/ns/solid/notifications#WebSocketChannel2023", "source": { "@type": "ComposedNotificationHandler", "generator": { "@id": "urn:solid-server:default:BaseNotificationGenerator" }, "serializer": { "@id": "urn:solid-server:default:BaseNotificationSerializer" }, - "emitter": { "@id": "urn:solid-server:default:WebSocket2021Emitter" } + "emitter": { "@id": "urn:solid-server:default:WebSocket2023Emitter" } } }, { "comment": "Emits serialized notifications through WebSockets.", - "@id": "urn:solid-server:default:WebSocket2021Emitter", - "@type": "WebSocket2021Emitter", + "@id": "urn:solid-server:default:WebSocket2023Emitter", + "@type": "WebSocket2023Emitter", "socketMap": { "@id": "urn:solid-server:default:WebSocketMap" } }, @@ -24,7 +24,7 @@ "@id": "urn:solid-server:default:NotificationHandler", "@type": "WaterfallHandler", "handlers": [ - { "@id": "urn:solid-server:default:WebSocket2021NotificationHandler" } + { "@id": "urn:solid-server:default:WebSocket2023NotificationHandler" } ] } ] diff --git a/config/http/notifications/websockets/http.json b/config/http/notifications/websockets/http.json index 85c9f7430..a69f775e6 100644 --- a/config/http/notifications/websockets/http.json +++ b/config/http/notifications/websockets/http.json @@ -3,15 +3,15 @@ "@graph": [ { "comment": "Catches newly opened WebSockets and verifies if they belong to a subscription.", - "@id": "urn:solid-server:default:WebSocket2021Listener", - "@type": "WebSocket2021Listener", + "@id": "urn:solid-server:default:WebSocket2023Listener", + "@type": "WebSocket2023Listener", "storage": { "@id": "urn:solid-server:default:SubscriptionStorage" }, - "route": { "@id": "urn:solid-server:default:WebSocket2021Route" }, + "route": { "@id": "urn:solid-server:default:WebSocket2023Route" }, "handler": { "@type": "SequenceHandler", "handlers": [ - { "@id": "urn:solid-server:default:WebSocket2021Storer" }, - { "@id": "urn:solid-server:default:WebSocket2021StateHandler" } + { "@id": "urn:solid-server:default:WebSocket2023Storer" }, + { "@id": "urn:solid-server:default:WebSocket2023StateHandler" } ] } }, @@ -22,16 +22,16 @@ }, { "comment": "Stores the opened WebSockets for reuse.", - "@id": "urn:solid-server:default:WebSocket2021Storer", - "@type": "WebSocket2021Storer", + "@id": "urn:solid-server:default:WebSocket2023Storer", + "@type": "WebSocket2023Storer", "storage": { "@id": "urn:solid-server:default:SubscriptionStorage" }, "socketMap": { "@id": "urn:solid-server:default:WebSocketMap" } }, { - "comment": "Handles the state feature of a WebSocketSubscription2021 subscription.", - "@id": "urn:solid-server:default:WebSocket2021StateHandler", + "comment": "Handles the state feature of a WebSocketChannel2023 subscription.", + "@id": "urn:solid-server:default:WebSocket2023StateHandler", "@type": "BaseStateHandler", - "handler": { "@id": "urn:solid-server:default:WebSocket2021NotificationHandler" }, + "handler": { "@id": "urn:solid-server:default:WebSocket2023NotificationHandler" }, "storage": { "@id": "urn:solid-server:default:SubscriptionStorage" } }, @@ -39,7 +39,7 @@ "@id": "urn:solid-server:default:ServerConfigurator", "@type": "ParallelHandler", "handlers": [ - { "@id": "urn:solid-server:default:WebSocket2021Listener" } + { "@id": "urn:solid-server:default:WebSocket2023Listener" } ] } ] diff --git a/config/http/notifications/websockets/subscription.json b/config/http/notifications/websockets/subscription.json index 57afa9fff..12f5dfed2 100644 --- a/config/http/notifications/websockets/subscription.json +++ b/config/http/notifications/websockets/subscription.json @@ -2,15 +2,15 @@ "@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^6.0.0/components/context.jsonld", "@graph": [ { - "comment": "Handles the subscriptions targeting a WebSocketSubscription2021.", - "@id": "urn:solid-server:default:WebSocket2021Subscriber", + "comment": "Handles the subscriptions targeting a WebSocketChannel2023.", + "@id": "urn:solid-server:default:WebSocket2023Subscriber", "@type": "OperationRouterHandler", "baseUrl": { "@id": "urn:solid-server:default:variable:baseUrl" }, "allowedMethods": [ "HEAD", "GET", "POST" ], - "allowedPathNames": [ "/WebSocketSubscription2021/$" ], + "allowedPathNames": [ "/WebSocketChannel2023/$" ], "handler": { "@type": "NotificationSubscriber", - "channelType": { "@id": "urn:solid-server:default:WebSocketSubscription2021" }, + "channelType": { "@id": "urn:solid-server:default:WebSocketChannel2023Type" }, "converter": { "@id": "urn:solid-server:default:RepresentationConverter" }, "credentialsExtractor": { "@id": "urn:solid-server:default:CredentialsExtractor" }, "permissionReader": { "@id": "urn:solid-server:default:PermissionReader" }, @@ -19,23 +19,23 @@ } }, { - "@id": "urn:solid-server:default:WebSocket2021Route", + "@id": "urn:solid-server:default:WebSocket2023Route", "@type": "RelativePathInteractionRoute", "base": { "@id": "urn:solid-server:default:NotificationRoute" }, - "relativePath": "/WebSocketSubscription2021/" + "relativePath": "/WebSocketChannel2023/" }, { - "comment": "Contains all the metadata relevant for a WebSocketSubscription2021.", - "@id": "urn:solid-server:default:WebSocketSubscription2021", - "@type": "WebSocketSubscription2021", - "route": { "@id": "urn:solid-server:default:WebSocket2021Route" } + "comment": "Contains all the metadata relevant for a WebSocketChannel2023.", + "@id": "urn:solid-server:default:WebSocketChannel2023Type", + "@type": "WebSocketChannel2023Type", + "route": { "@id": "urn:solid-server:default:WebSocket2023Route" } }, { "@id": "urn:solid-server:default:NotificationTypeHandler", "@type": "WaterfallHandler", "handlers": [ - { "@id": "urn:solid-server:default:WebSocket2021Subscriber" } + { "@id": "urn:solid-server:default:WebSocket2023Subscriber" } ] }, @@ -44,7 +44,7 @@ "@type": "NotificationDescriber", "subscriptions": [ { - "@id": "urn:solid-server:default:WebSocketSubscription2021" + "@id": "urn:solid-server:default:WebSocketChannel2023Type" } ] } diff --git a/documentation/markdown/architecture/features/notifications.md b/documentation/markdown/architecture/features/notifications.md index 78031c8c8..bbeaa0fb7 100644 --- a/documentation/markdown/architecture/features/notifications.md +++ b/documentation/markdown/architecture/features/notifications.md @@ -96,15 +96,14 @@ It will pull the relevant subscriptions from the storage and call the stored `No For every subscription type, a `NotificationHandler` should be added to the `WaterfallHandler` that handles notifications for the specific type. -## WebSocketSubscription2021 +## WebSocketChannel2023 -To add support for [WebSocketSubscription2021](https://solidproject.org/TR/2022/websocket-subscription-2021-20220509) -notifications, +To add support for [WebSocketChannel2023](https://solid.github.io/notifications/websocket-channel-2023) notifications, components were added as described in the documentation above. For discovery, a `NotificationDescriber` was added with the corresponding settings. -As `SubscriptionType`, there is a specific `WebSocketSubscription2021` that contains all the necessary information. +As `NotificationChannelType`, there is a specific `WebSocketChannel2023Type` that contains all the necessary information. ### Handling notifications @@ -120,13 +119,13 @@ flowchart TB direction LR BaseNotificationGenerator("BaseNotificationGenerator
NotificationGenerator") BaseNotificationSerializer("BaseNotificationSerializer
NotificationSerializer") - WebSocket2021Emitter("WebSocket2021Emitter
WebSocket2021Emitter") - BaseNotificationGenerator --> BaseNotificationSerializer --> WebSocket2021Emitter + WebSocket2023Emitter("WebSocket2023Emitter
WebSocket2023Emitter") + BaseNotificationGenerator --> BaseNotificationSerializer --> WebSocket2023Emitter end ``` A `TypedNotificationHandler` is a handler that can be used to filter out subscriptions for a specific type, -making sure only WebSocketSubscription2021 subscriptions will be handled. +making sure only WebSocketChannel2023 subscriptions will be handled. A `ComposedNotificationHandler` combines 3 interfaces to handle the notifications: @@ -140,17 +139,17 @@ and also caches the result so it can be reused by multiple subscriptions. `urn:solid-server:default:BaseNotificationSerializer` converts the Notification to a JSON-LD representation and handles any necessary content negotiation based on the `accept` notification feature. -A `WebSocket2021Emitter` is a specific emitter that checks +A `WebSocket2023Emitter` is a specific emitter that checks whether the current open WebSockets correspond to the subscription. ### WebSockets ```mermaid flowchart TB - WebSocket2021Listener("WebSocket2021Listener
WebSocket2021Listener") - WebSocket2021Listener --> WebSocket2021ListenerArgs + WebSocket2023Listener("WebSocket2023Listener
WebSocket2023Listener") + WebSocket2023Listener --> WebSocket2023ListenerArgs - subgraph WebSocket2021ListenerArgs[" "] + subgraph WebSocket2023ListenerArgs[" "] direction LR NotificationChannelStorage("NotificationChannelStorage
NotificationChannelStorage") SequenceHandler("
SequenceHandler") @@ -160,17 +159,17 @@ flowchart TB subgraph SequenceHandlerArgs[" "] direction TB - WebSocket2021Storer("WebSocket2021Storer
WebSocket2021Storer") - WebSocket2021StateHandler("WebSocket2021StateHandler
BaseStateHandler") + WebSocket2023Storer("WebSocket2023Storer
WebSocket2023Storer") + WebSocket2023StateHandler("WebSocket2023StateHandler
BaseStateHandler") end ``` -To detect and store WebSocket connections, the `WebSocket2021Listener` is added as a listener to the HTTP server. +To detect and store WebSocket connections, the `WebSocket2023Listener` is added as a listener to the HTTP server. For all WebSocket connections that get opened, it verifies whether they correspond to an existing subscription. -If yes, the information gets sent out to its stored `WebSocket2021Handler`. +If yes, the information gets sent out to its stored `WebSocket2023Handler`. -In this case, this is a `SequenceHandler`, which contains a `WebSocket2021Storer` and a `BaseStateHandler`. -The `WebSocket2021Storer` will store the WebSocket in the same map used by the `WebSocket2021Emitter`, +In this case, this is a `SequenceHandler`, which contains a `WebSocket2023Storer` and a `BaseStateHandler`. +The `WebSocket2023Storer` will store the WebSocket in the same map used by the `WebSocket2023Emitter`, so that class can emit events later on, as mentioned above. The state handler will make sure that a notification gets sent out if the subscription has a `state` feature request, as defined in the notification specification. @@ -179,7 +178,7 @@ as defined in the notification specification. The additions required to support [WebHookSubscription2021](https://github.com/solid/notifications/blob/main/webhook-subscription-2021.md) -are quite similar to those needed for WebSocketSubscription2021: +are quite similar to those needed for WebSocketChannel2023: * For discovery, there is a `WebHookDescriber`, which is an extension of a `NotificationDescriber`. * The `WebHookSubscription2021` class contains all the necessary typing information. diff --git a/src/index.ts b/src/index.ts index ebc0643c5..fb9767caf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -326,14 +326,14 @@ export * from './server/notifications/WebHookSubscription2021/WebHookSubscriptio export * from './server/notifications/WebHookSubscription2021/WebHookUnsubscriber'; export * from './server/notifications/WebHookSubscription2021/WebHookWebId'; -// Server/Notifications/WebSocketSubscription2021 -export * from './server/notifications/WebSocketSubscription2021/WebSocket2021Emitter'; -export * from './server/notifications/WebSocketSubscription2021/WebSocket2021Handler'; -export * from './server/notifications/WebSocketSubscription2021/WebSocket2021Listener'; -export * from './server/notifications/WebSocketSubscription2021/WebSocket2021Storer'; -export * from './server/notifications/WebSocketSubscription2021/WebSocket2021Util'; -export * from './server/notifications/WebSocketSubscription2021/WebSocketMap'; -export * from './server/notifications/WebSocketSubscription2021/WebSocketSubscription2021'; +// Server/Notifications/WebSocketChannel2023 +export * from './server/notifications/WebSocketChannel2023/WebSocket2023Emitter'; +export * from './server/notifications/WebSocketChannel2023/WebSocket2023Handler'; +export * from './server/notifications/WebSocketChannel2023/WebSocket2023Listener'; +export * from './server/notifications/WebSocketChannel2023/WebSocket2023Storer'; +export * from './server/notifications/WebSocketChannel2023/WebSocket2023Util'; +export * from './server/notifications/WebSocketChannel2023/WebSocketMap'; +export * from './server/notifications/WebSocketChannel2023/WebSocketChannel2023Type'; // Server/Notifications export * from './server/notifications/ActivityEmitter'; diff --git a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter.ts b/src/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.ts similarity index 89% rename from src/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter.ts rename to src/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.ts index ae2bf629f..af2e8f251 100644 --- a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter.ts +++ b/src/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.ts @@ -6,11 +6,11 @@ import { NotificationEmitter } from '../NotificationEmitter'; import type { NotificationEmitterInput } from '../NotificationEmitter'; /** - * Emits notifications on WebSocketSubscription2021 subscription. + * Emits notifications on WebSocketChannel2023 subscription. * Uses the WebSockets found in the provided map. * The key should be the identifier of the matching channel. */ -export class WebSocket2021Emitter extends NotificationEmitter { +export class WebSocket2023Emitter extends NotificationEmitter { protected readonly logger = getLoggerFor(this); private readonly socketMap: SetMultiMap; diff --git a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Handler.ts b/src/server/notifications/WebSocketChannel2023/WebSocket2023Handler.ts similarity index 50% rename from src/server/notifications/WebSocketSubscription2021/WebSocket2021Handler.ts rename to src/server/notifications/WebSocketChannel2023/WebSocket2023Handler.ts index 9e22553f7..901930760 100644 --- a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Handler.ts +++ b/src/server/notifications/WebSocketChannel2023/WebSocket2023Handler.ts @@ -2,12 +2,12 @@ import type { WebSocket } from 'ws'; import { AsyncHandler } from '../../../util/handlers/AsyncHandler'; import type { NotificationChannel } from '../NotificationChannel'; -export interface WebSocket2021HandlerInput { +export interface WebSocket2023HandlerInput { channel: NotificationChannel; webSocket: WebSocket; } /** - * A handler that is called when a valid WebSocketSubscription2021 connection has been made. + * A handler that is called when a valid WebSocketChannel2023 connection has been made. */ -export abstract class WebSocket2021Handler extends AsyncHandler {} +export abstract class WebSocket2023Handler extends AsyncHandler {} diff --git a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Listener.ts b/src/server/notifications/WebSocketChannel2023/WebSocket2023Listener.ts similarity index 80% rename from src/server/notifications/WebSocketSubscription2021/WebSocket2021Listener.ts rename to src/server/notifications/WebSocketChannel2023/WebSocket2023Listener.ts index a6ad8a1ab..38fc2afb0 100644 --- a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Listener.ts +++ b/src/server/notifications/WebSocketChannel2023/WebSocket2023Listener.ts @@ -4,21 +4,21 @@ import type { InteractionRoute } from '../../../identity/interaction/routing/Int import { getLoggerFor } from '../../../logging/LogUtil'; import { WebSocketServerConfigurator } from '../../WebSocketServerConfigurator'; import type { NotificationChannelStorage } from '../NotificationChannelStorage'; -import type { WebSocket2021Handler } from './WebSocket2021Handler'; -import { parseWebSocketRequest } from './WebSocket2021Util'; +import type { WebSocket2023Handler } from './WebSocket2023Handler'; +import { parseWebSocketRequest } from './WebSocket2023Util'; /** - * Listens for WebSocket connections and verifies if they are valid WebSocketSubscription2021 connections, - * in which case its {@link WebSocket2021Handler} will be alerted. + * Listens for WebSocket connections and verifies if they are valid WebSocketChannel2023 connections, + * in which case its {@link WebSocket2023Handler} will be alerted. */ -export class WebSocket2021Listener extends WebSocketServerConfigurator { +export class WebSocket2023Listener extends WebSocketServerConfigurator { protected readonly logger = getLoggerFor(this); private readonly storage: NotificationChannelStorage; - private readonly handler: WebSocket2021Handler; + private readonly handler: WebSocket2023Handler; private readonly path: string; - public constructor(storage: NotificationChannelStorage, handler: WebSocket2021Handler, route: InteractionRoute) { + public constructor(storage: NotificationChannelStorage, handler: WebSocket2023Handler, route: InteractionRoute) { super(); this.storage = storage; this.handler = handler; diff --git a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Storer.ts b/src/server/notifications/WebSocketChannel2023/WebSocket2023Storer.ts similarity index 88% rename from src/server/notifications/WebSocketSubscription2021/WebSocket2021Storer.ts rename to src/server/notifications/WebSocketChannel2023/WebSocket2023Storer.ts index ee2d9551b..e6a035fc3 100644 --- a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Storer.ts +++ b/src/server/notifications/WebSocketChannel2023/WebSocket2023Storer.ts @@ -3,11 +3,11 @@ import { getLoggerFor } from '../../../logging/LogUtil'; import type { SetMultiMap } from '../../../util/map/SetMultiMap'; import { setSafeInterval } from '../../../util/TimerUtil'; import type { NotificationChannelStorage } from '../NotificationChannelStorage'; -import type { WebSocket2021HandlerInput } from './WebSocket2021Handler'; -import { WebSocket2021Handler } from './WebSocket2021Handler'; +import type { WebSocket2023HandlerInput } from './WebSocket2023Handler'; +import { WebSocket2023Handler } from './WebSocket2023Handler'; /** - * Keeps track of the WebSockets that were opened for a WebSocketSubscription2021 channel. + * Keeps track of the WebSockets that were opened for a WebSocketChannel2023 channel. * The WebSockets are stored in the map using the identifier of the matching channel. * * `cleanupTimer` defines in minutes how often the stored WebSockets are closed @@ -15,7 +15,7 @@ import { WebSocket2021Handler } from './WebSocket2021Handler'; * Defaults to 60 minutes. * Open WebSockets will not receive notifications if their channel expired. */ -export class WebSocket2021Storer extends WebSocket2021Handler { +export class WebSocket2023Storer extends WebSocket2023Handler { protected readonly logger = getLoggerFor(this); private readonly storage: NotificationChannelStorage; @@ -34,7 +34,7 @@ export class WebSocket2021Storer extends WebSocket2021Handler { timer.unref(); } - public async handle({ webSocket, channel }: WebSocket2021HandlerInput): Promise { + public async handle({ webSocket, channel }: WebSocket2023HandlerInput): Promise { this.socketMap.add(channel.id, webSocket); webSocket.on('error', (): boolean => this.socketMap.deleteEntry(channel.id, webSocket)); webSocket.on('close', (): boolean => this.socketMap.deleteEntry(channel.id, webSocket)); diff --git a/src/server/notifications/WebSocketSubscription2021/WebSocket2021Util.ts b/src/server/notifications/WebSocketChannel2023/WebSocket2023Util.ts similarity index 100% rename from src/server/notifications/WebSocketSubscription2021/WebSocket2021Util.ts rename to src/server/notifications/WebSocketChannel2023/WebSocket2023Util.ts diff --git a/src/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021.ts b/src/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type.ts similarity index 55% rename from src/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021.ts rename to src/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type.ts index af5427197..3692d9e3d 100644 --- a/src/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021.ts +++ b/src/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type.ts @@ -5,45 +5,45 @@ import { getLoggerFor } from '../../../logging/LogUtil'; import { NOTIFY } from '../../../util/Vocabularies'; import { BaseChannelType } from '../BaseChannelType'; import type { NotificationChannel } from '../NotificationChannel'; -import { generateWebSocketUrl } from './WebSocket2021Util'; +import { generateWebSocketUrl } from './WebSocket2023Util'; /** - * A {@link NotificationChannel} containing the necessary fields for a WebSocketSubscription2021 channel. + * A {@link NotificationChannel} containing the necessary fields for a WebSocketChannel2023 channel. */ -export interface WebSocketSubscription2021Channel extends NotificationChannel { +export interface WebSocketChannel2023 extends NotificationChannel { /** - * The "notify:WebSocketSubscription2021" type. + * The "notify:WebSocketChannel2023" type. */ - type: typeof NOTIFY.WebSocketSubscription2021; + type: typeof NOTIFY.WebSocketChannel2023; /** * The WebSocket through which the channel will send notifications. */ - source: string; + receiveFrom: string; } -export function isWebSocket2021Channel(channel: NotificationChannel): channel is WebSocketSubscription2021Channel { - return channel.type === NOTIFY.WebSocketSubscription2021; +export function isWebSocket2023Channel(channel: NotificationChannel): channel is WebSocketChannel2023 { + return channel.type === NOTIFY.WebSocketChannel2023; } /** - * The notification channel type WebSocketSubscription2021 as described in + * The notification channel type WebSocketChannel2023 as described in * https://solidproject.org/TR/websocket-subscription-2021 * * Requires read permissions on a resource to be able to receive notifications. */ -export class WebSocketSubscription2021 extends BaseChannelType { +export class WebSocketChannel2023Type extends BaseChannelType { protected readonly logger = getLoggerFor(this); public constructor(route: InteractionRoute, features?: string[]) { - super(NOTIFY.terms.WebSocketSubscription2021, route, features); + super(NOTIFY.terms.WebSocketChannel2023, route, features); } - public async initChannel(data: Store, credentials: Credentials): Promise { + public async initChannel(data: Store, credentials: Credentials): Promise { const channel = await super.initChannel(data, credentials); return { ...channel, - type: NOTIFY.WebSocketSubscription2021, - source: generateWebSocketUrl(this.path, channel.id), + type: NOTIFY.WebSocketChannel2023, + receiveFrom: generateWebSocketUrl(this.path, channel.id), }; } } diff --git a/src/server/notifications/WebSocketSubscription2021/WebSocketMap.ts b/src/server/notifications/WebSocketChannel2023/WebSocketMap.ts similarity index 100% rename from src/server/notifications/WebSocketSubscription2021/WebSocketMap.ts rename to src/server/notifications/WebSocketChannel2023/WebSocketMap.ts diff --git a/src/util/Vocabularies.ts b/src/util/Vocabularies.ts index 95b045c2c..30b93327a 100644 --- a/src/util/Vocabularies.ts +++ b/src/util/Vocabularies.ts @@ -197,6 +197,7 @@ export const NOTIFY = createVocabulary('http://www.w3.org/ns/solid/notifications 'endAt', 'feature', 'rate', + 'receiveFrom', 'startAt', 'state', 'subscription', @@ -206,7 +207,7 @@ export const NOTIFY = createVocabulary('http://www.w3.org/ns/solid/notifications 'webid', 'WebHookSubscription2021', - 'WebSocketSubscription2021', + 'WebSocketChannel2023', ); export const OIDC = createVocabulary('http://www.w3.org/ns/solid/oidc#', diff --git a/test/integration/WebSocketSubscription2021.test.ts b/test/integration/WebSocketChannel2023.test.ts similarity index 91% rename from test/integration/WebSocketSubscription2021.test.ts rename to test/integration/WebSocketChannel2023.test.ts index 1d414ce4d..8ba824eca 100644 --- a/test/integration/WebSocketSubscription2021.test.ts +++ b/test/integration/WebSocketChannel2023.test.ts @@ -14,17 +14,16 @@ import { getPresetConfigPath, getTestConfigPath, getTestFolder, - instantiateFromConfig, - removeFolder, + instantiateFromConfig, removeFolder, } from './Config'; import quad = DataFactory.quad; import namedNode = DataFactory.namedNode; -const port = getPort('WebSocketSubscription2021'); +const port = getPort('WebSocketChannel2023'); const baseUrl = `http://localhost:${port}/`; -const notificationType = NOTIFY.WebSocketSubscription2021; +const notificationType = NOTIFY.WebSocketChannel2023; -const rootFilePath = getTestFolder('WebSocketSubscription2021'); +const rootFilePath = getTestFolder('WebSocketChannel2023'); const stores: [string, any][] = [ [ 'in-memory storage', { configs: [ 'storage/backend/memory.json', 'util/resource-locker/memory.json' ], @@ -37,7 +36,7 @@ const stores: [string, any][] = [ }], ]; -describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', (name, { configs, teardown }): void => { +describe.each(stores)('A server supporting WebSocketChannel2023 using %s', (name, { configs, teardown }): void => { let app: App; let store: ResourceStore; const webId = 'http://example.com/card/#me'; @@ -89,7 +88,7 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', // Find the notification channel for websockets const subscriptions = quads.getObjects(storageDescriptionUrl, NOTIFY.terms.subscription, null); const websocketSubscriptions = subscriptions.filter((channel): boolean => quads.has( - quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebSocketSubscription2021`)), + quad(channel as NamedNode, NOTIFY.terms.channelType, namedNode(`${NOTIFY.namespace}WebSocketChannel2023`)), )); expect(websocketSubscriptions).toHaveLength(1); subscriptionUrl = websocketSubscriptions[0].value; @@ -97,7 +96,7 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', it('supports subscribing.', async(): Promise => { const response = await subscribe(notificationType, webId, subscriptionUrl, topic); - webSocketUrl = (response as any).source; + webSocketUrl = (response as any).receiveFrom; }); it('emits Created events.', async(): Promise => { @@ -167,7 +166,7 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', const channel = { '@context': [ 'https://www.w3.org/ns/solid/notification/v1' ], - type: NOTIFY.WebSocketSubscription2021, + type: notificationType, topic: restricted, }; @@ -199,9 +198,9 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', }); expect(response.status).toBe(201); - const { source } = await subscribe(notificationType, webId, subscriptionUrl, topic, { state: 'abc' }) as any; + const { receiveFrom } = await subscribe(notificationType, webId, subscriptionUrl, topic, { state: 'abc' }) as any; - const socket = new WebSocket(source); + const socket = new WebSocket(receiveFrom); const notificationPromise = new Promise((resolve): any => socket.on('message', resolve)); await new Promise((resolve): any => socket.on('open', resolve)); @@ -213,10 +212,10 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', }); it('removes expired channels.', async(): Promise => { - const { source } = + const { receiveFrom } = await subscribe(notificationType, webId, subscriptionUrl, topic, { endAt: '1988-03-09T14:48:00.000Z' }) as any; - const socket = new WebSocket(source); + const socket = new WebSocket(receiveFrom); const messagePromise = new Promise((resolve): any => socket.on('message', resolve)); await new Promise((resolve): any => socket.on('close', resolve)); @@ -245,7 +244,8 @@ describe.each(stores)('A server supporting WebSocketSubscription2021 using %s', const parser = new Parser({ baseIRI: subscriptionUrl }); const quads = new Store(parser.parse(await response.text())); - expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ NOTIFY.terms.WebSocketSubscription2021 ]); + expect(quads.getObjects(null, RDF.terms.type, null)).toEqual([ NOTIFY.terms.WebSocketChannel2023 ]); expect(quads.getObjects(null, NOTIFY.terms.topic, null)).toEqual([ namedNode(topic) ]); + expect(quads.countQuads(null, NOTIFY.terms.receiveFrom, null, null)).toBe(1); }); }); diff --git a/test/unit/server/notifications/KeyValueChannelStorage.test.ts b/test/unit/server/notifications/KeyValueChannelStorage.test.ts index 8d7fc7465..2082e9a20 100644 --- a/test/unit/server/notifications/KeyValueChannelStorage.test.ts +++ b/test/unit/server/notifications/KeyValueChannelStorage.test.ts @@ -27,9 +27,9 @@ describe('A KeyValueChannelStorage', (): void => { beforeEach(async(): Promise => { resetAllMocks(); channel = { - id: `WebSocketSubscription2021:${v4()}:http://example.com/foo`, + id: `WebSocketChannel2023:${v4()}:http://example.com/foo`, topic, - type: 'WebSocketSubscription2021', + type: 'WebSocketChannel2023', }; internalMap = new Map(); diff --git a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter.test.ts b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.test.ts similarity index 92% rename from test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter.test.ts rename to test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.test.ts index 2527c5aac..0a50ecd73 100644 --- a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter.test.ts +++ b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Emitter.test.ts @@ -3,12 +3,12 @@ import type { WebSocket } from 'ws'; import { BasicRepresentation } from '../../../../../src/http/representation/BasicRepresentation'; import type { NotificationChannel } from '../../../../../src/server/notifications/NotificationChannel'; import { - WebSocket2021Emitter, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Emitter'; + WebSocket2023Emitter, +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Emitter'; import type { SetMultiMap } from '../../../../../src/util/map/SetMultiMap'; import { WrappedSetMultiMap } from '../../../../../src/util/map/WrappedSetMultiMap'; -describe('A WebSocket2021Emitter', (): void => { +describe('A WebSocket2023Emitter', (): void => { const channel: NotificationChannel = { id: 'id', topic: 'http://example.com/foo', @@ -17,7 +17,7 @@ describe('A WebSocket2021Emitter', (): void => { let webSocket: jest.Mocked; let socketMap: SetMultiMap; - let emitter: WebSocket2021Emitter; + let emitter: WebSocket2023Emitter; beforeEach(async(): Promise => { webSocket = new EventEmitter() as any; @@ -26,7 +26,7 @@ describe('A WebSocket2021Emitter', (): void => { socketMap = new WrappedSetMultiMap(); - emitter = new WebSocket2021Emitter(socketMap); + emitter = new WebSocket2023Emitter(socketMap); }); it('emits notifications to the stored WebSockets.', async(): Promise => { diff --git a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Listener.test.ts b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Listener.test.ts similarity index 89% rename from test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Listener.test.ts rename to test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Listener.test.ts index d8d2bc8fc..a3f316587 100644 --- a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Listener.test.ts +++ b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Listener.test.ts @@ -10,11 +10,11 @@ import type { NotificationChannelStorage, } from '../../../../../src/server/notifications/NotificationChannelStorage'; import type { - WebSocket2021Handler, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Handler'; + WebSocket2023Handler, +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Handler'; import { - WebSocket2021Listener, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Listener'; + WebSocket2023Listener, +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Listener'; import { flushPromises } from '../../../../util/Util'; jest.mock('ws', (): any => ({ @@ -26,7 +26,7 @@ jest.mock('ws', (): any => ({ })), })); -describe('A WebSocket2021Listener', (): void => { +describe('A WebSocket2023Listener', (): void => { const channel: NotificationChannel = { id: 'id', topic: 'http://example.com/foo', @@ -37,9 +37,9 @@ describe('A WebSocket2021Listener', (): void => { let webSocket: WebSocket; let upgradeRequest: HttpRequest; let storage: jest.Mocked; - let handler: jest.Mocked; + let handler: jest.Mocked; const route = new AbsolutePathInteractionRoute('http://example.com/foo'); - let listener: WebSocket2021Listener; + let listener: WebSocket2023Listener; beforeEach(async(): Promise => { server = new EventEmitter() as any; @@ -57,7 +57,7 @@ describe('A WebSocket2021Listener', (): void => { handleSafe: jest.fn(), } as any; - listener = new WebSocket2021Listener(storage, handler, route); + listener = new WebSocket2023Listener(storage, handler, route); await listener.handle(server); }); diff --git a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Storer.test.ts b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Storer.test.ts similarity index 90% rename from test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Storer.test.ts rename to test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Storer.test.ts index bfc1ab384..1b49be672 100644 --- a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Storer.test.ts +++ b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Storer.test.ts @@ -6,13 +6,13 @@ import type { } from '../../../../../src/server/notifications/NotificationChannelStorage'; import { - WebSocket2021Storer, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Storer'; + WebSocket2023Storer, +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Storer'; import type { SetMultiMap } from '../../../../../src/util/map/SetMultiMap'; import { WrappedSetMultiMap } from '../../../../../src/util/map/WrappedSetMultiMap'; import { flushPromises } from '../../../../util/Util'; -describe('A WebSocket2021Storer', (): void => { +describe('A WebSocket2023Storer', (): void => { const channel: NotificationChannel = { id: 'id', topic: 'http://example.com/foo', @@ -21,7 +21,7 @@ describe('A WebSocket2021Storer', (): void => { let webSocket: jest.Mocked; let storage: jest.Mocked; let socketMap: SetMultiMap; - let storer: WebSocket2021Storer; + let storer: WebSocket2023Storer; beforeEach(async(): Promise => { webSocket = new EventEmitter() as any; @@ -33,7 +33,7 @@ describe('A WebSocket2021Storer', (): void => { socketMap = new WrappedSetMultiMap(); - storer = new WebSocket2021Storer(storage, socketMap); + storer = new WebSocket2023Storer(storage, socketMap); }); it('stores WebSockets.', async(): Promise => { @@ -60,7 +60,7 @@ describe('A WebSocket2021Storer', (): void => { jest.useFakeTimers(); // Need to create class after fake timers have been enabled - storer = new WebSocket2021Storer(storage, socketMap); + storer = new WebSocket2023Storer(storage, socketMap); const webSocket2: jest.Mocked = new EventEmitter() as any; webSocket2.close = jest.fn(); diff --git a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Util.test.ts b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Util.test.ts similarity index 88% rename from test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Util.test.ts rename to test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Util.test.ts index a8eca294e..78530885b 100644 --- a/test/unit/server/notifications/WebSocketSubscription2021/WebSocket2021Util.test.ts +++ b/test/unit/server/notifications/WebSocketChannel2023/WebSocket2023Util.test.ts @@ -1,9 +1,9 @@ import type { IncomingMessage } from 'http'; import { generateWebSocketUrl, parseWebSocketRequest, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Util'; +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Util'; -describe('WebSocket2021Util', (): void => { +describe('WebSocket2023Util', (): void => { describe('#generateWebSocketUrl', (): void => { it('generates a WebSocket link with a query parameter.', async(): Promise => { expect(generateWebSocketUrl('http://example.com/', '123456')).toBe('ws://example.com/?auth=123456'); diff --git a/test/unit/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021.test.ts b/test/unit/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type.test.ts similarity index 63% rename from test/unit/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021.test.ts rename to test/unit/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type.test.ts index 967c2f73d..4643bfcb1 100644 --- a/test/unit/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021.test.ts +++ b/test/unit/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type.test.ts @@ -6,14 +6,14 @@ import type { NotificationChannel } from '../../../../../src/server/notification import { generateWebSocketUrl, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocket2021Util'; +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocket2023Util'; import type { - WebSocketSubscription2021Channel, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021'; + WebSocketChannel2023, +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type'; import { - isWebSocket2021Channel, - WebSocketSubscription2021, -} from '../../../../../src/server/notifications/WebSocketSubscription2021/WebSocketSubscription2021'; + isWebSocket2023Channel, + WebSocketChannel2023Type, +} from '../../../../../src/server/notifications/WebSocketChannel2023/WebSocketChannel2023Type'; import { NOTIFY, RDF } from '../../../../../src/util/Vocabularies'; import quad = DataFactory.quad; import blankNode = DataFactory.blankNode; @@ -21,35 +21,35 @@ import namedNode = DataFactory.namedNode; jest.mock('uuid', (): any => ({ v4: (): string => '4c9b88c1-7502-4107-bb79-2a3a590c7aa3' })); -describe('A WebSocketSubscription2021', (): void => { +describe('A WebSocketChannel2023', (): void => { let data: Store; - let channel: WebSocketSubscription2021Channel; + let channel: WebSocketChannel2023; const subject = blankNode(); const topic = 'https://storage.example/resource'; const route = new AbsolutePathInteractionRoute('http://example.com/foo'); - let channelType: WebSocketSubscription2021; + let channelType: WebSocketChannel2023Type; beforeEach(async(): Promise => { data = new Store(); - data.addQuad(quad(subject, RDF.terms.type, NOTIFY.terms.WebSocketSubscription2021)); + data.addQuad(quad(subject, RDF.terms.type, NOTIFY.terms.WebSocketChannel2023)); data.addQuad(quad(subject, NOTIFY.terms.topic, namedNode(topic))); const id = 'http://example.com/foo/4c9b88c1-7502-4107-bb79-2a3a590c7aa3'; channel = { id, - type: NOTIFY.WebSocketSubscription2021, + type: NOTIFY.WebSocketChannel2023, topic, - source: generateWebSocketUrl(route.getPath(), id), + receiveFrom: generateWebSocketUrl(route.getPath(), id), }; - channelType = new WebSocketSubscription2021(route); + channelType = new WebSocketChannel2023Type(route); }); it('exposes a utility function to verify if a channel is a websocket channel.', async(): Promise => { - expect(isWebSocket2021Channel(channel)).toBe(true); + expect(isWebSocket2023Channel(channel)).toBe(true); (channel as NotificationChannel).type = 'something else'; - expect(isWebSocket2021Channel(channel)).toBe(false); + expect(isWebSocket2023Channel(channel)).toBe(false); }); it('correctly parses notification channel bodies.', async(): Promise => { diff --git a/test/util/Util.ts b/test/util/Util.ts index 6047e13f4..f25491803 100644 --- a/test/util/Util.ts +++ b/test/util/Util.ts @@ -31,7 +31,7 @@ const portNames = [ 'Subdomains', 'WebHookSubscription2021', 'WebHookSubscription2021-client', - 'WebSocketSubscription2021', + 'WebSocketChannel2023', // Unit 'BaseServerFactory',