Skip to content

Commit b01cc1a

Browse files
Y-SindoCopilot
andcommitted
Add August 2026 preview support for Web PubSub Chat
Generate from the corrected specification and update samples and documentation. Verify the complete sync/async live suite in Central US EUAP, remove the routing workaround, and upload sanitized latest-version recordings. Track the independent upstream async paging limitation without customization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e094123 commit b01cc1a

23 files changed

Lines changed: 4842 additions & 154 deletions
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Web PubSub Chat development constraints
2+
3+
Before changing tests, recording tests, regenerating, or releasing this package,
4+
read [KNOWN_ISSUES.md](KNOWN_ISSUES.md) for the pending upstream Java
5+
generator paging fix. Do not add a paging customization; preserve strict
6+
regression assertions and verify the upstream fix after regeneration.
7+
8+
Run live tests against a Chat-enabled resource in the TTL = 7 days subscription.
9+
The server routing fix was verified in Central US EUAP on 2026-10-13 using the
10+
complete sync/async live suite. All operations, including setup and cleanup,
11+
use `2026-08-01-preview`; do not restore legacy-version clients or routing skips.
12+
Upload sanitized recordings and verify clean-cache playback after test changes.
13+
14+
Before publishing an issue, PR, or team message for this package, show the user
15+
the destination and exact draft and obtain explicit approval.

‎sdk/webpubsub/azure-messaging-webpubsub-chat/CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,20 @@
44

55
### Features Added
66

7+
- Added support for service API version `2026-08-01-preview`, now the default service version.
8+
- Added synchronous and asynchronous operations to list rooms, users, and rooms associated with a user.
9+
- Added topic creation, replacement, retrieval, update, soft deletion, and listing.
10+
- Added `ChatTopic`, `ChatTopicState`, and the read-only `ChatUserRoom` projection.
11+
712
### Breaking Changes
813

914
### Bugs Fixed
1015

1116
### Other Changes
1217

18+
- Verified all existing and new operations end to end with `2026-08-01-preview` in Central US EUAP; removed the temporary server routing workaround and restored the complete live/playback suite.
19+
- Tracked the upstream typed asynchronous page-size defect in [microsoft/typespec#12149](https://github.com/microsoft/typespec/issues/12149). No paging customization is applied; tests temporarily use protocol overloads for asynchronous page-size checks.
20+
1321
## 1.0.0-beta.1 (2026-09-15)
1422

1523
- Azure WebPubSubChat client library for Java. This package contains Microsoft Azure WebPubSubChat client library.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Web PubSub Chat SDK known generator issues
2+
3+
## Typed asynchronous paging ignores the requested page size
4+
5+
- **Tracking issue:** [microsoft/typespec#12149](https://github.com/microsoft/typespec/issues/12149).
6+
- **Status:** Awaiting an upstream Java generator fix; reproduced with
7+
`@azure-tools/typespec-java` 0.48.0 on 2026-10-09.
8+
- **User decision:** Do not add a paging customization or manually repair
9+
generated SDK code. Wait for the generator team to fix the implementation.
10+
11+
The typed asynchronous paged convenience methods accept `pageSizeParam` but
12+
discard it when delegating to `PagedFlux<BinaryData>`. For example,
13+
`asyncClient.listRoomsForUser("alice").byPage(1)` does not send `maxpagesize=1`.
14+
Default continuation-token paging still works; the page-size override is
15+
ignored. Synchronous typed paging forwards the page size correctly.
16+
17+
This affects both existing operations (`listRoles`, `listRoomMembers`,
18+
`listMessages`) and the new operations (`listRooms`, `listTopics`, `listUsers`,
19+
`listRoomsForUser`). The defect predates this package's August API upgrade; the
20+
first affected generator release has not been determined.
21+
22+
### Approved temporary test workaround
23+
24+
The user approved disabling only
25+
`WebPubSubChatPaginationTests.asyncPageSizeReachesFirstAndNextRequests`; its
26+
seven strict cases and assertions remain intact. New async live pagination tests
27+
use the existing protocol overloads, such as
28+
`asyncClient.listTopics(roomId, new RequestOptions()).byPage(1)`, and still assert
29+
one item per page and follow continuation requests. Default typed async
30+
collection/model coverage remains enabled. No production paging customization
31+
or generated-code repair is applied.
32+
33+
The mock suite also verifies first and next request page sizes for all seven
34+
protocol async list methods. Passing these tests does not mean the typed async
35+
generator defect is fixed.
36+
37+
The implementation belongs to the shared
38+
[Java generator in microsoft/typespec](https://github.com/microsoft/typespec/blob/main/packages/http-client-java/generator/http-client-generator-core/src/main/java/com/microsoft/typespec/http/client/generator/core/template/ConvenienceAsyncMethodTemplate.java).
39+
The original [Azure/typespec-azure#5657](https://github.com/Azure/typespec-azure/issues/5657)
40+
was filed in the wrong repository and is closed.
41+
42+
### Checking whether it has been fixed
43+
44+
1. Check the tracking issue and the version of `@azure-tools/typespec-java` in
45+
`eng/emitter-package.json`. An issue being closed does not prove that the
46+
installed emitter includes the fix.
47+
2. After the repository adopts a generator release containing the fix,
48+
regenerate the package using its pinned `tsp-location.yaml`. Do not bypass
49+
the issue by adding a customization.
50+
3. Remove the issue-linked `@Disabled` annotation from
51+
`asyncPageSizeReachesFirstAndNextRequests`, then run the strict,
52+
credential-free regression tests:
53+
54+
```powershell
55+
mvn -f sdk\webpubsub\azure-messaging-webpubsub-chat\pom.xml test "-Dtest=WebPubSubChatPaginationTests" "-Dgpg.skip=true" "-Drevapi.skip=true"
56+
```
57+
58+
`WebPubSubChatPaginationTests` covers all seven sync and async list operations.
59+
It asserts `maxpagesize=1` on **both first-page and continuation requests**,
60+
and checks that the corrected `listRoomsForUser` continuation overload sends
61+
a query parameter. The original 16-case reproduction produced seven async
62+
failures and nine passes. The protocol async cases were added for the
63+
approved test workaround. Do not weaken the assertions or accept skipped async
64+
page-size cases as evidence of a fix.
65+
4. Verify the new sync/async live pagination scenarios, then verify sanitized
66+
recording playback using the persisted `assets.json` tag. Check actual page
67+
sizes and continuation requests, not only whether a non-empty page exists.
68+
5. Only mark this issue resolved after the generated code and all strict
69+
regression cases pass. Switch async live page-size checks back to the typed
70+
overloads and remove the temporary test workaround at that point.
71+
72+
### Server routing fix is independent
73+
74+
The server routing issue was verified fixed in Central US EUAP on 2026-10-13:
75+
all 14 sync/async live scenarios passed with `2026-08-01-preview`, including
76+
existing operations and setup/cleanup. The routing workaround and its temporary
77+
skill have been removed. This does not fix the typed async paging generator
78+
defect; retain its strict regression cases and the protocol paging workaround.

‎sdk/webpubsub/azure-messaging-webpubsub-chat/README.md‎

Lines changed: 155 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ Use this client library in an application server to:
66

77
- Create and manage Chat roles and permissions.
88
- Create users, rooms, and room memberships.
9+
- List rooms and users in a hub, or list the rooms associated with a user.
10+
- Create, get, update, list, and soft delete topics in a room.
911
- Get room conversations and query persisted message history.
1012
- Update and delete persisted messages.
1113
- Generate client access credentials for Chat WebSocket clients.
@@ -21,19 +23,22 @@ Use this client library in an application server to:
2123
- An [Azure Web PubSub resource][create_instance].
2224
- A Web PubSub hub with [Chat enabled][enable_chat].
2325

24-
### 1. Add the package to your project
26+
### Install the package
27+
28+
The following dependency shows the current development version. It has not been
29+
released to Maven Central; build it locally when evaluating the new API.
2530

2631
[//]: # ({x-version-update-start;com.azure:azure-messaging-webpubsub-chat;current})
2732
```xml
2833
<dependency>
2934
<groupId>com.azure</groupId>
3035
<artifactId>azure-messaging-webpubsub-chat</artifactId>
31-
<version>1.0.0-beta.1</version>
36+
<version>1.0.0-beta.2</version>
3237
</dependency>
3338
```
3439
[//]: # ({x-version-update-end})
3540

36-
### 2. Create and authenticate a `WebPubSubChatServiceClient`
41+
### Create and authenticate a client
3742

3843
The client supports a connection string, an `AzureKeyCredential`, or a Microsoft Entra ID token credential. The hub passed to the client must have Chat enabled.
3944

@@ -98,6 +103,19 @@ A user represents an application identity that can send and receive messages. A
98103

99104
A room groups users together and is the primary organizational unit for chat interactions. Every room has an automatically created default conversation.
100105

106+
### Topic
107+
108+
A topic is a named conversation in a room. Each topic has a title, creation time,
109+
creator, conversation ID, ETag, and lifecycle state. `ChatTopicState` includes
110+
`NORMAL`, `ARCHIVED`, and `SOFT_DELETED`. The August API adds topic management;
111+
topic deletion is a soft delete rather than a room deletion.
112+
113+
### User's rooms
114+
115+
`listRoomsForUser` returns read-only `ChatUserRoom` projections of the rooms
116+
associated with a user. A projection contains the room ID, title, default
117+
conversation ID, and ETag; it does not provide a separate room lifecycle.
118+
101119
### Room member
102120

103121
A room member represents a user added to a room. Membership controls which users can receive and send messages in the room. Each room member is assigned a room role.
@@ -131,61 +149,174 @@ String memberRole = BuiltInChatRoles.ROOM_MEMBER;
131149
ChatPermission publishPermission = ChatPermission.ROOM_PUBLISH_MESSAGE;
132150
```
133151

134-
### Create and list a custom role
152+
The following examples are independent operations. Where an operation refers to
153+
`general`, `alice`, or `announcements`, the corresponding resources must already
154+
exist. All examples use the default `2026-08-01-preview` API version.
155+
156+
### Create a custom role
135157

136-
```java readme-sample-manageChatRoles
158+
```java readme-sample-createChatRole
137159
ChatRole moderator = new ChatRole(Arrays.asList(ChatPermission.ROOM_HISTORY,
138160
ChatPermission.ROOM_REMOVE_USER, ChatPermission.ROOM_PUBLISH_MESSAGE));
139161
client.createOrReplaceRole("room.moderator", moderator);
162+
```
140163

164+
### List roles
165+
166+
```java readme-sample-listChatRoles
141167
client.listRoles().forEach(role -> System.out.println(role.getName()));
168+
```
169+
170+
### Delete a custom role
171+
172+
```java readme-sample-deleteChatRole
142173
client.deleteRole("room.moderator");
143174
```
144175

145-
### Create a user, room, and room membership
176+
Remove references to a custom role before deleting it.
177+
178+
### Create a user
179+
180+
```java readme-sample-createChatUser
181+
client.createOrReplaceUser("alice", new HumanChatUser("Alice", BuiltInChatRoles.USER_NORMAL));
182+
```
146183

147-
```java readme-sample-manageChatRooms
148-
client.createOrReplaceRole("user.room_creator",
149-
new ChatRole(Arrays.asList(ChatPermission.USER_CREATE_ROOM)));
150-
client.createOrReplaceRole("room.contributor",
151-
new ChatRole(Arrays.asList(ChatPermission.ROOM_PUBLISH_MESSAGE)));
152-
client.createOrReplaceUser("alice", new HumanChatUser("Alice", "user.room_creator"));
184+
### Create a room
153185

186+
```java readme-sample-createChatRoom
154187
ChatRoom room = client.createOrReplaceRoom("general", new ChatRoom("General"));
188+
String defaultConversationId = room.getDefaultConversation();
189+
```
190+
191+
### Add a room member
192+
193+
```java readme-sample-addChatRoomMember
155194
ChatRoomMember member = client.createOrReplaceRoomMember(
156-
room.getId(), "alice", new ChatRoomMember("room.contributor"));
195+
"general", "alice", new ChatRoomMember(BuiltInChatRoles.ROOM_MEMBER));
157196
System.out.printf("%s: %s%n", member.getUserId(), member.getRoleName());
197+
```
198+
199+
### List rooms
158200

159-
client.deleteRoom(room.getId());
160-
client.deleteUser("alice");
161-
client.deleteRole("room.contributor");
162-
client.deleteRole("user.room_creator");
201+
```java readme-sample-listChatRooms
202+
client.listRooms().forEach(room -> System.out.printf("%s: %s%n", room.getId(), room.getTitle()));
163203
```
164204

165-
Delete dependent resources in reverse order when they are no longer needed: room, user, and then roles.
205+
### List users
206+
207+
```java readme-sample-listChatUsers
208+
client.listUsers().forEach(user -> System.out.printf("%s: %s%n", user.getId(), user.getNickname()));
209+
```
210+
211+
### List rooms for a user
212+
213+
```java readme-sample-listChatRoomsForUser
214+
client.listRoomsForUser("alice").forEach(room ->
215+
System.out.printf("%s: %s%n", room.getId(), room.getTitle()));
216+
```
217+
218+
List operations return `PagedIterable` on the synchronous client and `PagedFlux`
219+
on the asynchronous client. Iteration fetches subsequent pages automatically.
220+
To process synchronous results page by page, use `iterableByPage(pageSize)`.
221+
222+
### Create a topic
223+
224+
The parent room must already exist.
225+
226+
```java readme-sample-createChatTopic
227+
ChatTopic topic = client.createOrReplaceTopic("general", "announcements",
228+
new ChatTopic().setTitle("Announcements"));
229+
String conversationId = topic.getConversationId();
230+
```
231+
232+
Use the returned conversation ID when a Chat WebSocket client sends messages to
233+
the topic. This server-side library manages resources and persisted messages;
234+
it is not a WebSocket chat client.
235+
236+
### Get a topic
237+
238+
```java readme-sample-getChatTopic
239+
ChatTopic topic = client.getTopic("general", "announcements");
240+
System.out.printf("%s: %s%n", topic.getTitle(), topic.getState());
241+
```
242+
243+
### Update a topic
244+
245+
Only explicitly set properties are included in the merge-patch request.
246+
Use the overload accepting `MatchConditions` and the current ETag to prevent
247+
overwriting another caller's changes.
248+
249+
```java readme-sample-updateChatTopic
250+
ChatTopic updated = client.updateTopic("general", "announcements",
251+
new ChatTopic().setTitle("Archived announcements").setState(ChatTopicState.ARCHIVED));
252+
```
253+
254+
### List topics
255+
256+
```java readme-sample-listChatTopics
257+
client.listTopics("general").forEach(topic ->
258+
System.out.printf("%s: %s%n", topic.getId(), topic.getTitle()));
259+
```
260+
261+
### Soft delete a topic
262+
263+
```java readme-sample-deleteChatTopic
264+
client.deleteTopic("general", "announcements");
265+
```
166266

167267
### List persisted messages
168268

169269
```java readme-sample-listChatMessages
170-
ChatRoom room = client.getRoom("general");
171-
client.listMessages(room.getDefaultConversation()).forEach(message ->
270+
String conversationId = "<conversation-id>";
271+
client.listMessages(conversationId).forEach(message ->
172272
System.out.printf("%s: %s%n", message.getCreatedBy(), message.getContent().getText()));
173273
```
174274

275+
Use a conversation ID returned by room or topic creation. Message history
276+
queries return messages from latest to earliest.
277+
175278
### Use the asynchronous client
176279

177280
```java readme-sample-createAsyncChatClient
178281
WebPubSubChatServiceAsyncClient asyncClient = new WebPubSubChatServiceClientBuilder()
179282
.connectionString("<web-pubsub-connection-string>")
180283
.hub("chat")
181284
.buildAsyncClient();
285+
```
182286

183-
asyncClient.listRoles().subscribe(role -> System.out.println(role.getName()));
287+
Subscribe to the returned publisher to execute an asynchronous operation, and
288+
handle errors explicitly:
289+
290+
```java readme-sample-listChatTopicsAsync
291+
asyncClient.listTopics("general").subscribe(
292+
topic -> System.out.println(topic.getTitle()),
293+
error -> System.err.println("Could not list topics: " + error.getMessage()));
294+
```
295+
296+
#### Known asynchronous page-size limitation
297+
298+
The generator currently ignores `byPage(pageSize)` on typed asynchronous
299+
collections. Default continuation paging is unaffected. Until
300+
[microsoft/typespec#12149](https://github.com/microsoft/typespec/issues/12149)
301+
is fixed in the emitter used by this package, use the existing protocol overload
302+
when an explicit asynchronous page size is required:
303+
304+
```java readme-sample-listChatTopicsAsyncByPage
305+
asyncClient.listTopics("general", new RequestOptions()).byPage(10).subscribe(
306+
page -> page.getValue().forEach(data -> System.out.println(data.toObject(ChatTopic.class).getTitle())),
307+
error -> System.err.println("Could not list topic pages: " + error.getMessage()));
184308
```
185309

310+
See [known generator issues](KNOWN_ISSUES.md) for verification and removal of the
311+
temporary test workaround. No paging customization is applied.
312+
186313
### Service API versions
187314

188-
The client library targets the latest service API version by default. To use another supported version, pass a `WebPubSubChatServiceVersion` to the builder's `serviceVersion` method. Verify that the selected version supports the operations and models used by your application.
315+
The default is `WebPubSubChatServiceVersion.V2026_08_01_PREVIEW`. The library also
316+
supports `V2026_02_01_PREVIEW` for existing operations. Topic operations and the
317+
new room/user listing operations require the August version. To select a version,
318+
pass it to the builder's `serviceVersion` method. All operations are supported
319+
with the August API; no separate client is needed for existing operations.
189320

190321
## Troubleshooting
191322

@@ -210,6 +341,8 @@ Explore the [complete package samples][samples] to learn how to:
210341

211342
- Authenticate with a connection string, access key, or Microsoft Entra ID.
212343
- Manage roles, permissions, users, rooms, and room members.
344+
- List rooms and users, and query rooms associated with a user.
345+
- Manage topics and their lifecycle states.
213346
- Generate client access credentials.
214347
- Query, update, and delete message history.
215348
- Use synchronous and asynchronous clients.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"AssetsRepo":"Azure/azure-sdk-assets","AssetsRepoPrefixPath":"java","TagPrefix":"java/webpubsub/azure-messaging-webpubsub-chat","Tag": "java/webpubsub/azure-messaging-webpubsub-chat_395861d3d4"}
1+
{"AssetsRepo":"Azure/azure-sdk-assets","AssetsRepoPrefixPath":"java","TagPrefix":"java/webpubsub/azure-messaging-webpubsub-chat","Tag": "java/webpubsub/azure-messaging-webpubsub-chat_a649b09111"}

0 commit comments

Comments
 (0)