Converted AMQPAdapeter Java code to Python
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import base64
|
||||
import logging
|
||||
|
||||
from amqp.adapter.amq_message_factory import AMQMessageFactory
|
||||
from amqp.adapter.trace_info_adapter import TraceInfoAdapter
|
||||
from amqp.model.model import CleverMicroServiceMessage, ServiceMessageType
|
||||
from amqp.model.snowflake_id import SnowflakeId
|
||||
from amqp.router.serializer import parse_map_string, map_as_string
|
||||
|
||||
RS = "|"
|
||||
SPLIT_RS = r"\|"
|
||||
|
||||
|
||||
INVALID_MESSAGE = CleverMicroServiceMessage() # default values mean invalid message
|
||||
|
||||
|
||||
class CleverMicroServiceMessageFactory:
|
||||
|
||||
def __init__(self, name: str):
|
||||
self.process_name = name
|
||||
|
||||
def to_string(self, message: CleverMicroServiceMessage) -> str:
|
||||
if message is not None:
|
||||
return (
|
||||
f"CleverMicroServiceMessage{{id={message.id.as_string()}|type={self.format_message_type(message)}|"
|
||||
f"recipient={message.recipient_name}|replyTo={message.reply_to}|"
|
||||
f"traceInfo={message.trace_info}|body={base64.b64encode(message.message.encode()).decode() if message.payload_type & 0x80 else message.message}}}"
|
||||
)
|
||||
return "null"
|
||||
|
||||
def of(self, message_type: ServiceMessageType, payload: str, recipient_name: str) -> CleverMicroServiceMessage:
|
||||
_id = AMQMessageFactory.get_instance(1).generate_snowflake_id()
|
||||
return CleverMicroServiceMessage(
|
||||
id=_id,
|
||||
payload_type=0,
|
||||
message_type=message_type,
|
||||
recipient_name=recipient_name,
|
||||
reply_to=self.process_name,
|
||||
trace_info=TraceInfoAdapter.create_produce_span(_id),
|
||||
message=payload
|
||||
)
|
||||
|
||||
def as_base64(self, message_type: ServiceMessageType, payload: str, recipient_name: str) -> CleverMicroServiceMessage:
|
||||
_id = AMQMessageFactory.get_instance(1).generate_snowflake_id()
|
||||
return CleverMicroServiceMessage(
|
||||
id=_id,
|
||||
payload_type=0x80,
|
||||
message_type=message_type,
|
||||
recipient_name=recipient_name,
|
||||
reply_to=self.process_name,
|
||||
trace_info=TraceInfoAdapter.create_produce_span(_id.as_string()),
|
||||
message=payload
|
||||
)
|
||||
|
||||
def from_bytes(self, input_bytes: bytes) -> CleverMicroServiceMessage:
|
||||
print(f"CleverMicroServiceMessage >>> [{input_bytes.decode()}]")
|
||||
input_str_array = input_bytes.decode().split(RS)
|
||||
try:
|
||||
i = 0
|
||||
_id = input_str_array[i]
|
||||
i += 1
|
||||
payload_type = int(input_str_array[i], 16)
|
||||
i += 1
|
||||
message_type = ServiceMessageType(payload_type + 1 & 0x7F)
|
||||
recipient_name = input_str_array[i] if i < len(input_str_array) else ""
|
||||
i += 1
|
||||
reply_to = input_str_array[i] if i < len(input_str_array) else ""
|
||||
i += 1
|
||||
trace_info = parse_map_string(input_str_array[i]) if i < len(input_str_array) else {}
|
||||
i += 1
|
||||
message = input_str_array[i] if i < len(input_str_array) else ""
|
||||
return CleverMicroServiceMessage(
|
||||
id=SnowflakeId.from_hex(_id),
|
||||
payload_type=payload_type,
|
||||
message_type=message_type,
|
||||
recipient_name=recipient_name,
|
||||
reply_to=reply_to,
|
||||
trace_info=trace_info,
|
||||
message=base64.b64decode(message).decode() if payload_type & 0x80 else message
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
"Unexpected ServiceMessage format. Expected 6 tokens separated by '|' in format: "
|
||||
"[ID(64bit number)|MessageType(8bit number)|RecipientName(String)|"
|
||||
"ReplyTo(String)|TraceInfo|Payload(String or Base64)], got: "
|
||||
"[{}], reported problem: {}", input_bytes.decode(), str(e)
|
||||
)
|
||||
return INVALID_MESSAGE
|
||||
|
||||
def serialize(self, message: CleverMicroServiceMessage) -> bytes:
|
||||
return (
|
||||
f"{message.id.as_string()}{RS}{self.format_message_type(message)}{RS}{message.recipient_name}{RS}"
|
||||
f"{message.reply_to}{RS}{map_as_string(message.trace_info)}{RS}"
|
||||
f"{base64.b64encode(message.message.encode()).decode() if message.payload_type != 0 else message.message}"
|
||||
).encode('utf-8')
|
||||
|
||||
|
||||
def format_message_type(self, message: CleverMicroServiceMessage) -> str:
|
||||
"""
|
||||
Formats the Enum message type and ecorates it with base64 flag at highest bit.
|
||||
For compatibility with 0-based enum ordinals in Java subtract 1 from ordinal value.
|
||||
:param message: Service message to send
|
||||
:return: formatted message type
|
||||
"""
|
||||
num_type = (message.message_type.value if message.message_type else ServiceMessageType.UNKNOWN.value) - 1
|
||||
fmt = ((num_type & 0x7F) | (message.payload_type & 0x80))
|
||||
return f"{fmt:02X}"
|
||||
Reference in New Issue
Block a user