コード例 #1
0
ファイル: InvocationDetailsTests.cs プロジェクト: yallie/zyan
        public void InvocationDetailsObtainPublicMethodInfo()
        {
            var foo = new InvocationDetails
            {
                Type = typeof(Service),
                InterfaceType = typeof(IService),
                MethodName = "Foo",
                ParamTypes = new Type[0],
                GenericArguments = new Type[0]
            };

            Assert.IsTrue(foo.FindMethodInfo());
            Assert.IsNotNull(foo.MethodInfo);
            Assert.AreEqual(foo.MethodName, foo.MethodInfo.Name);
        }
コード例 #2
0
ファイル: InvocationDetailsTests.cs プロジェクト: yallie/zyan
        public void InvocationDetailsObtainPrivateMethodInfo()
        {
            var bar = new InvocationDetails
            {
                Type = typeof(Service),
                InterfaceType = typeof(IService),
                MethodName = "Bar",
                ParamTypes = new Type[0],
                GenericArguments = new Type[0]
            };

            Assert.IsTrue(bar.FindMethodInfo());
            Assert.IsNotNull(bar.MethodInfo);
            Assert.AreNotEqual(bar.MethodName, bar.MethodInfo.Name);
        }
コード例 #3
0
ファイル: ZyanDispatcher.cs プロジェクト: zyanfx/Zyan
        /// <summary>
        /// Sets the session for the current worker thread.
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void Invoke_SetSession(InvocationDetails details)
        {
            // validate session
            var sessionID = details.CallContextData.Store.ContainsKey("sessionid") ? (Guid)details.CallContextData.Store["sessionid"] : Guid.Empty;

            if (!_host.SessionManager.ExistSession(sessionID))
            {
                throw new InvalidSessionException(string.Format(LanguageResource.InvalidSessionException_SessionIDInvalid, sessionID));
            }

            // double-check to avoid race condition
            var session = _host.SessionManager.GetSessionBySessionID(sessionID);

            if (session == null)
            {
                throw new InvalidSessionException(string.Format(LanguageResource.InvalidSessionException_SessionIDInvalid, sessionID));
            }

            // set current session
            details.Session               = session;
            details.Session.Timestamp     = DateTime.Now;
            details.Session.ClientAddress = GetCallingClientIPAddress();
            _host.SessionManager.SetCurrentSession(details.Session);
        }
コード例 #4
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Fires the InvokeRejected event.
        /// </summary>
        /// <param name="details">Invocation details</param>
        /// <param name="ex">Exception</param>
        private void Invoke_FireInvokeRejectedEvent(InvocationDetails details, Exception ex)
        {
            details.ExceptionThrown = true;

            var args = new InvokeCanceledEventArgs
            {
                TrackingID = details.TrackingID,
                CancelException = ex
            };

            _host.OnInvokeRejected(args);

            throw args.CancelException.PreserveStackTrace() ?? new InvokeCanceledException();
        }
コード例 #5
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Converts method arguments, if needed.
        /// <remarks>
        /// Conversion is needed when Types configured for custom serialization or arguments are delegates.
        /// </remarks>
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void Invoke_ConvertMethodArguments(InvocationDetails details)
        {
            details.DelegateParamIndexes = new Dictionary<int, DelegateInterceptor>();
            for (int i = 0; i < details.ParamTypes.Length; i++)
            {
                var delegateParamInterceptor = details.Args[i] as DelegateInterceptor;
                if (delegateParamInterceptor != null)
                {
                    details.DelegateParamIndexes.Add(i, delegateParamInterceptor);
                    continue;
                }

                var container = details.Args[i] as CustomSerializationContainer;
                if (container != null)
                {
                    var serializationHandler = _host.SerializationHandling[container.HandledType];
                    if (serializationHandler == null)
                    {
                        var ex = new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_SerializationHandlerNotFound, container.HandledType.FullName));
                        _host.OnInvokeCanceled(new InvokeCanceledEventArgs() { TrackingID = details.TrackingID, CancelException = ex });
                        throw ex;
                    }

                    details.Args[i] = serializationHandler.Deserialize(container.DataType, container.Data);
                }
            }
        }
コード例 #6
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
 /// <summary>
 /// Sets the remote subscription counter.
 /// </summary>
 /// <param name="details">The details.</param>
 private void Invoke_SetRemoteSubscriptionCounter(InvocationDetails details)
 {
     if (details.CallContextData.Store != null && ServerSession.CurrentSession != null)
     {
         details.CallContextData.Store["subscriptions"] = ServerSession.CurrentSession.RemoteSubscriptionCounter;
     }
 }
コード例 #7
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Adds a handler to an event of a server component.
        /// </summary>
        /// <param name="interfaceName">Name of the server component interface</param>
        /// <param name="correlation">Correlation information</param>
        /// <param name="uniqueName">Unique name of the server component instance (May left empty, if component isn´t registered with a unique name)</param>
        /// <param name="callContext">Call context data</param>
        public void AddEventHandler(string interfaceName, DelegateCorrelationInfo correlation, string uniqueName, LogicalCallContextData callContext)
        {
            if (string.IsNullOrEmpty(interfaceName))
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");

            if (string.IsNullOrEmpty(uniqueName))
                uniqueName = interfaceName;

            if (!_host.ComponentRegistry.ContainsKey(uniqueName))
                throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_CannotFindComponentForInterface, interfaceName));

            var details = new InvocationDetails()
            {
                InterfaceName = interfaceName,
                Registration = _host.ComponentRegistry[uniqueName],
                CallContextData = callContext
            };

            Invoke_LoadCallContextData(details);
            Invoke_SetSession(details);
            Invoke_ResolveComponentInstance(details);

            var correlationSet = new List<DelegateCorrelationInfo>
            {
                correlation
            };

            CreateClientServerWires(details.Type, details.Registration.EventStub, correlationSet, details.Registration.EventWirings);
        }
コード例 #8
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
 /// <summary>
 /// Processes AfterInvoke event subscriptions (if there any).
 /// </summary>
 /// <param name="details">Invocation details</param>
 private void ProcessAfterInvoke(InvocationDetails details)
 {
     if (_host.HasAfterInvokeSubscriptions())
     {
         AfterInvokeEventArgs afterInvokeArgs = new AfterInvokeEventArgs()
         {
             TrackingID = details.TrackingID,
             InterfaceName = details.InterfaceName,
             DelegateCorrelationSet = details.DelegateCorrelationSet,
             MethodName = details.MethodName,
             Arguments = details.Args,
             ReturnValue = details.ReturnValue
         };
         _host.OnAfterInvoke(afterInvokeArgs);
     }
 }
コード例 #9
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Sets the session for the current worker thread.
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void Invoke_SetSession(InvocationDetails details)
        {
            // validate session
            var sessionID = details.CallContextData.Store.ContainsKey("sessionid") ? (Guid)details.CallContextData.Store["sessionid"] : Guid.Empty;
            if (!_host.SessionManager.ExistSession(sessionID))
            {
                throw new InvalidSessionException(string.Format(LanguageResource.InvalidSessionException_SessionIDInvalid, sessionID.ToString()));
            }

            // set current session
            details.Session = _host.SessionManager.GetSessionBySessionID(sessionID);
            details.Session.Timestamp = DateTime.Now;
            ServerSession.CurrentSession = details.Session;
            PutClientAddressToCurrentSession();
        }
コード例 #10
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
 /// <summary>
 /// Obtains metadata of the invoked method via reflection.
 /// </summary>
 /// <param name="details">Invocation details</param>
 private void Invoke_ObtainMethodMetadata(InvocationDetails details)
 {
     details.MethodInfo = details.Type.GetMethod(details.MethodName, details.GenericArguments, details.ParamTypes);
     if (details.MethodInfo == null)
     {
         var methodSignature = MessageHelpers.GetMethodSignature(details.Type, details.MethodName, details.ParamTypes);
         var exceptionMessage = String.Format(LanguageResource.MissingMethodException_MethodNotFound, methodSignature);
         throw new MissingMethodException(exceptionMessage);
     }
 }
コード例 #11
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Processes remote method invocation.
        /// </summary>
        /// <param name="trackingID">Key for call tracking</param>
        /// <param name="interfaceName">Name of the component interface</param>
        /// <param name="delegateCorrelationSet">Correlation set for dynamic event and delegate wiring</param>
        /// <param name="methodName">Name of the invoked method</param>
        /// <param name="genericArguments">Generic arguments of the invoked method</param>
        /// <param name="paramTypes">Parameter types</param>
        /// <param name="callContext">Call context data</param>
        /// <param name="args">Parameter values</param>
        /// <returns>Return value</returns>
        public object Invoke(Guid trackingID, string interfaceName, List<DelegateCorrelationInfo> delegateCorrelationSet, string methodName, Type[] genericArguments, Type[] paramTypes, LogicalCallContextData callContext, params object[] args)
        {
            if (string.IsNullOrEmpty(interfaceName))
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");

            if (string.IsNullOrEmpty(methodName))
                throw new ArgumentException(LanguageResource.ArgumentException_MethodNameMissing, "methodName");

            // Reset session variable (May point to wrong session, if threadpool thread is reused)
            ServerSession.CurrentSession = null;

            var details = new InvocationDetails()
            {
                TrackingID = trackingID,
                InterfaceName = interfaceName,
                DelegateCorrelationSet = delegateCorrelationSet,
                MethodName = methodName,
                GenericArguments = genericArguments,
                ParamTypes = paramTypes,
                Args = args,
                CallContextData = callContext
            };

            var beforeInvokeOccured = false;

            try
            {
                //Invoke_LoadCallContextData(details);
                Invoke_SetSession(details);
                Invoke_SetTransaction(details);

                beforeInvokeOccured = true;
                ProcessBeforeInvoke(details);

                Invoke_CheckInterfaceName(details);
                Invoke_ConvertMethodArguments(details);
                Invoke_ResolveComponentInstance(details);
                Invoke_ObtainMethodMetadata(details);
                Invoke_InterceptDelegateParams(details);

                details.ReturnValue = details.MethodInfo.Invoke(details.Instance, details.Args, details.MethodInfo.IsOneWay());

                Invoke_ApplyCustomSerializationOnReturnValue(details);
            }
            catch (Exception ex)
            {
                if (beforeInvokeOccured)
                    Invoke_FireInvokeCanceledEvent(details, ex);
                else
                    Invoke_FireInvokeRejectedEvent(details, ex);
            }
            finally
            {
                Invoke_CompleteTransactionScope(details);
                Invoke_CleanUp(details);
            }

            ProcessAfterInvoke(details);

            return details.ReturnValue;
        }
コード例 #12
0
ファイル: InvocationDetailsTests.cs プロジェクト: yallie/zyan
        public void InvocationDetailsUnknownMethod()
        {
            var baz = new InvocationDetails
            {
                Type = typeof(Service),
                InterfaceType = typeof(IService),
                MethodName = "Baz",
                ParamTypes = new Type[0],
                GenericArguments = new Type[0]
            };

            Assert.IsFalse(baz.FindMethodInfo());
            Assert.IsNull(baz.MethodInfo);
        }
コード例 #13
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Adds remote handlers to events of a server component.
        /// </summary>
        /// <param name="interfaceName">Name of the server component interface.</param>
        /// <param name="correlationSet">Correlation information.</param>
        /// <param name="uniqueName">Unique name of the server component instance (may be left empty, if component isn't registered with a unique name).</param>
        public void AddEventHandlers(string interfaceName, IEnumerable<DelegateCorrelationInfo> correlationSet, string uniqueName)
        {
            if (string.IsNullOrEmpty(interfaceName))
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");

            if (string.IsNullOrEmpty(uniqueName))
                uniqueName = interfaceName;

            if (!_host.ComponentCatalog.IsRegistered(uniqueName))
                throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_CannotFindComponentForInterface, interfaceName));

            var details = new InvocationDetails()
            {
                InterfaceName = interfaceName,
                Registration = _host.ComponentCatalog.GetRegistration(uniqueName)
            };

            Invoke_LoadCallContextData(details);
            Invoke_SetSession(details);
            Invoke_ResolveComponentInstance(details);

            CreateClientServerWires(details.Type, details.Registration.EventStub, correlationSet, details.Registration.EventWirings);
            Invoke_CleanUp(details);
        }
コード例 #14
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Intercepts delegate parameters.
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void Invoke_InterceptDelegateParams(InvocationDetails details)
        {
            var serverMethodParamDefs = details.MethodInfo.GetParameters();
            foreach (int index in details.DelegateParamIndexes.Keys)
            {
                var delegateParamInterceptor = details.DelegateParamIndexes[index];
                var serverMethodParamDef = serverMethodParamDefs[index];

                var dynamicWire = DynamicWireFactory.CreateDynamicWire(details.Type, serverMethodParamDef.ParameterType);
                dynamicWire.Interceptor = delegateParamInterceptor;
                details.Args[index] = dynamicWire.InDelegate;
            }
        }
コード例 #15
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Called from client to send a heartbeat signal.
        /// </summary>
        /// <param name="sessionID">Client´s session key</param>
        /// <param name="callContext">Call context data</param>
        public void ReceiveClientHeartbeat(Guid sessionID, LogicalCallContextData callContext)
        {
            // validate server session
            var details = new InvocationDetails();
            details.CallContextData = callContext;
            //Invoke_LoadCallContextData(details);
            Invoke_SetSession(details);

            // fire the heartbeat event
            OnClientHeartbeatReceived(new ClientHeartbeatEventArgs(DateTime.Now, sessionID));
        }
コード例 #16
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
 /// <summary>
 /// Loads data from the logical call context.
 /// </summary>
 /// <param name="details">Invocation details</param>
 private void Invoke_LoadCallContextData(InvocationDetails details)
 {
     // check for logical context data
     details.CallContextData = CallContext.GetData("__ZyanContextData_" + _host.Name) as LogicalCallContextData;
     if (details.CallContextData == null)
     {
         throw new SecurityException(LanguageResource.SecurityException_ContextInfoMissing);
     }
 }
コード例 #17
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Applies custom serialization on return value (if configured).
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void Invoke_ApplyCustomSerializationOnReturnValue(InvocationDetails details)
        {
            if (details.ReturnValue != null)
            {
                Type returnValueType = details.ReturnValue.GetType();

                Type handledType;
                ISerializationHandler handler;
                _host.SerializationHandling.FindMatchingSerializationHandler(returnValueType, out handledType, out handler);

                if (handler != null)
                {
                    byte[] raw = handler.Serialize(details.ReturnValue);
                    details.ReturnValue = new CustomSerializationContainer(handledType, returnValueType, raw);
                }
            }
        }
コード例 #18
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Resolves the component instance to be invoked.
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void Invoke_ResolveComponentInstance(InvocationDetails details)
        {
            // Skip resolving registration, if already done
            if (details.Registration == null)
                details.Registration = _host.ComponentRegistry[details.InterfaceName];

            // get component instance
            details.Instance = _host.GetComponentInstance(details.Registration);
            details.Type = details.Instance.GetType();
        }
コード例 #19
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
 /// <summary>
 /// Checks if the provided interface name belongs to a registered component.
 /// </summary>
 /// <param name="details">Invocation details</param>
 private void Invoke_CheckInterfaceName(InvocationDetails details)
 {
     // look up the component registration info
     if (!_host.ComponentRegistry.ContainsKey(details.InterfaceName))
         throw new KeyNotFoundException(string.Format(LanguageResource.KeyNotFoundException_CannotFindComponentForInterface, details.InterfaceName));
 }
コード例 #20
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
 /// <summary>
 /// Sets a transaction for the current worker thread, if provided.
 /// </summary>
 /// <param name="details">Invocation details</param>
 private void Invoke_SetTransaction(InvocationDetails details)
 {
     // transfer implicit transaction
     var transaction = details.CallContextData.Store.ContainsKey("transaction") ? (Transaction)details.CallContextData.Store["transaction"] : null;
     if (transaction != null)
         details.Scope = new TransactionScope(transaction);
 }
コード例 #21
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
 /// <summary>
 /// Cleans up event handlers and component instance (if needed).
 /// </summary>
 /// <param name="details">Invocation details</param>
 private void Invoke_CleanUp(InvocationDetails details)
 {
     if (details.Instance != null && details.Registration != null &&
         details.Registration.ActivationType == ActivationType.SingleCall)
     {
         _host.ComponentCatalog.CleanUpComponentInstance(details.Registration, details.Instance);
     }
 }
コード例 #22
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Processes BeforeInvoke event subscriptions (if there any).
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void ProcessBeforeInvoke(InvocationDetails details)
        {
            if (_host.HasBeforeInvokeSubscriptions())
            {
                BeforeInvokeEventArgs cancelArgs = new BeforeInvokeEventArgs()
                {
                    TrackingID = details.TrackingID,
                    InterfaceName = details.InterfaceName,
                    DelegateCorrelationSet = details.DelegateCorrelationSet,
                    MethodName = details.MethodName,
                    Arguments = details.Args,
                    Cancel = false
                };
                _host.OnBeforeInvoke(cancelArgs);

                if (cancelArgs.Cancel)
                {
                    if (cancelArgs.CancelException == null)
                        cancelArgs.CancelException = new InvokeCanceledException();

                    throw cancelArgs.CancelException.PreserveStackTrace();
                }

                details.InterfaceName = cancelArgs.InterfaceName;
                details.DelegateCorrelationSet = cancelArgs.DelegateCorrelationSet;
                details.MethodName = cancelArgs.MethodName;
                details.Args = cancelArgs.Arguments;
            }
        }
コード例 #23
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Completes the transaction scope, if no exception occured.
        /// </summary>
        /// <param name="details">Invocation details</param>
        private void Invoke_CompleteTransactionScope(InvocationDetails details)
        {
            if (details.Scope != null)
            {
                if (!details.ExceptionThrown)
                    details.Scope.Complete();

                details.Scope.Dispose();
            }
        }
コード例 #24
0
        /// <summary>
        /// Processes remote method invocation.
        /// </summary>
        /// <param name="trackingID">Key for call tracking</param>
        /// <param name="interfaceName">Name of the component interface</param>
        /// <param name="delegateCorrelationSet">Correlation set for dynamic event and delegate wiring</param>
        /// <param name="methodName">Name of the invoked method</param>
        /// <param name="genericArguments">Generic arguments of the invoked method</param>
        /// <param name="paramTypes">Parameter types</param>
        /// <param name="args">Parameter values</param>
        /// <returns>Return value</returns>
        public object Invoke(Guid trackingID, string interfaceName, List <DelegateCorrelationInfo> delegateCorrelationSet, string methodName, Type[] genericArguments, Type[] paramTypes, params object[] args)
        {
            if (string.IsNullOrEmpty(interfaceName))
            {
                throw new ArgumentException(LanguageResource.ArgumentException_InterfaceNameMissing, "interfaceName");
            }

            if (string.IsNullOrEmpty(methodName))
            {
                throw new ArgumentException(LanguageResource.ArgumentException_MethodNameMissing, "methodName");
            }

            // Reset session variable (May point to wrong session, if threadpool thread is reused)
            _host.SessionManager.SetCurrentSession(null);

            var details = new InvocationDetails()
            {
                TrackingID             = trackingID,
                InterfaceName          = interfaceName,
                DelegateCorrelationSet = delegateCorrelationSet,
                MethodName             = methodName,
                GenericArguments       = genericArguments,
                ParamTypes             = paramTypes,
                Args = args
            };

            var beforeInvokeOccured = false;

            try
            {
                Invoke_LoadCallContextData(details);
                Invoke_SetSession(details);
                Invoke_SetTransaction(details);

                beforeInvokeOccured = true;
                ProcessBeforeInvoke(details);

                Invoke_CheckInterfaceName(details);
                Invoke_ConvertMethodArguments(details);
                Invoke_ResolveComponentInstance(details);
                Invoke_ObtainMethodMetadata(details);
                Invoke_InterceptDelegateParams(details);

                details.ReturnValue = details.MethodInfo.Invoke(details.Instance, details.Args, details.MethodInfo.IsOneWay());

                Invoke_ApplyCustomSerializationOnReturnValue(details);
            }
            catch (Exception ex)
            {
                if (beforeInvokeOccured)
                {
                    Invoke_FireInvokeCanceledEvent(details, ex);
                }
                else
                {
                    Invoke_FireInvokeRejectedEvent(details, ex);
                }
            }
            finally
            {
                Invoke_CompleteTransactionScope(details);
                Invoke_SetRemoteSubscriptionCounter(details);
                Invoke_CleanUp(details);
            }

            ProcessAfterInvoke(details);

            return(details.ReturnValue);
        }
コード例 #25
0
ファイル: ZyanDispatcher.cs プロジェクト: yallie/zyan
        /// <summary>
        /// Fires the InvokeRejected event.
        /// </summary>
        /// <param name="details">Invocation details</param>
        /// <param name="ex">Exception</param>
        private void Invoke_FireInvokeRejectedEvent(InvocationDetails details, Exception ex)
        {
            details.ExceptionThrown = true;

            var args = new InvokeCanceledEventArgs
            {
                TrackingID = details.TrackingID,
                InterfaceName = details.InterfaceName,
                DelegateCorrelationSet = details.DelegateCorrelationSet,
                MethodName = details.MethodName,
                Arguments = details.Args,
                CancelException = ex
            };

            _host.OnInvokeRejected(args);

            throw args.CancelException.PreserveStackTrace() ?? new InvokeCanceledException();
        }