/// <summary>
        /// Processes the specified message context.
        /// </summary>
        /// <param name="messageContext">The message context.</param>
        /// <param name="storeContext">The store context.</param>
        internal static void Process(MessageContext messageContext, IndexStoreContext storeContext)
        {
            // TBD : Support concurrent DeleteAllInType for different types
            lock (LockingUtil.Instance.LockerObjects)
            {
                RelayMessage msg;

                if (DataTierUtil.ShouldForwardToDataTier(messageContext.RelayTTL,
                    messageContext.SourceZone,
                    storeContext.MyZone,
                    storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId].IndexServerMode))
                {
                    // Send DeleteAll to Data Store
                    short relatedTypeId;
                    if(!storeContext.TryGetRelatedIndexTypeId(messageContext.TypeId, out relatedTypeId))
                    {
                        LoggingUtil.Log.ErrorFormat("Invalid RelatedTypeId for TypeId - {0}", messageContext.TypeId);
                        throw new Exception("Invalid RelatedTypeId for TypeId - " + messageContext.TypeId);
                    }
                    msg = new RelayMessage(relatedTypeId, 0, MessageType.DeleteAllInType);
                    storeContext.ForwarderComponent.HandleMessage(msg);
                }

                // Send DeleteAll to local Index storage
                msg = new RelayMessage(messageContext.TypeId, 0, MessageType.DeleteAllInType);
                storeContext.IndexStorageComponent.HandleMessage(msg);

                // Delete hash mapping entries in file
                storeContext.RemoveType(messageContext.TypeId);
            }
        }
예제 #2
0
        /// <summary>
        /// Processes the specified message context.
        /// </summary>
        /// <param name="messageContext">The message context.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns>Raw CacheIndexInternal</returns>
        internal static byte[] Process(MessageContext messageContext, IndexStoreContext storeContext)
        {
            byte[] payloadByteArray = null;
            RelayMessage getMsg = new RelayMessage
                                      {
                                          MessageType = MessageType.Get,
                                          Id = IndexCacheUtils.GeneratePrimaryId(messageContext.ExtendedId),
                                          ExtendedId = IndexServerUtils.FormExtendedId(messageContext.ExtendedId, 0)  // Pull first of the multiple indexes
                                      };

            if (storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection.Contains(messageContext.TypeId))
            {
                getMsg.TypeId = messageContext.TypeId;
            }
            else if (storeContext.RelatedTypeIds.TryGetValue(messageContext.TypeId, out getMsg.TypeId))
            {
            }
            else
            {
                LoggingUtil.Log.InfoFormat("Invalid TypeID for GetMessage {0}", messageContext.TypeId);
                return payloadByteArray;
            }

            storeContext.IndexStorageComponent.HandleMessage(getMsg);

            if (getMsg.Payload != null)
            {
                payloadByteArray = getMsg.Payload.ByteArray;
            }
            return payloadByteArray;
        }
		/// <summary>
		///	<para>Converts a <see cref="RelayMessage"/> into a <see cref="MemoryStream"/>.</para>
		/// </summary>
		/// <param name="message">The <see cref="RelayMessage"/>.</param>
		/// <returns>A <see cref="MemoryStream"/> version of the given <see cref="RelayMessage"/>.</returns>		
		public static MemoryStream WriteRelayMessage(RelayMessage message)
		{
			MemoryStream ms = new MemoryStream();

			WriteRelayMessage(message, ms);
			ms.Seek(0, SeekOrigin.Begin);

			return ms;
		}
 /// <summary>
 /// Constructor to create a <see cref="RelayMessageWithContext"/>
 /// </summary>
 /// <param name="relayMessage">The <see cref="RelayMessage"/> that needs to be processed</param>
 /// <param name="processingContext">The <see cref="RelayMessageProcessingContext"/> associated to the <see cref="RelayMessage"/></param>
 /// <exception cref="ArgumentNullException">All arguments for this constructor must be non-null</exception>
 public RelayMessageWithContext(RelayMessage relayMessage, RelayMessageProcessingContext processingContext)
 {
     if (relayMessage == null || processingContext == null)
     {
         throw new ArgumentNullException("RelayMessageWithContext consturctor requires non-null arguments");
     }
     this.relayMessage = relayMessage;
     this.processingContext = processingContext;
 }
예제 #5
0
		/// <summary>
		/// Applies the default TTL to the given <see cref="RelayMessage"/>.
		/// </summary>
		/// <param name="message"></param>
		public void ApplyDefaultTTL(RelayMessage message)
		{
			if (message.Payload != null)
			{
				int defaultTTL = GetDefaultTTL(message.TypeId);
				if (message.Payload.TTL == -1 && defaultTTL != -1)
				{
					//message has no specified ttl but this type does have a default ttl
					message.Payload.TTL = defaultTTL;
				}
			}
		}
		public SerializedRelayMessage(RelayMessage message)
		{
			MessageStream = new MemoryStream();
			RelayMessageFormatter.WriteRelayMessage(message, MessageStream);
			MessageStream.Seek(0, SeekOrigin.Begin);
			MessageType = message.MessageType;
			EnteredCurrentSystemAt = message.EnteredCurrentSystemAt;

			if (message.Payload != null && message.Payload.ByteArray != null)
			{
				PayloadLength = message.Payload.ByteArray.Length;
			}
		}
예제 #7
0
		/// <summary>
		/// Evaluates the <see cref="RelayMessage"/> for an expired TTL and if
		/// the message qualifies for deletion a deletion message is returned.
		/// </summary>
		/// <param name="message">The <see cref="RelayMessage"/> to evaluate.</param>
		/// <returns>Returns a delete message if a delete is required; otherwise, returns null.</returns>
		public RelayMessage ProcessExpiredTTLDelete(RelayMessage message)
		{
			RelayMessage deleteMessage = null;
			
			if (message.Payload != null &&
				UseTTLByType(message.TypeId) &&
				message.Payload.ExpirationTicks != -1 &&
				message.Payload.ExpirationTicks < DateTime.Now.Ticks)
			{
				message.Payload = null;
				if (this.deletesEnabled)
				{
					deleteMessage = new RelayMessage(message, MessageType.Delete);
				}
			}

			return deleteMessage;
		}
예제 #8
0
		public void Add(RelayMessage message)
		{
		    if(message.IsTwoWayMessage)
			{
	            if(OutMessages == null)
	            {
		            OutMessages = new List<RelayMessage>();
	            }				
	            OutMessages.Add(message);
			}
			else
			{
		        if (InMessages == null)
		        {
			        InMessages = new List<RelayMessage>();
		        }
		        InMessages.Add(message);
		    }
		}
예제 #9
0
		internal static void WriteDebugInfo(RelayMessage message, SimpleLinkedList<Node> destinations)
		{
			if (WriteMessageTrace && message != null)
			{
				StringBuilder debugString = new StringBuilder();
				StackTrace stack = null;
				if (WriteCallingMethod)
				{
					stack = new StackTrace(2,true);
				}
				debugString.Append("Relay Forwarding: ");
				debugString.Append(message.ToString());
				debugString.Append(Environment.NewLine);
				debugString.Append("    sending " + DescribeDestinations(destinations));
				if (stack != null)
				{
					debugString.Append(Environment.NewLine);
				    debugString.Append("    called ");
                    debugString.Append(stack.ToString());
				}
				
				_messageTracer.WriteLogMessage(message.MessageType,message.TypeId,debugString.ToString());
			}
		}
예제 #10
0
		private void SetHydrationPolicy(RelayMessage message)
		{
			if (message.IsTwoWayMessage && !message.IsGroupBroadcastMessage && !message.IsClusterBroadcastMessage)
			{
				var typeSetting = NodeManager.Instance.Config.TypeSettings.TypeSettingCollection[message.TypeId];
				if (typeSetting != null && typeSetting.HydrationPolicy != null)
				{
					message.HydrationPolicy = typeSetting.HydrationPolicy;
				}
			}
		}
예제 #11
0
        /// <summary>
        /// Gets the query metadata.
        /// </summary>
        /// <param name="internalCacheIndexList">The internal cache index list.</param>
        /// <param name="indexTypeMapping">The index type mapping.</param>
        /// <param name="typeId">The type id.</param>
        /// <param name="primaryId">The primary id.</param>
        /// <param name="extendedId">The extended id.</param>
        /// <param name="storeContext">The store context.</param>
        /// <returns></returns>
        internal static byte[] GetQueryMetadata(List<CacheIndexInternal> internalCacheIndexList,
            IndexTypeMapping indexTypeMapping,
            short typeId,
            int primaryId,
            byte[] extendedId,
            IndexStoreContext storeContext)
        {
            if (indexTypeMapping.MetadataStoredSeperately)
            {
                #region Check if metadata is stored seperately
                //Send a get message to local index storage and fetch index for IndexId
                RelayMessage getMsg = new RelayMessage(typeId, primaryId, extendedId, MessageType.Get);
                storeContext.IndexStorageComponent.HandleMessage(getMsg);

                if (getMsg.Payload != null)
                {
                    return getMsg.Payload.ByteArray;
                }
                #endregion
            }
            else
            {
                #region Check metadata on indexes
                foreach (CacheIndexInternal cacheIndexInternal in internalCacheIndexList)
                {
                    if (indexTypeMapping.IndexCollection[cacheIndexInternal.InDeserializationContext.IndexName].MetadataPresent)
                    {
                        return cacheIndexInternal.Metadata;
                    }
                }
                #endregion
            }
            return null;
        }
예제 #12
0
 public static IAsyncAction AddAsync(RelayMessage message)
 {
     return(AddAsyncHelper(message).AsAsyncAction());
 }
예제 #13
0
 /// <summary>
 ///	<para>Writes <paramref name="message"/> into <paramref name="stream"/>.
 ///	The position of <paramref name="stream"/> will not be reset to the
 ///	beginning following the write unlike in
 ///	<see cref="WriteRelayMessage(RelayMessage)" />.</para>
 /// </summary>
 /// <param name="message">The <see cref="RelayMessage"/>.</param>
 /// <param name="stream">The stream to write <paramref name="message"/> into.</param>
 public static void WriteRelayMessage(RelayMessage message, Stream stream)
 {
     Serializer.Serialize <RelayMessage>(stream, message);
 }
예제 #14
0
		private void HandleOutMessage(RelayMessage message)
		{
			try
			{
				counters.CountInputBytes(message);
				components.HandleOutMessage(message);
				counters.CountOutMessage(message);
				if (message.AllowsReturnPayload == false) message.Payload = null;
			}
			catch (Exception exc)
			{
				message.Payload = null;
                if (log.IsErrorEnabled)
                    log.ErrorFormat("Error handling message {0}: {1}", message, exc);
			}
		}
예제 #15
0
		/// <summary>
		/// Begins asynchronous processing of a single <see cref="T:MySpace.DataRelay.RelayMessage"/>.
		/// </summary>
		/// <param name="message">The <see cref="T:MySpace.DataRelay.RelayMessage"/>.</param>
		/// <param name="state">Callers can put any state they like here.</param>
		/// <param name="callback">The method to call upon completion.</param>
		/// <returns>
		/// Returns an <see cref="T:System.IAsyncResult"/>.
		/// </returns>
		public IAsyncResult BeginHandleMessage(RelayMessage message, object state, AsyncCallback callback)
		{
			if (!message.IsTwoWayMessage)
			{
				// cheat for now and just handle in messages synchronously
				// as long as the type doesn't use sync in messages then
				// we won't block on IO anyway.
				HandleMessage(message);
				return SynchronousAsyncResult.CreateAndComplete(callback, state);
			}

			
			SimpleLinkedList<Node> nodes = PrepareMessage(message, false);

			Node node;
			if (nodes.Pop(out node))
			{
				var result = new AsynchronousResult<Node>((ar, n, m) =>
				{
					n.EndHandleOutMessage(ar);
					int allowedRetries = NodeManager.Instance.GetRetryCountForMessage(message);
					while (message.ErrorType == RelayErrorType.NodeUnreachable && --allowedRetries >= 0)
					{
						if (PrepareMessage(message, true).Pop(out node))
						{
							node.HandleOutMessage(message);
						}
						else
						{
							message.SetError(RelayErrorType.NoNodesAvailable);
						}
					}
				}, node, message);
				var origCallback = callback;
				if (callback != null)
				{
					callback = ar =>
					{
						result.InnerResult = ar;
						origCallback(result);
					};
				}
				result.InnerResult = node.BeginHandleOutMessage(message, callback, state);
				return result;
			}
			else
			{
				message.SetError(RelayErrorType.NoNodesAvailable);
			}
			return SynchronousAsyncResult.CreateAndComplete(callback, state);
		}
예제 #16
0
        internal SimpleLinkedList <Node> GetNodesForMessage(RelayMessage message)
        {
            SimpleLinkedList <Node> nodes = null;

            if (message == null || message.RelayTTL < 1 || NodeGroups == null)
            {
                return(new SimpleLinkedList <Node>());
            }

            const bool useLegacySerialization = true;

            //commands that, from out of system, route to all groups
            if (message.IsGroupBroadcastMessage)
            {
                message.PrepareMessageToBeSent(useLegacySerialization);
                if (MyNodeGroup == null)                //out of system: all groups
                {
                    nodes = new SimpleLinkedList <Node>();
                    for (int groupIndex = 0; groupIndex < this.NodeGroups.Count; groupIndex++)
                    {
                        nodes.Push(NodeGroups[groupIndex].GetNodesForMessage(message));
                    }
                }
                else                //In system: my group
                {
                    nodes = MyNodeGroup.MyCluster.GetNodesForMessage(message);
                }
            }
            else
            {
                //Commands that always route to a single group
                NodeGroup group = GetNodeGroup(message.TypeId);
                if (group != null)
                {
                    message.PrepareMessageToBeSent(group.GroupDefinition.LegacySerialization);
                    nodes = group.GetNodesForMessage(message);
                }
                else
                {
                    message.PrepareMessageToBeSent(useLegacySerialization);
                    if (_log.IsErrorEnabled)
                    {
                        _log.ErrorFormat("No group found for {0}", message);
                    }
                    nodes = new SimpleLinkedList <Node>();
                }
            }

            if (nodes == null)
            {
                nodes = new SimpleLinkedList <Node>();
            }

            // If no nodes are returned, we predict that the caller
            // will drop the message.  Therefore we call the notification delegate.
            // This is admittedly a kludgy solution, but the only one
            // available without changing this method's signature.
            // A better solution should be adopted. [tchow 01/29/2008]
            if (nodes.Count == 0)
            {
                Forwarder.RaiseMessageDropped(message);
            }

            return(nodes);
        }
예제 #17
0
        private static void ExtractRequestParameters(string requestUri,
                                                     out ServerCommand command,
                                                     out string commandParam,
                                                     out RelayMessage requestMessage,
                                                     out string responseType)
        {
            responseType = "";
            //for now sticking with manual parsing because we have a limited command set.
            //if the command set gets much bigger we can switch to just using HttpUtility parsing and a name/value collection.
            char[] queryDelimeters = { '?', '=' };             //. is a hack to get favicon to work with enum parsing
            // /get/{typeid}/{objectid}
            // /status/{componentName}
            string[] querySplit = requestUri.Split(queryDelimeters);             //0=command string, then 1/2 = name/value etc
            string[] slashSplit = querySplit[0].Split('/');
            short    typeId;
            int      objectId;

            requestMessage = null;

            if (slashSplit.Length < 2)
            {
                throw new InvalidRequestException("Request Uri Invalid - " + requestUri);
            }

            //0- empty
            //1- command
            //2- typeId OR commandParam1
            //3- objectId
            string commandString = slashSplit[1];            //.ToLowerInvariant();

            commandParam = String.Empty;
            if (commandString.Length == 0)
            {
                command = ServerCommand.Empty;
            }
            else
            {
                if (commandString[0] < serverCommandLookupTable.Length)
                {
                    command = serverCommandLookupTable[commandString[0]];
                    switch (command)
                    {
                    case ServerCommand.Status:
                        if (slashSplit.Length > 2)
                        {
                            commandParam = slashSplit[2];
                        }
                        break;

                    case ServerCommand.Get:
                        if (slashSplit.Length > 3)
                        {
                            short.TryParse(slashSplit[2], out typeId);
                            int.TryParse(slashSplit[3], out objectId);
                            requestMessage = new RelayMessage(typeId, objectId, MessageType.Get);
                        }
                        break;
                    }
                }
                else
                {
                    throw new InvalidRequestException("Request Uri Invalid - " + requestUri);
                }
            }
        }
 public void Relay(RelayMessage message)
 {
     SendToServer(message);
 }
예제 #19
0
        /// <summary>
        /// Begins the handling of a complete message from a stream. All references
        /// to <see cref="MessageState.Message"/> must be released by the end of this method.
        /// </summary>
        /// <param name="message">The complete message that is to be handled.</param>
        /// <param name="callback">The delegate to call when complete.</param>
        /// <returns>Returns an <see cref="IAsyncResult"/>.</returns>
        /// <remarks>
        ///		<para>
        ///		All implementors must release any references to <see cref="MessageState.Message"/>
        ///		by the time that <see cref="BeginHandleMessage"/> returns.
        ///		</para>
        /// </remarks>
        public IAsyncResult BeginHandleMessage(MessageState message, AsyncCallback callback)
        {
            SocketHandlerAsyncResult result = new SocketHandlerAsyncResult(null, callback);

            //don't use callback directly, use result.Complete();
            callback = null;
            const bool wasSyncronous = true;

            //VERY IMPORTANT! don't hold any references to message or it's properties after leaving this method
            try
            {
                SocketCommand       command       = SocketCommand.Unknown;
                RelayMessage        relayMessage  = null;
                List <RelayMessage> relayMessages = null;

                try
                {
                    command = (SocketCommand)message.CommandId;
                }
                catch
                {
                    if (RelayNode.log.IsErrorEnabled)
                    {
                        RelayNode.log.ErrorFormat("Unrecognized commandID {0} sent to Relay Service via socket transport", message.CommandId);
                    }
                    result.CompleteOperation(wasSyncronous);
                    return(result);
                }

                switch (command)
                {
                case SocketCommand.Unknown:
                    if (RelayNode.log.IsErrorEnabled)
                    {
                        RelayNode.log.Error("SocketCommand.Unknown received");
                    }
                    result.CompleteOperation(wasSyncronous);
                    return(result);

                case SocketCommand.HandleOneWayMessage:
                case SocketCommand.HandleSyncMessage:
                    relayMessage = RelayMessageFormatter.ReadRelayMessage(message.Message);
                    relayMessage.ResultOutcome = RelayOutcome.Received;
                    _dataHandler.BeginHandleMessage(relayMessage, null, async => {
                        try
                        {
                            _dataHandler.EndHandleMessage(async);
                            if (command == SocketCommand.HandleSyncMessage)
                            {
                                result.ReplyMessage = relayMessage;
                            }
                        }
                        catch (Exception exc)
                        {
                            result.Exception = exc;
                        }
                        finally
                        {
                            result.CompleteOperation(async.CompletedSynchronously);
                        }
                    });
                    break;

                case SocketCommand.HandleOneWayMessages:
                case SocketCommand.HandleSyncMessages:
                    relayMessages = RelayMessageFormatter.ReadRelayMessageList(message.Message, msg => msg.ResultOutcome = RelayOutcome.Received);
                    _dataHandler.BeginHandleMessages(relayMessages, null, async =>
                    {
                        try
                        {
                            _dataHandler.EndHandleMessages(async);
                            if (command == SocketCommand.HandleSyncMessages)
                            {
                                result.ReplyMessages = relayMessages;
                            }
                        }
                        catch (Exception exc)
                        {
                            result.Exception = exc;
                        }
                        finally
                        {
                            result.CompleteOperation(async.CompletedSynchronously);
                        }
                    });
                    break;

                case SocketCommand.GetRuntimeInfo:
                    _enqueueGetComponentRuntimeInfo(result);
                    break;

                default:
                    if (RelayNode.log.IsErrorEnabled)
                    {
                        RelayNode.log.ErrorFormat("Unhandled command {0} sent to Relay Service via socket transport", command);
                    }
                    result.CompleteOperation(wasSyncronous);
                    return(result);
                }
            }
            catch (Exception exc)
            {
                result.Exception = exc;
                result.CompleteOperation(wasSyncronous);
            }

            return(result);
        }
예제 #20
0
 public void ServerRelay(RelayMessage message)
 {
     EnqueueMessage(message);
 }
예제 #21
0
 public void Relay(RelayMessage message)
 {
     ServerConfirmation(Confirmation.For(message));
     OnRelayMessage?.Invoke(this, message);
 }
예제 #22
0
		/// <summary>
		///	Performs processing on single message
		/// </summary>
		/// <exception cref="SyncRelayOperationException">
		/// When the type of an object is defined with settings
		///		<see cref="MySpace.DataRelay.Common.Schemas.TypeSettings"></see> with 
		///		SyncInMessages=true and 
		///		ThrowOnSyncFailure=true
		///	failed "in" executions will throw this exception
		/// </exception>
		/// <param name="message">Message to be processed</param>
		public void HandleMessage(RelayMessage message)
		{
			
			Node node;
			if (message.IsTwoWayMessage)
			{
				int allowedRetries = NodeManager.Instance.GetRetryCountForMessage(message);
				bool triedBefore = false;
				do
				{
					if (PrepareMessage(message, triedBefore).Pop(out node))
					{
						triedBefore = true;
						node.HandleOutMessage(message);
					}
					else
					{
						message.SetError(RelayErrorType.NoNodesAvailable);
					}
				}
				while (message.ErrorType == RelayErrorType.NodeUnreachable && --allowedRetries >= 0);
			}
			else
			{
				SimpleLinkedList<Node> nodes = PrepareMessage(message, false);
				SerializedRelayMessage serializedMessage = new SerializedRelayMessage(message);
				SerializedRelayMessage serializedMessageInterZone = null;

				bool messageHandled = true; // start with "true" so that we do not pop
				// if there are no items in "nodes"
				if (nodes.Count == 0)
				{
					message.SetError(RelayErrorType.NoNodesAvailable);
				}
				else
				{
					while (nodes.Pop(out node))
					{
						TypeSetting typeSetting = NodeManager.Instance.Config.TypeSettings.TypeSettingCollection[message.TypeId];

						bool typesettingThrowOnSyncFailure = false;
						bool typesettingSyncInMessages = false;
						if (null != typeSetting && !node.NodeCluster.MeInThisCluster)
						{
							typesettingSyncInMessages = typeSetting.SyncInMessages;
							typesettingThrowOnSyncFailure = typeSetting.ThrowOnSyncFailure;
						}

						if (_myNodeDefinition != null && _myNodeDefinition.Zone != node.NodeDefinition.Zone)
						{
							// Message needs to cross Zone bounderies
							if (serializedMessageInterZone == null)
							{
								serializedMessageInterZone = new SerializedRelayMessage(RelayMessage.CreateInterZoneMessageFrom(message));
							}

							if (message.ResultOutcome == null) message.ResultOutcome = RelayOutcome.Queued;
							node.HandleInMessage(serializedMessageInterZone);
						}
						else if (typesettingSyncInMessages)
						{
							messageHandled = node.HandleInMessageSync(message, typesettingSyncInMessages, typesettingThrowOnSyncFailure);
						}
						else
						{
							if (message.ResultOutcome == null) message.ResultOutcome = RelayOutcome.Queued;
							node.HandleInMessage(serializedMessage);
						}

						if (!messageHandled)
						{
							throw new SyncRelayOperationException(string.Format("Node {0} failed to process message {1}\r\n", node, message));
						}
					}
				}
			}
		}
예제 #23
0
		/// <summary>
		/// Replicates a message if the message can be replicated.
		/// </summary>
		/// <param name="message">The message to replicate.</param>
		/// <returns>Returns true if replicated.</returns>
		public bool Replicate(RelayMessage message)
		{
			RelayMessage replicationMessage = DoReplicate(message);
			if (replicationMessage != null)
			{
				HandleMessage(replicationMessage);
				return true;
			}

			return false;

		}
예제 #24
0
        /// <summary>
        /// Splits messages into various lists of in and out message destined for different nodes.
        /// </summary>
        /// <param name="messages"></param>
        /// <returns></returns>
        internal NodeWithMessagesCollection DistributeMessages(IList <RelayMessage> messages)
        {
            NodeWithMessagesCollection distribution = new NodeWithMessagesCollection();
            RelayMessage message;
            Node         node;

            for (int i = 0; i < messages.Count; i++)
            {
                if (messages[i] != null)
                {
                    message = messages[i];

                    RelayMessage interZoneMessage = null;

                    SimpleLinkedList <Node> nodesForMessage          = GetNodesForMessage(message);
                    SimpleLinkedList <Node> nodesForInterZoneMessage = null;

                    if (nodesForMessage.Count > 0)
                    {
                        message.AddressHistory.Add(MyIpAddress);
                    }
                    message.RelayTTL--;

                    #region Identify InterZone Messages
                    if (message.IsTwoWayMessage == false)
                    {
                        message.ResultOutcome = RelayOutcome.Queued;                         //will be queued, if sync will not get overwritten

                        // Identify nodes in foreign zones
                        int nodeCount = nodesForMessage.Count;
                        for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
                        {
                            nodesForMessage.Pop(out node);
                            if (_myNodeDefinition != null && _myNodeDefinition.Zone != node.NodeDefinition.Zone)
                            {
                                // Message needs to cross Zone bounderies
                                if (interZoneMessage == null)
                                {
                                    interZoneMessage         = RelayMessage.CreateInterZoneMessageFrom(message);
                                    nodesForInterZoneMessage = new SimpleLinkedList <Node>();
                                }
                                nodesForInterZoneMessage.Push(node);
                            }
                            else
                            {
                                nodesForMessage.Push(node);
                            }
                        }
                    }
                    #endregion

                    if (nodesForMessage.Count > 0)
                    {
                        DebugWriter.WriteDebugInfo(message, nodesForMessage);
                        distribution.Add(message, nodesForMessage);
                    }

                    if (nodesForInterZoneMessage != null && nodesForInterZoneMessage.Count > 0)
                    {
                        DebugWriter.WriteDebugInfo(interZoneMessage, nodesForInterZoneMessage);
                        distribution.Add(interZoneMessage, nodesForInterZoneMessage);
                    }
                }
            }

            return(distribution);
        }
        /// <summary>
        /// Calculates the life of the given <see cref="RelayMessage"/>.
        /// </summary>
        /// <param name="message">The given message.</param>
        public void CalculateLife(RelayMessage message)
        {
			CalculateLife(message.EnteredCurrentSystemAt, Stopwatch.GetTimestamp());
        }
 public override async Task OnRemoteHangup(RelayMessage message)
 {
     var hangingUpState = new VoipState_HangingUp();
     await Context.SwitchState(hangingUpState);
 }
예제 #27
0
		/// <summary>
		/// Processes a given <see cref="RelayMessage"/>.
		/// </summary>
		/// <remarks>
		///     <para>This method is the primary entry point for handling a <see cref="RelayMessage"/>. </para>
		/// </remarks>
		/// <param name="message">The given <see cref="RelayMessage"/>.</param>
		public void HandleMessage(RelayMessage message)
		{
			if (message != null)
			{
				messageTracer.WriteMessageInfo(message);

				if (components.DoHandleMessagesOfType(message.MessageType))
				{
					#region Assign SourceZone
					if (message.SourceZone == 0)
					{
						message.SourceZone = MyZone;
					}
					#endregion

					if (message.IsTwoWayMessage)
					{
						HandleOutMessage(message);
					}
					else
					{
						//post message to async queue
						inMessagePort.Post(message);
					}
				}
			}
		}
예제 #28
0
        /// <summary>
        ///	Performs processing on single message
        /// </summary>
        /// <exception cref="SyncRelayOperationException">
        /// When the type of an object is defined with settings
        ///		<see cref="MySpace.DataRelay.Common.Schemas.TypeSettings"></see> with
        ///		SyncInMessages=true and
        ///		ThrowOnSyncFailure=true
        ///	failed "in" executions will throw this exception
        /// </exception>
        /// <param name="message">Message to be processed</param>
        public virtual void HandleMessage(RelayMessage message)
        {
            Node node;

            if (message.IsTwoWayMessage)
            {
                if (PrepareMessage(message).Pop(out node))
                {
                    node.HandleOutMessage(message);
                }
                else
                {
                    message.SetError(RelayErrorType.NoNodesAvailable);
                }

                RetryHandleMessageOnError(message, node);
            }
            else
            {
                LinkedListStack <Node> nodes                      = PrepareMessage(message);
                SerializedRelayMessage serializedMessage          = new SerializedRelayMessage(message);
                SerializedRelayMessage serializedMessageInterZone = null;

                bool messageHandled = true;                 // start with "true" so that we do not pop
                // if there are no items in "nodes"
                if (nodes.Count == 0)
                {
                    message.SetError(RelayErrorType.NoNodesAvailable);
                }
                else
                {
                    while (nodes.Pop(out node))
                    {
                        TypeSetting typeSetting = NodeManager.Instance.Config.TypeSettings.TypeSettingCollection[message.TypeId];

                        bool typesettingThrowOnSyncFailure = false;
                        bool typesettingSyncInMessages     = false;
                        if (null != typeSetting && !node.NodeCluster.MeInThisCluster)
                        {
                            typesettingSyncInMessages     = typeSetting.SyncInMessages;
                            typesettingThrowOnSyncFailure = typeSetting.ThrowOnSyncFailure;
                        }

                        if (_myNodeDefinition != null && _myZone != node.Zone)
                        {
                            // Message needs to cross Zone bounderies
                            if (serializedMessageInterZone == null)
                            {
                                serializedMessageInterZone = new SerializedRelayMessage(RelayMessage.CreateInterZoneMessageFrom(message));
                            }

                            if (message.ResultOutcome == null)
                            {
                                message.ResultOutcome = RelayOutcome.Queued;
                            }
                            node.HandleInMessage(serializedMessageInterZone);
                        }
                        else if (typesettingSyncInMessages)
                        {
                            messageHandled = node.HandleInMessageSync(message, true, typesettingThrowOnSyncFailure);
                        }
                        else
                        {
                            if (message.ResultOutcome == null)
                            {
                                message.ResultOutcome = RelayOutcome.Queued;
                            }
                            node.HandleInMessage(serializedMessage);
                        }

                        if (!messageHandled)
                        {
                            throw new SyncRelayOperationException(string.Format("Node {0} failed to process message {1}\r\n", node, message));
                        }
                    }
                }
            }
        }
예제 #29
0
 public void Post(RelayMessage message)
 {
     Post(message, 0);
 }
 /// <summary>
 /// Called by the site to send a generic message up to the hub for further processing, using the SiteOperation enum
 /// to specify the command to execute
 /// </summary>
 /// <param name="message"></param>
 public void Send(RelayMessage message)
 {
     SendStatus("Calling generic Send");
     _siteHubProxy.Invoke <RelayMessage>("ProcessMessage", message);
 }
예제 #31
0
 void IRelayTransportExtended.SendSyncMessage(RelayMessage message)
 {
     DoAllExtendedTransports(t => t.SendSyncMessage(message));
 }
예제 #32
0
 private static void OnMessageReceived(object sender, RelayMessage e)
 {
     Console.WriteLine("{0}: {1}", e.SenderName, e.Text);
 }
 public void StartIncomingCall(RelayMessage message)
 {
 }
예제 #34
0
 public IAsyncAction RelayAsync(RelayMessage message)
 {
     return(SendToServer(message).AsAsyncAction());
 }
예제 #35
0
        /// <summary>
        /// Gets the CacheIndexInternal.
        /// </summary>
        /// <param name="storeContext">The store context.</param>
        /// <param name="typeId">The type id.</param>
        /// <param name="primaryId">The primary id.</param>
        /// <param name="indexId">The index id.</param>
        /// <param name="extendedIdSuffix">The extended id suffix.</param>
        /// <param name="indexName">Name of the index.</param>
        /// <param name="count">The count.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="inclusiveFilter">if set to <c>true</c> includes the items that pass the filter; otherwise , <c>false</c>.</param>
        /// <param name="indexCondition">The index condition.</param>
        /// <param name="deserializeHeaderOnly">if set to <c>true</c> if just CacheIndexInternal header is to be deserialized; otherwise, <c>false</c>.</param>
        /// <param name="getFilteredItems">if set to <c>true</c> get filtered items; otherwise, <c>false</c>.</param>
        /// <param name="primarySortInfo">The primary sort info.</param>
        /// <param name="localIdentityTagNames">The local identity tag names.</param>
        /// <param name="stringHashCodeDictionary">The string hash code dictionary.</param>
        /// <param name="capCondition">The cap condition.</param>
        /// <returns>CacheIndexInternal</returns>
        internal static CacheIndexInternal GetCacheIndexInternal(IndexStoreContext storeContext,
            short typeId,
            int primaryId,
            byte[] indexId,
            short extendedIdSuffix,
            string indexName,
            int count,
            Filter filter,
            bool inclusiveFilter,
            IndexCondition indexCondition,
            bool deserializeHeaderOnly,
            bool getFilteredItems,
            PrimarySortInfo primarySortInfo,
            List<string> localIdentityTagNames,
            Dictionary<int, bool> stringHashCodeDictionary,
            CapCondition capCondition)
        {
            CacheIndexInternal cacheIndexInternal = null;
            byte[] extendedId = FormExtendedId(indexId, extendedIdSuffix);
            RelayMessage getMsg = new RelayMessage(typeId, primaryId, extendedId, MessageType.Get);
            storeContext.IndexStorageComponent.HandleMessage(getMsg);

            if (getMsg.Payload != null) //CacheIndex exists
            {
                cacheIndexInternal = new CacheIndexInternal
                                         {
                                             InDeserializationContext = new InDeserializationContext
                                                                            {
                                                                                TypeId = getMsg.TypeId,
                                                                                TagHashCollection = storeContext.TagHashCollection,
                                                                                IndexId = indexId,
                                                                                IndexName = indexName,
                                                                                MaxItemsPerIndex = count,
                                                                                Filter = filter,
                                                                                InclusiveFilter = inclusiveFilter,
                                                                                IndexCondition = indexCondition,
                                                                                DeserializeHeaderOnly = deserializeHeaderOnly,
                                                                                CollectFilteredItems = getFilteredItems,
                                                                                PrimarySortInfo = primarySortInfo,
                                                                                LocalIdentityTagNames = localIdentityTagNames,
                                                                                StringHashCollection = storeContext.StringHashCollection,
                                                                                StringHashCodeDictionary = stringHashCodeDictionary,
                                                                                CapCondition = capCondition
                                                                            }
                                         };

                // This mess is required until Moods 2.0 migrated to have IVersionSerializable version of CacheIndexInternal
                // ** TBD - Should be removed later
                if (LegacySerializationUtil.Instance.IsSupported(getMsg.TypeId))
                {
                    MemoryStream stream = new MemoryStream(getMsg.Payload.ByteArray);
                    cacheIndexInternal.Deserialize(new CompactBinaryReader(stream));
                }
                else
                {
                    getMsg.GetObject(cacheIndexInternal);
                }
            }

            return cacheIndexInternal;
        }
예제 #36
0
 public async void Relay(RelayMessage message)
 {
     await SendToServer(message);
 }
예제 #37
0
		private SimpleLinkedList<Node> PrepareMessage(RelayMessage message, bool isRetry)
		{
			if (isRetry)
			{
				message.RelayTTL++;
			}
			SimpleLinkedList<Node> nodes = NodeManager.Instance.GetNodesForMessage(message);
			message.RelayTTL--;
			SetHydrationPolicy(message);
			
			if (nodes.Count > 0 && !isRetry)
			{
				System.Net.IPAddress myAddress = NodeManager.Instance.MyIpAddress;
				if (myAddress != null)
				{
					message.AddressHistory.Add(myAddress);
				}
			}
			DebugWriter.WriteDebugInfo(message, nodes);
			return nodes;
		}
예제 #38
0
 public void Relay(RelayMessage message)
 {
     InvokeHubChannel <IClientChannel>(message);
 }
예제 #39
0
		/// <summary>
		/// Calls the NotifyDroppedMessage event with the supplied message.
		/// </summary>        
		public static void RaiseMessageDropped(RelayMessage message)
		{
			if (MessageDropped != null)
			{
				SerializedRelayMessage serializedMessage = new SerializedRelayMessage(message);
				MessageDropped(serializedMessage);
			}
		}
예제 #40
0
 public void OnIceCandidate(RelayMessage message)
 {
     InvokeHubChannel <IVoipChannel>(message);
 }
예제 #41
0
		private static RelayMessage DoReplicate(RelayMessage message)
		{
			if (message.IsTwoWayMessage == false) return message;
			else
			{
				switch (message.MessageType)
				{
					case MessageType.SaveWithConfirm:
						return new RelayMessage(message, MessageType.Save);
					case MessageType.UpdateWithConfirm:
						return new RelayMessage(message, MessageType.Update);
					case MessageType.DeleteWithConfirm:
						return new RelayMessage(message, MessageType.Delete);
					case MessageType.DeleteAllInTypeWithConfirm:
						return new RelayMessage(message, MessageType.DeleteAllInType);
					case MessageType.NotificationWithConfirm:
						return new RelayMessage(message, MessageType.Notification);
					case MessageType.IncrementWithConfirm:
						return new RelayMessage(message, MessageType.Increment);
					case MessageType.DeleteAllWithConfirm:
						return new RelayMessage(message, MessageType.DeleteAll);
					case MessageType.DeleteInAllTypesWithConfirm:
						return new RelayMessage(message, MessageType.DeleteInAllTypes);
					default:
						return null;
				}
			}
		}
예제 #42
0
 public void OnIncomingCall(RelayMessage message)
 {
     InvokeHubChannel <IVoipChannel>(message);
 }
예제 #43
0
        /// <summary>
        /// Processes the specified cache index.
        /// </summary>
        /// <param name="cacheIndex">Index of the cache.</param>
        /// <param name="messageContext">The message context.</param>
        /// <param name="storeContext">The store context.</param>
        internal static void Process(CacheIndex cacheIndex, MessageContext messageContext, IndexStoreContext storeContext)
        {
            lock (LockingUtil.Instance.GetLock(messageContext.PrimaryId))
            {
                try
                {
                    IndexTypeMapping indexTypeMapping =
                        storeContext.StorageConfiguration.CacheIndexV3StorageConfig.IndexTypeMappingCollection[messageContext.TypeId];

                    #region Extract CacheIndex and Validate from incoming message

                    ValidateSave(cacheIndex);

                    #endregion

                    #region Log CacheIndex before processing
                    StringBuilder dbgIndexInfo = null;
                    if (LoggingUtil.Log.IsDebugEnabled)
                    {
                        dbgIndexInfo = new StringBuilder();
                        dbgIndexInfo.Append("TypeId=").Append(messageContext.TypeId).Append(Environment.NewLine);
                        dbgIndexInfo.Append(IndexServerUtils.GetPrintableCacheIndex(cacheIndex,
                            storeContext.TagHashCollection,
                            messageContext.TypeId));
                    }
                    #endregion

                    #region Init vars

                    List<RelayMessage> indexStorageMessageList = new List<RelayMessage>();
                    List<RelayMessage> dataStorageMessageList = new List<RelayMessage>();
                    List<CacheIndexInternal> internalIndexList = new List<CacheIndexInternal>();
                    List<IndexItem> cappedDeleteItemList = new List<IndexItem>();
                    CacheIndexInternal internalIndex;

                    #endregion

                    if (cacheIndex.IndexVirtualCountMapping == null)
                    {
                        #region Save Items

                        #region Extract CacheIndexInternal from index storage

                        if (cacheIndex.TargetIndexName == null) //Save to multiple indexes
                        {
                            #region Get CacheIndexInternal for multiple indexes

                            foreach (KeyValuePair<string /*IndexName*/, List<string> /*TagNameList*/> kvp in cacheIndex.IndexTagMapping)
                            {
                                Index indexInfo = indexTypeMapping.IndexCollection[kvp.Key];
                                internalIndex = IndexServerUtils.GetCacheIndexInternal(storeContext,
                                    messageContext.TypeId,
                                    cacheIndex.PrimaryId,
                                    cacheIndex.IndexId,
                                    indexInfo.ExtendedIdSuffix,
                                    kvp.Key,
                                    0,
                                    null,
                                    true,
                                    null,
                                    false,
                                    false,
                                    indexInfo.PrimarySortInfo,
                                    indexInfo.LocalIdentityTagList,
                                    indexInfo.StringHashCodeDictionary,
                                    null);

                                if (internalIndex != null)
                                {
                                    // update performance counter
                                    PerformanceCounters.Instance.SetCounterValue(
                                        PerformanceCounterEnum.NumberOfItemsInIndexPerSave,
                                        messageContext.TypeId,
                                        internalIndex.OutDeserializationContext.TotalCount);
                                }

                                if (internalIndex == null || cacheIndex.ReplaceFullIndex) //CacheIndexInternal does not exists or is to be discarded
                                {
                                    internalIndex = new CacheIndexInternal
                                                        {
                                                            InDeserializationContext = new InDeserializationContext
                                                                                           {
                                                                                               TypeId = messageContext.TypeId,
                                                                                               TagHashCollection = storeContext.TagHashCollection,
                                                                                               IndexId = cacheIndex.IndexId,
                                                                                               IndexName = kvp.Key,
                                                                                               InclusiveFilter = true,
                                                                                               PrimarySortInfo = indexInfo.PrimarySortInfo,
                                                                                               LocalIdentityTagNames = indexInfo.LocalIdentityTagList,
                                                                                               StringHashCollection = storeContext.StringHashCollection,
                                                                                               StringHashCodeDictionary = indexInfo.StringHashCodeDictionary
                                                                                           }
                                                        };
                                }

                                internalIndexList.Add(internalIndex);
                            }

                            #endregion
                        }
                        else //Save to single index
                        {
                            #region Get CacheIndexInternal for TargetIndexName

                            Index indexInfo = indexTypeMapping.IndexCollection[cacheIndex.TargetIndexName];

                            internalIndex = IndexServerUtils.GetCacheIndexInternal(storeContext,
                                messageContext.TypeId,
                                cacheIndex.PrimaryId,
                                cacheIndex.IndexId,
                                indexInfo.ExtendedIdSuffix,
                                cacheIndex.TargetIndexName,
                                0,
                                null,
                                true,
                                null,
                                false,
                                false,
                                indexInfo.PrimarySortInfo,
                                indexInfo.LocalIdentityTagList,
                                indexInfo.StringHashCodeDictionary,
                                null);

                            if (internalIndex != null)
                            {
                                // update performance counter
                                PerformanceCounters.Instance.SetCounterValue(
                                    PerformanceCounterEnum.NumberOfItemsInIndexPerSave,
                                    messageContext.TypeId,
                                    internalIndex.OutDeserializationContext.TotalCount);
                            }

                            if (internalIndex == null || cacheIndex.ReplaceFullIndex) //CacheIndexInternal does not exists or is to be discarded
                            {
                                internalIndex = new CacheIndexInternal
                                {
                                    InDeserializationContext = new InDeserializationContext
                                                                             {
                                                                                 TypeId = messageContext.TypeId,
                                                                                 TagHashCollection = storeContext.TagHashCollection,
                                                                                 IndexId = cacheIndex.IndexId,
                                                                                 IndexName = cacheIndex.TargetIndexName,
                                                                                 InclusiveFilter = true,
                                                                                 PrimarySortInfo = indexInfo.PrimarySortInfo,
                                                                                 LocalIdentityTagNames = indexInfo.LocalIdentityTagList,
                                                                                 StringHashCollection = storeContext.StringHashCollection,
                                                                                 StringHashCodeDictionary = indexInfo.StringHashCodeDictionary
                                                                             }
                                };
                            }

                            internalIndexList.Add(internalIndex);

                            #endregion

                        }
                        #endregion

                        #region Log CacheIndexInternals before save
                        if (LoggingUtil.Log.IsDebugEnabled && dbgIndexInfo != null)
                        {
                            dbgIndexInfo.Append(Environment.NewLine).Append(string.Format("BEFORE SAVE {0}",
                                                        IndexServerUtils.GetPrintableCacheIndexInternalList(
                                                            internalIndexList,
                                                            storeContext.TagHashCollection,
                                                            messageContext.TypeId)));
                        }
                        #endregion

                        #region Process Delete and Add List
                        try
                        {
                            #region Process Delete List

                            if (cacheIndex.DeleteList.Count > 0 && !cacheIndex.ReplaceFullIndex)
                            {
                                ProcessDeleteList(internalIndexList, cacheIndex.DeleteList, messageContext.TypeId);
                            }

                            #endregion

                            #region Process Add List

                            if (cacheIndex.AddList.Count > 0 || cacheIndex.UpdateMetadata)
                            {
                                ProcessAddList(internalIndexList, cappedDeleteItemList, cacheIndex, storeContext, indexTypeMapping);
                            }

                            #endregion
                        }
                        catch
                        {
                            LoggingUtil.Log.Debug(IndexServerUtils.GetPrintableCacheIndexInternalList(internalIndexList, storeContext.TagHashCollection, messageContext.TypeId));
                            throw;
                        }
                        #endregion

                        #region Log CacheIndexInternals after save
                        if (LoggingUtil.Log.IsDebugEnabled && dbgIndexInfo != null)
                        {
                            dbgIndexInfo.Append(Environment.NewLine).Append(string.Format("AFTER SAVE {0}",
                                                        IndexServerUtils.GetPrintableCacheIndexInternalList(internalIndexList,
                                                            storeContext.TagHashCollection,
                                                            messageContext.TypeId)));
                        }
                        #endregion

                        #region Data store relay messages for deletes and saves

                        if (DataTierUtil.ShouldForwardToDataTier(messageContext.RelayTTL,
                            messageContext.SourceZone,
                            storeContext.MyZone,
                            indexTypeMapping.IndexServerMode) && !cacheIndex.PreserveData)
                        {
                            byte[] fullDataId;
                            short relatedTypeId;
                            if (!storeContext.TryGetRelatedIndexTypeId(messageContext.TypeId, out relatedTypeId))
                            {
                                LoggingUtil.Log.ErrorFormat("Invalid RelatedTypeId for TypeId - {0}", messageContext.TypeId);
                                throw new Exception("Invalid RelatedTypeId for TypeId - " + messageContext.TypeId);
                            }

                            #region Delete Messages

                            foreach (IndexItem indexItem in cacheIndex.DeleteList)
                            {
                                fullDataId = DataTierUtil.GetFullDataId(cacheIndex.IndexId, indexItem, indexTypeMapping.FullDataIdFieldList);
                                if (fullDataId != null)
                                {
                                    dataStorageMessageList.Add(new RelayMessage(relatedTypeId,
                                                                   IndexCacheUtils.GeneratePrimaryId(fullDataId),
                                                                   fullDataId,
                                                                   MessageType.Delete));
                                }
                            }

                            #endregion

                            #region Save Messages

                            foreach (IndexDataItem indexDataItem in cacheIndex.AddList)
                            {
                                fullDataId = DataTierUtil.GetFullDataId(cacheIndex.IndexId, indexDataItem, indexTypeMapping.FullDataIdFieldList);

                                if (fullDataId != null)
                                {
                                    dataStorageMessageList.Add(new RelayMessage(relatedTypeId,
                                                                    IndexCacheUtils.GeneratePrimaryId(fullDataId),
                                                                    fullDataId,
                                                                    DateTime.Now,
                                                                    indexDataItem.Data ?? new byte[0],
                                                                    storeContext.GetCompressOption(messageContext.TypeId),
                                                                    MessageType.Save));

                                    if (indexDataItem.Data == null || indexDataItem.Data.Length == 0)
                                    {

                                        LoggingUtil.Log.WarnFormat("Saving null data for TypeId: {0}, IndexId: {1}, ItemId: {2}, FullDataId: {3}, PrimaryId: {4}",
                                                                    relatedTypeId,
                                                                    IndexCacheUtils.GetReadableByteArray(cacheIndex.IndexId),
                                                                    IndexCacheUtils.GetReadableByteArray(indexDataItem.ItemId),
                                                                    IndexCacheUtils.GetReadableByteArray(fullDataId),
                                                                    IndexCacheUtils.GeneratePrimaryId(fullDataId));
                                    }

                                }
                            }

                            #endregion

                            #region Capped Item Delete Messages

                            foreach (IndexItem indexItem in cappedDeleteItemList)
                            {
                                fullDataId = DataTierUtil.GetFullDataId(cacheIndex.IndexId, indexItem, indexTypeMapping.FullDataIdFieldList);
                                if (fullDataId != null)
                                {
                                    dataStorageMessageList.Add(new RelayMessage(relatedTypeId,
                                                                   IndexCacheUtils.GeneratePrimaryId(fullDataId),
                                                                   fullDataId,
                                                                   MessageType.Delete));
                                }
                            }

                            #endregion

                            #region Send relay mesaages to data store

                            if (dataStorageMessageList.Count > 0)
                            {
                                storeContext.ForwarderComponent.HandleMessages(dataStorageMessageList);
                            }

                            #endregion
                        }

                        #endregion

                        #endregion

                        if (dbgIndexInfo != null)
                        {
                            LoggingUtil.Log.Debug(dbgIndexInfo.ToString());
                        }
                    }
                    else
                    {
                        #region Update Virtual Count

                        foreach (KeyValuePair<string /*IndexName*/, int /*VirtualCount*/> kvp in cacheIndex.IndexVirtualCountMapping)
                        {
                            Index indexInfo = indexTypeMapping.IndexCollection[kvp.Key];
                            internalIndex = IndexServerUtils.GetCacheIndexInternal(storeContext,
                                                                                   messageContext.TypeId,
                                                                                   cacheIndex.PrimaryId,
                                                                                   cacheIndex.IndexId,
                                                                                   indexInfo.ExtendedIdSuffix,
                                                                                   kvp.Key,
                                                                                   0,
                                                                                   null,
                                                                                   true,
                                                                                   null,
                                                                                   true,
                                                                                   false,
                                                                                   indexInfo.PrimarySortInfo,
                                                                                   indexInfo.LocalIdentityTagList,
                                                                                   indexInfo.StringHashCodeDictionary,
                                                                                   null);

                            if (internalIndex == null)
                            {
                                internalIndex = new CacheIndexInternal
                                                    {
                                                        InDeserializationContext = new InDeserializationContext
                                                                                            {
                                                                                                TypeId = messageContext.TypeId,
                                                                                                TagHashCollection = storeContext.TagHashCollection,
                                                                                                IndexId = cacheIndex.IndexId,
                                                                                                IndexName = kvp.Key,
                                                                                                InclusiveFilter = true,
                                                                                                DeserializeHeaderOnly = true,
                                                                                                PrimarySortInfo = indexInfo.PrimarySortInfo,
                                                                                                LocalIdentityTagNames = indexInfo.LocalIdentityTagList,
                                                                                                StringHashCollection = storeContext.StringHashCollection,
                                                                                                StringHashCodeDictionary = indexInfo.StringHashCodeDictionary
                                                                                            }
                                                    };
                            }
                            else
                            {
                                // update performance counter
                                PerformanceCounters.Instance.SetCounterValue(
                                    PerformanceCounterEnum.NumberOfItemsInIndexPerSave,
                                    messageContext.TypeId,
                                    internalIndex.OutDeserializationContext.TotalCount);
                            }

                            internalIndex.VirtualCount = kvp.Value;
                            internalIndexList.Add(internalIndex);
                        }
                        #endregion
                    }

                    #region Index storage relay messages for each CacheIndexInternal

                    #region Metadata

                    if (indexTypeMapping.MetadataStoredSeperately && cacheIndex.UpdateMetadata)
                    {
                        indexStorageMessageList.Add(new RelayMessage(messageContext.TypeId,
                                                         cacheIndex.PrimaryId,
                                                         cacheIndex.IndexId,
                                                         DateTime.Now,
                                                         cacheIndex.Metadata ?? new byte[0],
                                                         storeContext.GetCompressOption(messageContext.TypeId),
                                                         MessageType.Save));
                    }

                    #endregion

                    #region Index(es)

                    byte[] payload;
                    CompactBinaryWriter writer;
                    RelayMessage indexStorageMessage;
                    byte[] extendedId;

                    foreach (CacheIndexInternal cacheIndexInternal in internalIndexList)
                    {
                        extendedId = IndexServerUtils.FormExtendedId(
                            cacheIndex.IndexId,
                            indexTypeMapping.IndexCollection[cacheIndexInternal.InDeserializationContext.IndexName].ExtendedIdSuffix);

                        // This mess is required until Moods 2.0 migrated to have IVersionSerializable version of CacheIndexInternal
                        // ** TBD - Should be removed later
                        if (LegacySerializationUtil.Instance.IsSupported(messageContext.TypeId))
                        {
                            writer = new CompactBinaryWriter(new BinaryWriter(new MemoryStream()));
                            cacheIndexInternal.Serialize(writer);
                            payload = new byte[writer.BaseStream.Length];
                            writer.BaseStream.Position = 0;
                            writer.BaseStream.Read(payload, 0, payload.Length);

                            indexStorageMessage = new RelayMessage(messageContext.TypeId,
                                 cacheIndex.PrimaryId,
                                 extendedId,
                                 DateTime.Now,
                                 payload,
                                 storeContext.GetCompressOption(messageContext.TypeId),
                                 MessageType.Save);
                        }
                        else
                        {
                            indexStorageMessage = RelayMessage.GetSaveMessageForObject(messageContext.TypeId,
                                cacheIndex.PrimaryId,
                                extendedId,
                                DateTime.Now,
                                cacheIndexInternal,
                                storeContext.GetCompressOption(messageContext.TypeId));
                        }

                        indexStorageMessageList.Add(indexStorageMessage);
                    }

                    #endregion

                    #region Send relay mesaages to index storage

                    storeContext.IndexStorageComponent.HandleMessages(indexStorageMessageList);

                    #endregion

                    #endregion
                }
                catch (Exception ex)
                {
                    LoggingUtil.Log.DebugFormat("CacheIndex: {0}", IndexServerUtils.GetPrintableCacheIndex(cacheIndex, storeContext.TagHashCollection, messageContext.TypeId));
                    throw new Exception("TypeId " + messageContext.TypeId + " -- Error processing save message.", ex);
                }
            }

        }
예제 #44
0
 public void OnOutgoingCallRejected(RelayMessage message)
 {
     InvokeHubChannel <IVoipChannel>(message);
 }
예제 #45
0
		public IAsyncResult BeginHandleMessage(RelayMessage message, object state, AsyncCallback callback)
		{
			RelayMessageAsyncResult resultMessage = new RelayMessageAsyncResult(message, state, callback);
			try
			{
				if (message != null)
				{
					messageTracer.WriteMessageInfo(message);

					if (components.DoHandleMessagesOfType(message.MessageType))
					{
						#region Assign SourceZone
						if (message.SourceZone == 0)
						{
							message.SourceZone = MyZone;
						}
						#endregion

						if (message.IsTwoWayMessage)
						{
							if (outMessagesPort == null)
							{
								throw new InvalidOperationException("DataRelay is misconfigured.  BeginHandleMessages was called without OutMessagesOnRelayThreads enabled.");
							}
							outMessagePort.Post(resultMessage);	
						}
						else
						{
							//post message to async queue
							inMessagePort.Post(message);
							//by wasSync being false we're letting the caller know
							//that complete is being called on the same thread
							const bool wasSynchronous = true;
							resultMessage.CompleteOperation(wasSynchronous);
						}
					}
				}
			}
			catch (Exception exc)
			{
                if (log.IsErrorEnabled)
                {
                    log.ErrorFormat("Exception doing BeginHandleMessage: {0}", exc);                    
                }
				resultMessage.Exception = exc;
				const bool wasSynchronous = true;
				resultMessage.CompleteOperation(wasSynchronous);
			}
			return resultMessage;
		}
예제 #46
0
 public void OnRemoteHangup(RelayMessage message)
 {
     InvokeHubChannel <IVoipChannel>(message);
 }
예제 #47
0
		private void HandleInMessage(RelayMessage message)
		{
			try
			{
				counters.CountInputBytes(message);
				components.HandleInMessage(message);
				counters.CountInMessage(message);
			}
			catch (Exception exc)
			{
                if (log.IsErrorEnabled)
                    log.ErrorFormat("Error handling message {0}: {1}", message, exc);
			}
		}
예제 #48
0
        public override async Task OnSdpOfferAsync(RelayMessage message)
        {
            bool isHold = SdpUtils.IsHold(message.Payload);

            if (isHold)
            {
                Context.VoipHelper.SetCallHeld();
            }
            else
            {
                Context.VoipHelper.SetCallActive(Context.PeerId, Context.IsVideoEnabled);
            }

            // If PeerConnection is not null, then this is an SDP renegotiation.
            if (Context.PeerConnection == null)
            {
                var config = new RTCConfiguration
                {
                    IceServers = WebRtcSettingsUtils.ToRTCIceServer(IceServerSettings.IceServers)
                };
                Context.PeerConnection = new RTCPeerConnection(config);
            }

            if (isHold)
            {
                // Even for just a renegotiation, it's easier to just teardown the media capture and start over.
                if (Context.LocalStream != null)
                {
                    Context.PeerConnection.RemoveStream(Context.LocalStream);
                }
                Context.StopStream(Context.LocalStream);
                Context.LocalStream = null;
                Context.StopStream(Context.RemoteStream);
                Context.RemoteStream = null;
                Context.ResetRenderers();
            }

            MediaVideoTrack oldVideoTrack = Context.RemoteStream?.GetVideoTracks()?.FirstOrDefault();

            await Context.PeerConnection.SetRemoteDescription(new RTCSessionDescription(RTCSdpType.Offer, message.Payload));

            MediaVideoTrack newVideoTrack = Context.RemoteStream?.GetVideoTracks()?.FirstOrDefault();

            bool videoTrackChanged = oldVideoTrack != null && newVideoTrack != null &&
                                     oldVideoTrack.Id.CompareTo(newVideoTrack.Id) != 0;

            if (videoTrackChanged)
            {
                Context.ResetRemoteRenderer();
                var source = RtcManager.Instance.Media.CreateMediaSource(newVideoTrack, CallContext.PeerMediaStreamId);
                Context.RemoteVideoRenderer.SetupRenderer(Context.ForegroundProcessId, source, Context.RemoteVideoControlSize);
            }
            else if (!isHold)
            {
                Context.LocalStream = await RtcManager.Instance.Media.GetUserMedia(new RTCMediaStreamConstraints
                {
                    videoEnabled = Context.IsVideoEnabled,
                    audioEnabled = true
                });

                Context.PeerConnection.AddStream(Context.LocalStream);

                // Setup the rendering of the local capture.
                var tracks = Context.LocalStream.GetVideoTracks();
                if (tracks.Count > 0)
                {
                    var source = RtcManager.Instance.Media.CreateMediaSource(tracks[0], CallContext.LocalMediaStreamId);
                    Context.LocalVideoRenderer.SetupRenderer(Context.ForegroundProcessId, source, Context.LocalVideoControlSize);
                }
            }

            var sdpAnswer = await Context.PeerConnection.CreateAnswer();

            await Context.PeerConnection.SetLocalDescription(sdpAnswer);

            var sdpVideoCodecIds = SdpUtils.GetVideoCodecIds(message.Payload);

            if (sdpVideoCodecIds.Count > 0)
            {
                Context.VideoCodecUsed = Array.Find((await Hub.Instance.MediaSettingsChannel.GetVideoCodecsAsync())?.Codecs,
                                                    it => it.Id == sdpVideoCodecIds.First())?.FromDto();
            }

            Context.SendToPeer(RelayMessageTags.SdpAnswer, sdpAnswer.Sdp);
            if (isHold)
            {
                await Context.SwitchState(new Held());
            }
            else
            {
                await Context.SwitchState(new Active());
            }
        }
예제 #49
0
		/// <summary>
		/// Use this method to process an 'In' <see cref="RelayMessage"/> while providing a list of 
		/// component types that should not receive the message.
		/// </summary>
		/// <param name="message">The message to process</param>
		/// <param name="exclusionList">The components that should not receive the message</param>
		/// <exception cref="InvalidOperationException"> This exception is thrown if the message is NOT an 'In 'message type </exception>
		void IRelayNodeServices.HandleInMessageWithComponentExclusionList(RelayMessage message, params Type[] exclusionList)
		{

			if (message != null)
			{
				if (message.MessageType == MessageType.Get ||
					 message.MessageType == MessageType.Query ||
					 message.MessageType == MessageType.Invoke)
				{
					throw new InvalidOperationException("HandleInMessageWithComponentExclusionList() processes 'In' MessageTypes Only.  Encountred Out MessageType: " + message.MessageType);
				}

				messageTracer.WriteMessageInfo(message);

				if (components.DoHandleMessagesOfType(message.MessageType))
				{
					#region Assign SourceZone
					if (message.SourceZone == 0)
					{
						message.SourceZone = MyZone;
					}
					#endregion

					// Create RelayMessageWithContext                   
					RelayMessageWithContext msgWithContext =
						 new RelayMessageWithContext(
							  message,
							  new RelayMessageProcessingContext(exclusionList));

					//post message to async queue
					inMessageWithContextPort.Post(msgWithContext);
				}
			}
		}
예제 #50
0
		internal static void LogNodeException(RelayMessage message, Node node, Exception ex)
		{
			if (_log.IsErrorEnabled)
			{
				if (ex is SocketException)
				{
					SocketException sex = (SocketException)ex;
					_log.ErrorFormat("Socket error {0} while handling {1} for node {2}.", sex.SocketErrorCode, message, node.ToExtendedString());

				}
				else
				{
					_log.ErrorFormat("Error handling {0} for node {1}: {2}", message, node.ToExtendedString(), ex);
				}
			}
		}
예제 #51
0
 public void Post(RelayMessage message, short waitId)
 {
     if (Log.IsDebugEnabled)
     {
         Log.DebugFormat("Post() Port posts message to DispatcherQueue '{0}' (TypeId={1}, MessageId={2})"
             , dispatcherQueue.Name, message.TypeId, message.Id);
     }
     QueueItem queueItem = new QueueItem();
     queueItem.WaitId = waitId;
     queueItem.Message = message;
     messagePort.Post(queueItem);
 }
 public void SetActiveIncomingCall(RelayMessage message, bool videoEnabled)
 {
 }
예제 #53
0
 public void OnSdpOffer(RelayMessage message)
 {
     InvokeHubChannel <IVoipChannel>(message);
 }
예제 #54
0
        /// <summary>
        /// Translates the given <see cref="Stream"/> into a <see cref="RelayMessage"/>.
        /// </summary>
        /// <param name="stream">The given stream.</param>
        /// <returns>The <see cref="RelayMessage"/> contained in the given stream..</returns>
        public static RelayMessage ReadRelayMessage(Stream stream)
        {
            RelayMessage op = RelayMessage.GetInstanceFromStream(stream);

            return(op);
        }
예제 #55
0
 public override async Task IncomingCallAsync(RelayMessage message)
 {
     var localRingingState = new LocalRinging(message);
     await Context.SwitchState(localRingingState);
 }
예제 #56
0
        public void TestIndexGap()
        {
            var test = CreateAPI();

            var simulator = test.simulator;
            var owner     = test.owner;
            var sender    = PhantasmaKeys.Generate();
            var receiver  = PhantasmaKeys.Generate();
            var node      = PhantasmaKeys.FromWIF(nodeWIF);
            var nexus     = simulator.Nexus;
            var api       = test.api;

            var contractAddress = SmartContract.GetAddressForName("relay");

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, DomainSettings.FuelTokenSymbol, 100000000);
            simulator.EndBlock();

            TopUpChannel(simulator, sender, 1000000);

            var indexGap     = 5;
            var messageCount = 3;
            var messages     = new RelayMessage[messageCount];

            var random = new Random();

            for (int i = 0; i < messageCount; i++)
            {
                var script = new byte[100];
                random.NextBytes(script);

                var message = new RelayMessage
                {
                    nexus     = nexus.Name,
                    index     = i * indexGap,
                    receiver  = receiver.Address, //node.Address,
                    script    = script,
                    sender    = sender.Address,
                    timestamp = Timestamp.Now
                };
                messages[i] = message;

                var    receipt       = RelayReceipt.FromMessage(message, sender);
                string serializedHex = Base16.Encode(receipt.Serialize());

                api.RelaySend(serializedHex);
            }

            var receipts = (ArrayResult)api.RelayReceive(receiver.Address.Text);

            Assert.IsTrue(receipts.values.Length == messageCount);

            for (int i = 0; i < messageCount; i++)
            {
                var obj = receipts.values[i];
                Assert.IsTrue(obj is ReceiptResult);

                var receiptResult = (ReceiptResult)obj;
                Assert.IsTrue(receiptResult.nexus == messages[i].nexus);
                Assert.IsTrue(new BigInteger(receiptResult.index, 10) == messages[i].index);
                //Assert.IsTrue(receiptResult.receiver == messages[i].receiver);
                //Assert.IsTrue(receiptResult.script == messages[i].script);
                //Assert.IsTrue(receiptResult.sender == messages[i].sender);
                Assert.IsTrue(receiptResult.timestamp == messages[i].timestamp);
            }

            var lastMessage = messages[messageCount - 1];
            var lastReceipt = RelayReceipt.FromMessage(lastMessage, sender);

            var fuelToken = simulator.Nexus.GetTokenInfo(simulator.Nexus.RootStorage, DomainSettings.FuelTokenSymbol);

            var senderInitialBalance   = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, sender.Address);
            var chainInitialBalance    = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, contractAddress);
            var receiverInitialBalance = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, node.Address);

            simulator.BeginBlock();
            var tx = simulator.GenerateCustomTransaction(sender, ProofOfWork.None, () =>
                                                         ScriptUtils.BeginScript().AllowGas(sender.Address, Address.Null, 1, 9999)
                                                         .CallContract("relay", nameof(RelayContract.SettleChannel), lastReceipt).
                                                         SpendGas(sender.Address).EndScript());

            simulator.EndBlock();

            var txCost = simulator.Nexus.RootChain.GetTransactionFee(tx);

            var senderFinalBalance   = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, sender.Address);
            var chainFinalBalance    = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, contractAddress);
            var receiverFinalBalance = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, fuelToken, receiver.Address);

            var expectedFee = RelayFeePerMessage * (lastReceipt.message.index + 1);

            Assert.IsTrue(senderFinalBalance == senderInitialBalance - txCost);
            Assert.IsTrue(receiverFinalBalance == receiverInitialBalance + (expectedFee / 2));
            Assert.IsTrue(chainFinalBalance == chainInitialBalance - (expectedFee / 2));    //the sender's balance is escrowed in the chain address, so the chain just sends the other half of the fee away to the receiver
        }
예제 #57
0
		public List<RelayMessage>[] GetModdedMessageLists(RelayMessage[] messages)
		{
			List<RelayMessage>[] lists = new List<RelayMessage>[Clusters.Count];

			for (int i = 0; i < messages.Length; i++)
			{
				int itemId = messages[i].Id;
				
				int clusterIndex = GetModdedIndex(itemId);
				
				if (lists[clusterIndex] == null)
				{
					lists[clusterIndex] = new List<RelayMessage>(messages.Length);
				}
				lists[clusterIndex].Add(messages[i]);
			}

			return lists;
		}
예제 #58
0
        public void TestSendReceive()
        {
            var test = CreateAPI();

            var simulator = test.simulator;
            var owner     = test.owner;
            var sender    = PhantasmaKeys.Generate();
            var receiver  = PhantasmaKeys.Generate();
            var node      = PhantasmaKeys.FromWIF(nodeWIF);
            var nexus     = simulator.Nexus;
            var api       = test.api;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, DomainSettings.FuelTokenSymbol, 100000000);
            simulator.EndBlock();

            var desiredChannelBalance = RelayFeePerMessage * 10;

            TopUpChannel(simulator, sender, desiredChannelBalance);

            var channelBalance = nexus.RootChain.InvokeContract(simulator.Nexus.RootStorage, "relay", "GetBalance", sender.Address).AsNumber();

            Assert.IsTrue(channelBalance == desiredChannelBalance);

            var messageCount = 5;
            var messages     = new RelayMessage[messageCount];

            var random = new Random();

            for (int i = 0; i < messageCount; i++)
            {
                var script = new byte[100];
                random.NextBytes(script);

                var message = new RelayMessage
                {
                    nexus     = nexus.Name,
                    index     = i,
                    receiver  = receiver.Address, //node.Address,
                    script    = script,
                    sender    = sender.Address,
                    timestamp = Timestamp.Now
                };
                messages[i] = message;

                var    receipt       = RelayReceipt.FromMessage(message, sender);
                string serializedHex = Base16.Encode(receipt.Serialize());

                api.RelaySend(serializedHex);
            }

            var receipts = (ArrayResult)api.RelayReceive(receiver.Address.Text);

            Assert.IsTrue(receipts.values.Length == messageCount);

            for (int i = 0; i < messageCount; i++)
            {
                var obj = receipts.values[i];
                Assert.IsTrue(obj is ReceiptResult);

                var receiptResult = (ReceiptResult)obj;
                Assert.IsTrue(receiptResult.nexus == messages[i].nexus);
                Assert.IsTrue(new BigInteger(receiptResult.index, 10) == messages[i].index);
                //Assert.IsTrue(receiptResult.receiver == messages[i].receiver);
                //Assert.IsTrue(receiptResult.script == messages[i].script);
                //Assert.IsTrue(receiptResult.sender == messages[i].sender);
                Assert.IsTrue(receiptResult.timestamp == messages[i].timestamp);
            }
        }
예제 #59
0
		internal SimpleLinkedList<Node> GetNodesForMessage(RelayMessage message)
		{
			if (!Activated)
			{
				return new SimpleLinkedList<Node>();
			}
			
			NodeCluster cluster;
			SimpleLinkedList<Node> nodes = null;
			
			//messages that, from out of system, go to each cluster
			if(message.IsClusterBroadcastMessage)
			{
				if (MyCluster == null) //out of system, each cluster
				{
					nodes = new SimpleLinkedList<Node>();
					for (int clusterIndex = 0; clusterIndex < Clusters.Count; clusterIndex++)
					{
						nodes.Push(Clusters[clusterIndex].GetNodesForMessage(message));							
					}
				}
				else //in system, my cluster
				{
					nodes = MyCluster.GetNodesForMessage(message);
				}
			}
			else
			{
				//messages that route to one modded cluster
				//to modded cluster in group
				cluster = GetClusterForId(message.Id, message.IsInterClusterMsg);
				if (cluster != null)
				{
					if (message.IsInterClusterMsg && cluster.MeInThisCluster)
					{
						nodes = new SimpleLinkedList<Node>();
						nodes.Push(cluster.Me);
					}
					else
					{
						nodes = cluster.GetNodesForMessage(message);
					}
				}
				else
				{
					nodes = new SimpleLinkedList<Node>();
				}
				
			}
			return nodes;
		}
예제 #60
0
 public void Relay(RelayMessage message)
 {
     _signalingClient.Relay(message);
 }