public static TcpMessage FromArraySegment(ArraySegment <byte> data) { var d = data.Array; if (data.Count < sizeof(int)) { throw new ArgumentException(string.Format("ArraySegment too short, length: {0}", data.Count), "data"); } var msgId = 0; for (var i = 0; i < 4; i++) { msgId |= (d[i] << (i * 8)); // little-endian order } //TODO: CLC Replace this with more robust lookup, Different version of system can have different ids for messages and this will not survive persistance var msgType = MessageHierarchy.GetMsgType(msgId); var messageBuffer = new byte[d.Length - sizeof(int)]; Buffer.BlockCopy(data.Array, data.Offset + sizeof(int), messageBuffer, 0, messageBuffer.Length); var ms = new MemoryStream(messageBuffer); Message msg; using (var reader = new BsonReader(ms)) { var serializer = new JsonSerializer(); msg = (Message)serializer.Deserialize(reader, msgType); } return(new TcpMessage(msg)); }
public void bson_serialize_message_test() { var prop1 = "prop1"; var prop2 = "prop2"; var msg = new WoftamEvent(prop1, prop2); MemoryStream ms = new MemoryStream(); var bs = new BsonDataWriter(ms); bs.WriteStartObject(); bs.WritePropertyName(msg.GetType().FullName); bs.WriteValue(JsonConvert.SerializeObject(msg)); bs.WriteEnd(); ms.Seek(0, SeekOrigin.Begin); Message msg2; var reader = new BsonDataReader(ms); // read object reader.Read(); // read type name reader.Read(); var messageType = MessageHierarchy.GetTypeByFullName((string)reader.Value); reader.Read(); //property value msg2 = (Message)JsonConvert.DeserializeObject((string)reader.Value, messageType); Assert.IsType <WoftamEvent>(msg2); Assert.Equal(prop1, ((WoftamEvent)msg2).Property1); }
public void TestNameLookup() { var messageType = MessageHierarchy.GetTypeByName("Message"); Assert.Equal(typeof(Message), messageType); var childMessageType = MessageHierarchy.GetTypeByName("Event"); Assert.Equal(typeof(Event), childMessageType); }
public void TestFullNameLookup() { var messageType = MessageHierarchy.GetTypeByFullName("ReactiveDomain.Messaging.Message"); Assert.Equal(typeof(Message), messageType); var childMessageType = MessageHierarchy.GetTypeByFullName("ReactiveDomain.Messaging.Event"); Assert.Equal(typeof(Event), childMessageType); }
public IDisposable SubscribeToAll(IHandle <IMessage> handler) { Ensure.NotNull(handler, "handler"); var allHandler = new MessageHandler <IMessage>(handler, handler.GetType().Name); var messageTypes = MessageHierarchy.DescendantsAndSelf(typeof(object)).ToArray(); for (var i = 0; i < messageTypes.Length; i++) { Subcribe(allHandler, messageTypes[i]); } return(new Disposer(() => { this?.Unsubscribe(handler); return Unit.Default; })); }
// Every wrapped message that came out of TCP/IP, TcpInboundMessageHandler published on the bus. // I handle EVERYTHING that comes from the bus, so I'm going to get that same message back // (instantaneously). Thus TcpInboundMessageHandler calls the IgnoreThisMessage() function, // which puts the message on the _messagesThatCameFromTcp list. TcpInboundMessageHandler then // publishes the message on the CommandBus, which immediately hands it back to me. The Handle() // method (below) then keeps me from sending it BACK out on TCP, and thus we avoid the feedback loop. public void IgnoreThisMessage(Message message) { Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); if (message.MsgId == Guid.Empty) { Log.Error("Message " + message.MsgId + " (Type " + type.Name + ") - INTERNAL ERROR: there should NEVER be a message with that MsgId value"); } if (_messagesThatCameFromTcp.TryAdd(message.MsgId, message)) { Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") came from TCP, now added to MessagesThatCameFromTcp hash. Hash now contains " + _messagesThatCameFromTcp.Count + " entries."); } }
public void TestMessageDescendents() { var sut = typeof(ParentTestEvent); var descendants = MessageHierarchy.DescendantsAndSelf(sut).ToList(); Assert.Equal(3, descendants.Count()); Assert.Contains(typeof(ParentTestEvent), descendants); Assert.Contains(typeof(ChildTestEvent), descendants); Assert.Contains(typeof(GrandChildTestEvent), descendants); sut = typeof(GrandChildTestEvent); descendants = MessageHierarchy.DescendantsAndSelf(sut).ToList(); Assert.Single(descendants); Assert.Contains(typeof(GrandChildTestEvent), descendants); }
public void TestMessageChildType() { var sut = typeof(MessageChild); var ancestors = MessageHierarchy.AncestorsAndSelf(sut); Assert.Equal(3, ancestors.Count()); Assert.Contains(typeof(Message), ancestors); Assert.Contains(typeof(MessageParent), ancestors); Assert.Contains(typeof(MessageChild), ancestors); var descendants = MessageHierarchy.DescendantsAndSelf(sut); Assert.Single(descendants); Assert.Contains(typeof(MessageChild), descendants); }
public void Handle(Message message) { Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); Message removedMessage; if (_messagesThatCameFromTcp.TryRemove(message.MsgId, out removedMessage)) { Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") came from TCP originally, NOT sent back on TCP. MessagesThatCameFromTcp hash now contains " + _messagesThatCameFromTcp.Count + " entries."); return; } Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") to be sent over TCP."); _outboundMessageQueuedHandler.Publish(message); }
public static void Main() { var type = typeof(Message); Console.WriteLine("MessageChild has " + MessageHierarchy.AncestorsAndSelf(type).Count() + " Ancestors"); foreach (var parent in MessageHierarchy.AncestorsAndSelf(type)) { Console.WriteLine(parent); } Console.WriteLine($"{type} has {MessageHierarchy.DescendantsAndSelf(type).Count()} Descendants"); foreach (var descendant in MessageHierarchy.DescendantsAndSelf(type)) { Console.WriteLine(descendant); } }
public void TestMessageAncestors() { var sut = typeof(Message); var ancestors = MessageHierarchy.AncestorsAndSelf(sut).ToList(); Assert.Single(ancestors); Assert.Contains(typeof(Message), ancestors); sut = typeof(ParentTestEvent); ancestors = MessageHierarchy.AncestorsAndSelf(sut).ToList(); Assert.Equal(4, ancestors.Count()); Assert.Contains(typeof(ParentTestEvent), ancestors); Assert.Contains(typeof(CorrelatedMessage), ancestors); Assert.Contains(typeof(Event), ancestors); Assert.Contains(typeof(Message), ancestors); }
private void Subscribe(IMessageHandler handler, bool includeDerived) { Type[] messageTypes; if (includeDerived) { messageTypes = MessageHierarchy.DescendantsAndSelf(handler.MessageType).ToArray(); } else { messageTypes = new[] { handler.MessageType }; } for (var i = 0; i < messageTypes.Length; i++) { Subcribe(handler, messageTypes[i]); } }
public void TestMessageAncestors() { var sut = typeof(Message); var ancestors = MessageHierarchy.AncestorsAndSelf(sut).ToList(); Assert.Collection(ancestors, x => Assert.Equal(typeof(Message), x), x => Assert.Equal(typeof(object), x) ); sut = typeof(ParentTestEvent); ancestors = MessageHierarchy.AncestorsAndSelf(sut).ToList(); Assert.Equal(3, ancestors.Count()); Assert.Contains(typeof(ParentTestEvent), ancestors); Assert.Contains(typeof(Message), ancestors); Assert.Contains(typeof(object), ancestors); }
protected bool HasSubscriberFor(Type type, bool includeDerived) { Type[] derivedTypes = { type }; if (includeDerived) { derivedTypes = MessageHierarchy.DescendantsAndSelf(type).ToArray(); } for (var i = 0; i < derivedTypes.Length; i++) { var derivedType = derivedTypes[i]; if (HasSubscriberForExactType(derivedType)) { return(true); } } return(false); }
public Tuple <string, Type> FromBytes(ArraySegment <byte> data) { if (data.Array == null || data.Count < sizeof(int)) { throw new ArgumentException($"ArraySegment null or too short, length: {data.Count}", nameof(data)); } var offset = data.Offset; offset += ReadBytes(data.Array, offset, out var typeNameByteCount); offset += ReadBytes(data.Array, offset, typeNameByteCount, out var typeName); offset += ReadBytes(data.Array, offset, out var jsonByteCount); ReadBytes(data.Array, offset, jsonByteCount, out var json); var messageType = MessageHierarchy.GetTypeByFullName(typeName); return(new Tuple <string, Type>(json, messageType)); }
public IDisposable Subscribe <T>(IHandle <T> handler) where T : Message { Ensure.NotNull(handler, "handler"); lock (_handlers) { int[] descendants = MessageHierarchy.DescendantsByType[typeof(T)]; for (int i = 0; i < descendants.Length; ++i) { var handlers = _handlers[descendants[i]]; if (!handlers.Any(x => x.IsSame <T>(handler))) { handlers.Add(new MessageHandler <T>(handler, handler.GetType().Name, MessageHierarchy.GetMsgTypeId(typeof(T)))); } } return(new SubscriptionDisposer(() => { this?.Unsubscribe(handler); return Unit.Default; })); } }
public void Publish(Message message) { if (message == null) { Log.Error("Message was null, publishing aborted"); return; } var type1 = MessageHierarchy.GetMsgType(message.MsgTypeId); var handlers = _handlers[message.MsgTypeId]; for (int i = 0, n = handlers.Count; i < n; ++i) { var handler = handlers[i]; if (_watchSlowMsg) { var before = DateTime.UtcNow; handler.TryHandle(message); var elapsed = DateTime.UtcNow - before; if (elapsed <= _slowMsgThreshold) { continue; } Log.Trace("SLOW BUS MSG [{0}]: {1} - {2}ms. Handler: {3}.", Name, type1.Name, (int)elapsed.TotalMilliseconds, handler.HandlerName); if (elapsed > QueuedHandler.VerySlowMsgThreshold)// && !(message is SystemMessage.SystemInit)) { Log.Error("---!!! VERY SLOW BUS MSG [{0}]: {1} - {2}ms. Handler: {3}.", Name, type1.Name, (int)elapsed.TotalMilliseconds, handler.HandlerName); } } else { handler.TryHandle(message); } } }
public void can_create_tcp_message_from_byte_array() { var tcpMsg = new TcpMessage(_testEvent); Assert.NotNull(tcpMsg.Data.Array); // ReSharper disable once AssignNullToNotNullAttribute var reader = new BsonDataReader(new MemoryStream(tcpMsg.Data.Array)); // read object reader.Read(); // read type name reader.Read(); var messageType = MessageHierarchy.GetTypeByFullName((string)reader.Value); reader.Read(); //read json value var msg2 = (Message)JsonConvert.DeserializeObject((string)reader.Value, messageType, Json.JsonSettings); Assert.IsType <WoftamEvent>(msg2); Assert.Equal(Prop1, ((WoftamEvent)msg2).Property1); }
public IMessage FromBytes(ArraySegment <byte> data) { if (data.Array == null || data.Count < sizeof(int)) { throw new ArgumentException($"ArraySegment null or too short, length: {data.Count}", nameof(data)); } var offset = data.Offset; offset += ReadBytes(data.Array, offset, out var typeNameByteCount); offset += ReadBytes(data.Array, offset, typeNameByteCount, out var typeName); offset += ReadBytes(data.Array, offset, out var jsonByteCount); ReadBytes(data.Array, offset, jsonByteCount, out var json); var messageType = MessageHierarchy.GetTypeByFullName(typeName); var msg = DeserializeMessage(json, messageType); Log.Debug("Deserialized Message MsgId=" + msg.MsgId + " MsgType" + msg.GetType().Name); return(msg); }
public void Unsubscribe <T>(IHandle <T> handler) where T : Message { Ensure.NotNull(handler, "handler"); var descendants = MessageHierarchy.DescendantsAndSelf(typeof(T)).ToArray(); for (var d = 0; d < descendants.Length; d++) { var handlers = GetHandlesFor(descendants[d]); for (var h = 0; h < handlers.Length; h++) { if (!handlers[h].IsSame(typeof(T), handler)) { continue; } lock (_handlers) { _handlers[descendants[d]].Remove(handlers[h]); } break; } } }
public void can_dynamicly_add_types_without_clearing_handlers() { var bus = InMemoryBus.CreateTest(); var fired = false; bus.Subscribe(new AdHocHandler <TestMsg>(m => fired = true)); bus.Publish(new TestMsg()); Assert.True(fired); AppDomain.CurrentDomain.Load(GetDynamicAssembly().GetName()); var messageType = MessageHierarchy.GetTypeByName("DynamicMessage"); Assert.Equal("DynamicMessage", messageType[0].Name); Assert.True(messageType.Count == 1); fired = false; bus.Publish(new TestMsg()); AssertEx.IsOrBecomesTrue(() => fired); }
protected void TcpMessageArrived(ArraySegment <byte> obj) { TcpMessage tcpMessage; try { tcpMessage = TcpMessage.FromArraySegment(obj); } catch (Exception ex) { Log.ErrorException(ex, "TcpMessage.FromArraySegment() threw an exception:"); throw; } Type type = MessageHierarchy.GetMsgType(tcpMessage.WrappedMessage.MsgTypeId); Log.Trace("Message " + tcpMessage.WrappedMessage.MsgId + " (Type " + type.Name + ") received from TCP."); if (_inboundSpamMessageTypes.Contains(type)) { if (_inboundSpamMessageQueuedHandler == null) { Log.Error("TCP message (a Message) has arrived, but _inboundSpamMessageQueuedHandler is null."); return; } _inboundSpamMessageQueuedHandler.Publish(tcpMessage.WrappedMessage); } else { if (_inboundMessageQueuedHandler == null) { Log.Error("TCP message (a Message) has arrived, but _inboundMessageQueuedHandler is null."); return; } _inboundMessageQueuedHandler.Publish(tcpMessage.WrappedMessage); } }
public void Handle(Message message) { Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); Log.Trace("Message " + message.MsgId + " (Type " + type.Name + ") to be sent over TCP."); if (TcpConnection == null) { Log.Debug("TCP connection not yet established - Message " + message.MsgId + " (Type " + type.Name + ") will be discarded."); return; } try { var framed = Framer.FrameData((new TcpMessage(message).AsArraySegment())); TcpConnection.EnqueueSend(framed); } catch (Exception ex) { Log.ErrorException(ex, "Exception caught while handling Message " + message.MsgId + " (Type " + type.Name + ")"); } }
private void Subscribe(IMessageHandler handler) { // Subscribe to the underlying message type and it's descendants var messageTypes = MessageHierarchy.DescendantsAndSelf(handler.MessageType).ToArray(); for (var i = 0; i < messageTypes.Length; i++) { var messageType = messageTypes[i]; var handlers = GetHandlesFor(messageType); if (!handlers.Any(hndl => hndl.IsSame(messageType, handler))) { lock (_handlers) { if (!_handlers.TryGetValue(messageType, out var handleList)) { handleList = new List <IMessageHandler>(); _handlers.Add(messageType, handleList); } handleList.Add(handler); } } } }
public bool TryResovleType() { if (!isType) { return(false); } if (PermissionType != null) { return(true); } try { var type = MessageHierarchy.GetTypeByFullName(PermissionName); if (type != null) { PermissionType = type; return(true); } } catch { /*ignore and return false */ } return(false); }
/// <summary> /// Builds a tcp messages from a wrapped data array /// used by the tcp processing system to deserialize recieved data /// </summary> /// <param name="data">The wrapped memory array.</param> /// <returns>a new tcp message built from the array segment</returns> /// <exception cref="UnregisteredMessageException"> If the message type is not found this will throw UnregisteredMessageException</exception> public static TcpMessage FromArraySegment(ArraySegment <byte> data) { if (data.Array == null || data.Count < sizeof(int)) { throw new ArgumentException($"ArraySegment null or too short, length: {data.Count}", nameof(data)); } Message msg; #pragma warning disable 618 using (var reader = new BsonDataReader(new MemoryStream(data.Array))) #pragma warning restore 618 { reader.Read(); //object reader.Read(); //property name var messageType = MessageHierarchy.GetTypeByFullName((string)reader.Value); reader.Read(); //property value msg = (Message)JsonConvert.DeserializeObject((string)reader.Value, messageType, Settings.JsonSettings); } Log.Debug("Deserialized Message MsgId=" + msg.MsgId + " MsgType" + msg.GetType().Name); return(new TcpMessage(msg, data)); }
public void Handle(Message message) { Type type1 = MessageHierarchy.GetMsgType(message.MsgTypeId); dynamic msg = message; var type2 = msg.GetType(); if (!type1.Equals(type2)) { var error = $"Message object-type mismatch. MsgTypeId={message.MsgTypeId}, which MessageHierarchy claims is a {type1.FullName}. However, .Net Reflection says that the command is a {type2.FullName}"; Log.Error(error); throw new Exception(error); } var before = DateTime.UtcNow; MessageReceived(msg, type1, "TcpBusSide"); _tcpOutboundMessageHandler.IgnoreThisMessage(message); Type type = MessageHierarchy.GetMsgType(message.MsgTypeId); _mainBus.Publish(message); PostHandleMessage(msg, type1, (DateTime.UtcNow - before)); }
public bool HasSubscriberFor <T>(bool includeDerived = false) where T : Message { return(HasSubscriberFor(MessageHierarchy.GetMsgTypeId(typeof(T)), includeDerived)); }