Skip to content

Commit e70125b

Browse files
authored
Fix 1771 complete (#1774)
* Add FlatBuffers support for remaining WAMP messages This commit completes FlatBuffers serialization support for the remaining WAMP messages: - Category 3 (Forwarding Only): Cancel, Interrupt, EventReceived - Category 1 (Session Lifecycle): Hello, Welcome - Category 1 (RPC): Unregister Changes: - Fixed Cancel, Interrupt build() methods to handle forward_for and remove non-existent session references - Fixed EventReceived build() to wrap in Message union - Added build() and cast() methods for Unregister - Fixed Hello and Welcome build() methods to wrap in Message union - Added MESSAGE_TYPE_MAP entries for Hello and Welcome - Enhanced test vector generator to: - Support EVENT_RECEIVED message type - Convert dict roles to RoleFeatures instances for Hello/Welcome Test results: 529 passed, 0 skipped, 12 warnings * Bump .proto submodule to include remaining WAMP message test vectors Update wamp-proto submodule to commit 2fcf809 which includes FlatBuffers test vectors for the remaining WAMP messages (Cancel, Interrupt, EventReceived, Hello, Welcome, Unregister). This completes FlatBuffers test coverage with 529 tests passing, 0 skipped. * skip shitty os Note: This work was completed with AI assistance (Claude Code).
1 parent d0ab7eb commit e70125b

File tree

5 files changed

+146
-19
lines changed

5 files changed

+146
-19
lines changed

.github/workflows/wheels.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ jobs:
175175
shell: pwsh
176176

177177
- name: Setup uv cache
178+
# skip broken platform ("Error: The template is not valid. .github/workflows/wheels.yml (Line: 182, Col: 13):
179+
# hashFiles('pyproject.toml') failed. Fail to hash files under directory '/Users/runner/work/autobahn-python/autobahn-python'")
180+
if: matrix.platform != 'macos'
178181
uses: actions/cache@v4
179182
with:
180183
path: ${{ env.UV_CACHE_DIR }}

autobahn/wamp/message.py

Lines changed: 113 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,9 +1279,6 @@ def build(self, builder, serializer=None):
12791279
message_fbs.HelloGen.HelloStart(builder)
12801280

12811281
# Add fields
1282-
session = getattr(self, 'session', None)
1283-
if session:
1284-
message_fbs.HelloGen.HelloAddSession(builder, session)
12851282
if realm:
12861283
message_fbs.HelloGen.HelloAddRealm(builder, realm)
12871284
if authid:
@@ -1299,9 +1296,16 @@ def build(self, builder, serializer=None):
12991296
# TODO: Add authmethods array serialization
13001297
# TODO: Add authextra Map serialization
13011298

1302-
# End and return
1299+
# End message
13031300
msg = message_fbs.HelloGen.HelloEnd(builder)
1304-
return msg
1301+
1302+
# Wrap in Message union with type
1303+
message_fbs.Message.MessageStart(builder)
1304+
message_fbs.Message.MessageAddMsgType(builder, message_fbs.MessageType.HELLO)
1305+
message_fbs.Message.MessageAddMsg(builder, msg)
1306+
union_msg = message_fbs.Message.MessageEnd(builder)
1307+
1308+
return union_msg
13051309

13061310
@staticmethod
13071311
def parse(wmsg):
@@ -1903,9 +1907,16 @@ def build(self, builder, serializer=None):
19031907
# TODO: Add authmethod enum serialization
19041908
# TODO: Add authextra Map serialization
19051909

1906-
# End and return
1910+
# End message
19071911
msg = message_fbs.WelcomeGen.WelcomeEnd(builder)
1908-
return msg
1912+
1913+
# Wrap in Message union with type
1914+
message_fbs.Message.MessageStart(builder)
1915+
message_fbs.Message.MessageAddMsgType(builder, message_fbs.MessageType.WELCOME)
1916+
message_fbs.Message.MessageAddMsg(builder, msg)
1917+
union_msg = message_fbs.Message.MessageEnd(builder)
1918+
1919+
return union_msg
19091920

19101921
@staticmethod
19111922
def parse(wmsg):
@@ -6230,8 +6241,6 @@ def cast(buf):
62306241
def build(self, builder, serializer=None):
62316242
message_fbs.EventReceivedGen.EventReceivedStart(builder)
62326243

6233-
if self.session:
6234-
message_fbs.EventReceivedGen.EventReceivedAddSession(builder, self.session)
62356244
if self.publication:
62366245
message_fbs.EventReceivedGen.EventReceivedAddPublication(
62376246
builder, self.publication
@@ -6241,7 +6250,9 @@ def build(self, builder, serializer=None):
62416250

62426251
# Wrap in Message union with type
62436252
message_fbs.Message.MessageStart(builder)
6244-
message_fbs.Message.MessageAddMsgType(builder, message_fbs.MessageType.EVENT_RECEIVED)
6253+
message_fbs.Message.MessageAddMsgType(
6254+
builder, message_fbs.MessageType.EVENT_RECEIVED
6255+
)
62456256
message_fbs.Message.MessageAddMsg(builder, msg)
62466257
union_msg = message_fbs.Message.MessageEnd(builder)
62476258

@@ -7138,10 +7149,36 @@ def cast(buf):
71387149
return Cancel(from_fbs=message_fbs.Cancel.GetRootAsCancel(buf, 0))
71397150

71407151
def build(self, builder, serializer=None):
7152+
# Handle forward_for: [Principal]
7153+
forward_for = self.forward_for
7154+
if forward_for:
7155+
from autobahn.wamp.gen.wamp.proto import Principal as PrincipalGen
7156+
7157+
_forward_for = []
7158+
for principal in forward_for:
7159+
_session = principal.get("session", 0)
7160+
_authid = principal.get("authid", None)
7161+
_authrole = principal.get("authrole", "")
7162+
7163+
if _authid:
7164+
_authid = builder.CreateString(_authid)
7165+
_authrole = builder.CreateString(_authrole)
7166+
7167+
PrincipalGen.Start(builder)
7168+
PrincipalGen.AddSession(builder, _session)
7169+
if _authid:
7170+
PrincipalGen.AddAuthid(builder, _authid)
7171+
PrincipalGen.AddAuthrole(builder, _authrole)
7172+
_forward_for.append(PrincipalGen.End(builder))
7173+
7174+
message_fbs.CancelGen.CancelStartForwardForVector(builder, len(_forward_for))
7175+
for principal in reversed(_forward_for):
7176+
builder.PrependUOffsetTRelative(principal)
7177+
forward_for = builder.EndVector()
7178+
7179+
# Start Cancel message
71417180
message_fbs.CancelGen.CancelStart(builder)
71427181

7143-
if self.session:
7144-
message_fbs.CancelGen.CancelAddSession(builder, self.session)
71457182
if self.request:
71467183
message_fbs.CancelGen.CancelAddRequest(builder, self.request)
71477184

@@ -7156,6 +7193,9 @@ def build(self, builder, serializer=None):
71567193
mode_val = message_fbs.CancelMode.SKIP # default
71577194
message_fbs.CancelGen.CancelAddMode(builder, mode_val)
71587195

7196+
if forward_for:
7197+
message_fbs.CancelGen.CancelAddForwardFor(builder, forward_for)
7198+
71597199
msg = message_fbs.CancelGen.CancelEnd(builder)
71607200

71617201
# Wrap in Message union with type
@@ -8429,6 +8469,35 @@ def marshal(self):
84298469
else:
84308470
return [Unregister.MESSAGE_TYPE, self.request, self.registration]
84318471

8472+
@staticmethod
8473+
def cast(buf):
8474+
return Unregister(from_fbs=message_fbs.Unregister.GetRootAsUnregister(buf, 0))
8475+
8476+
def build(self, builder, serializer=None):
8477+
# Start Unregister message
8478+
message_fbs.UnregisterGen.UnregisterStart(builder)
8479+
8480+
if self.request:
8481+
message_fbs.UnregisterGen.UnregisterAddRequest(builder, self.request)
8482+
if self.registration:
8483+
message_fbs.UnregisterGen.UnregisterAddRegistration(
8484+
builder, self.registration
8485+
)
8486+
8487+
# Note: forward_for not supported in current FlatBuffers schema
8488+
8489+
msg = message_fbs.UnregisterGen.UnregisterEnd(builder)
8490+
8491+
# Wrap in Message union with type
8492+
message_fbs.Message.MessageStart(builder)
8493+
message_fbs.Message.MessageAddMsgType(
8494+
builder, message_fbs.MessageType.UNREGISTER
8495+
)
8496+
message_fbs.Message.MessageAddMsg(builder, msg)
8497+
union_msg = message_fbs.Message.MessageEnd(builder)
8498+
8499+
return union_msg
8500+
84328501

84338502
class Unregistered(Message):
84348503
"""
@@ -9570,12 +9639,39 @@ def build(self, builder, serializer=None):
95709639
if reason:
95719640
reason = builder.CreateString(reason)
95729641

9642+
# Handle forward_for: [Principal]
9643+
forward_for = self.forward_for
9644+
if forward_for:
9645+
from autobahn.wamp.gen.wamp.proto import Principal as PrincipalGen
9646+
9647+
_forward_for = []
9648+
for principal in forward_for:
9649+
_session = principal.get("session", 0)
9650+
_authid = principal.get("authid", None)
9651+
_authrole = principal.get("authrole", "")
9652+
9653+
if _authid:
9654+
_authid = builder.CreateString(_authid)
9655+
_authrole = builder.CreateString(_authrole)
9656+
9657+
PrincipalGen.Start(builder)
9658+
PrincipalGen.AddSession(builder, _session)
9659+
if _authid:
9660+
PrincipalGen.AddAuthid(builder, _authid)
9661+
PrincipalGen.AddAuthrole(builder, _authrole)
9662+
_forward_for.append(PrincipalGen.End(builder))
9663+
9664+
message_fbs.InterruptGen.InterruptStartForwardForVector(
9665+
builder, len(_forward_for)
9666+
)
9667+
for principal in reversed(_forward_for):
9668+
builder.PrependUOffsetTRelative(principal)
9669+
forward_for = builder.EndVector()
9670+
95739671
# Start message
95749672
message_fbs.InterruptGen.InterruptStart(builder)
95759673

95769674
# Add fields
9577-
if self.session:
9578-
message_fbs.InterruptGen.InterruptAddSession(builder, self.session)
95799675
if self.request:
95809676
message_fbs.InterruptGen.InterruptAddRequest(builder, self.request)
95819677

@@ -9591,6 +9687,9 @@ def build(self, builder, serializer=None):
95919687
if reason:
95929688
message_fbs.InterruptGen.InterruptAddReason(builder, reason)
95939689

9690+
if forward_for:
9691+
message_fbs.InterruptGen.InterruptAddForwardFor(builder, forward_for)
9692+
95949693
msg = message_fbs.InterruptGen.InterruptEnd(builder)
95959694

95969695
# Wrap in Message union with type

autobahn/wamp/serializer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,8 @@ class FlatBuffersObjectSerializer(object):
10641064
message_fbs.MessageType.YIELD: (message_fbs.Yield, message.Yield),
10651065

10661066
# Category 1: Session lifecycle messages
1067+
message_fbs.MessageType.HELLO: (message_fbs.HelloGen.Hello, message.Hello),
1068+
message_fbs.MessageType.WELCOME: (message_fbs.WelcomeGen.Welcome, message.Welcome),
10671069
message_fbs.MessageType.ABORT: (message_fbs.AbortGen.Abort, message.Abort),
10681070
message_fbs.MessageType.CHALLENGE: (message_fbs.ChallengeGen.Challenge, message.Challenge),
10691071
message_fbs.MessageType.AUTHENTICATE: (message_fbs.AuthenticateGen.Authenticate, message.Authenticate),

examples/serdes/gen_flatbuffers_testvectors.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"INVOCATION": (wamp_messages.Invocation, 68),
8484
"INTERRUPT": (wamp_messages.Interrupt, 69),
8585
"YIELD": (wamp_messages.Yield, 70),
86+
"EVENT_RECEIVED": (wamp_messages.EventReceived, 71),
8687
}
8788

8889

@@ -98,11 +99,31 @@ def create_message_from_attributes(message_type_name, attributes):
9899

99100
# Session establishment messages
100101
if message_type_name == "HELLO":
101-
return message_class(realm=attributes["realm"], roles=attributes["roles"])
102+
# Convert dict roles to RoleFeatures instances
103+
from autobahn.wamp import role
104+
105+
roles_dict = {}
106+
for role_name, role_features in attributes["roles"].items():
107+
if role_name == "subscriber":
108+
roles_dict[role_name] = role.RoleSubscriberFeatures()
109+
elif role_name == "publisher":
110+
roles_dict[role_name] = role.RolePublisherFeatures()
111+
elif role_name == "caller":
112+
roles_dict[role_name] = role.RoleCallerFeatures()
113+
elif role_name == "callee":
114+
roles_dict[role_name] = role.RoleCalleeFeatures()
115+
return message_class(realm=attributes["realm"], roles=roles_dict)
102116
elif message_type_name == "WELCOME":
103-
return message_class(
104-
session=attributes["session_id"], roles=attributes["roles"]
105-
)
117+
# Convert dict roles to RoleFeatures instances
118+
from autobahn.wamp import role
119+
120+
roles_dict = {}
121+
for role_name, role_features in attributes["roles"].items():
122+
if role_name == "broker":
123+
roles_dict[role_name] = role.RoleBrokerFeatures()
124+
elif role_name == "dealer":
125+
roles_dict[role_name] = role.RoleDealerFeatures()
126+
return message_class(session=attributes["session_id"], roles=roles_dict)
106127
elif message_type_name == "ABORT":
107128
return message_class(
108129
reason=attributes["reason"], message=attributes.get("message")
@@ -282,6 +303,8 @@ def create_message_from_attributes(message_type_name, attributes):
282303
reason=attributes.get("options", {}).get("reason"),
283304
forward_for=attributes.get("options", {}).get("forward_for"),
284305
)
306+
elif message_type_name == "EVENT_RECEIVED":
307+
return message_class(publication=attributes["publication_id"])
285308
elif message_type_name == "YIELD":
286309
return message_class(
287310
request=attributes["request_id"],

0 commit comments

Comments
 (0)