|
| 1 | +module S2 |
| 2 | + class MessageFactory |
| 3 | + MESSAGE_TYPE_TO_MESSAGE_CLASS = { |
| 4 | + "FRBC.ActuatorStatus" => S2::Messages::FRBCActuatorStatus, |
| 5 | + "FRBC.FillLevelTargetProfile" => S2::Messages::FRBCFillLevelTargetProfile, |
| 6 | + "FRBC.Instruction" => S2::Messages::FRBCInstruction, |
| 7 | + "FRBC.LeakageBehaviour" => S2::Messages::FRBCLeakageBehaviour, |
| 8 | + "FRBC.StorageStatus" => S2::Messages::FRBCStorageStatus, |
| 9 | + "FRBC.SystemDescription" => S2::Messages::FRBCSystemDescription, |
| 10 | + "FRBC.TimerStatus" => S2::Messages::FRBCTimerStatus, |
| 11 | + "FRBC.UsageForecast" => S2::Messages::FRBCUsageForecast, |
| 12 | + "Handshake" => S2::Messages::Handshake, |
| 13 | + "HandshakeResponse" => S2::Messages::HandshakeResponse, |
| 14 | + "InstructionStatusUpdate" => S2::Messages::InstructionStatusUpdate, |
| 15 | + "PowerForecast" => S2::Messages::PowerForecast, |
| 16 | + "PowerMeasurement" => S2::Messages::PowerMeasurement, |
| 17 | + "ReceptionStatus" => S2::Messages::ReceptionStatus, |
| 18 | + "ResourceManagerDetails" => S2::Messages::ResourceManagerDetails, |
| 19 | + "RevokeObject" => S2::Messages::RevokeObject, |
| 20 | + "SelectControlType" => S2::Messages::SelectControlType, |
| 21 | + "SessionRequest" => S2::Messages::SessionRequest, |
| 22 | + }.freeze |
| 23 | + |
| 24 | + class BaseError < StandardError |
| 25 | + attr_reader :message_id |
| 26 | + |
| 27 | + def initialize(message, message_id = nil) |
| 28 | + super(message) |
| 29 | + @message_id = message_id |
| 30 | + end |
| 31 | + end |
| 32 | + |
| 33 | + class InvalidMessageFormat < BaseError; end |
| 34 | + class MissingMessageType < BaseError; end |
| 35 | + class UnsupportedMessageType < BaseError; end |
| 36 | + class InvalidMessagePayload < BaseError; end |
| 37 | + |
| 38 | + class << self |
| 39 | + def create_message(data) |
| 40 | + message = data.is_a?(String) ? parse_json(data) : data |
| 41 | + message_type = message["message_type"] |
| 42 | + message_id = message["message_id"] |
| 43 | + |
| 44 | + raise(MissingMessageType, "Message type not provided", message_id) if message_type.blank? |
| 45 | + |
| 46 | + message_class = MESSAGE_TYPE_TO_MESSAGE_CLASS[message_type] |
| 47 | + |
| 48 | + if message_class.nil? |
| 49 | + raise( |
| 50 | + UnsupportedMessageType, |
| 51 | + "Message type not supported: #{message_type}", |
| 52 | + message_id, |
| 53 | + ) |
| 54 | + end |
| 55 | + |
| 56 | + build_message(message_class, message) |
| 57 | + end |
| 58 | + |
| 59 | + private |
| 60 | + |
| 61 | + def parse_json(data) |
| 62 | + JSON.parse(data) |
| 63 | + rescue JSON::ParserError |
| 64 | + raise(InvalidMessageFormat, "Invalid JSON") |
| 65 | + end |
| 66 | + |
| 67 | + def build_message(message_class, message) |
| 68 | + message_class.from_dynamic!(message) |
| 69 | + rescue KeyError => e |
| 70 | + raise(InvalidMessagePayload, "Field missing in payload: #{e.key}", message["message_id"]) |
| 71 | + end |
| 72 | + end |
| 73 | + end |
| 74 | +end |
0 commit comments