Exemplo n.º 1
0
        /// <summary>
        /// Handles request synchronously in the context of the calling thread. Returns NULL for one-way calls
        /// </summary>
        public ResponseMsg HandleRequestFailure(FID reqID, bool oneWay, Exception failure, object bindingSpecCtx)
        {
            if (oneWay)
            {
                return(null);
            }

            var red      = new WrappedExceptionData(failure);
            var response = new ResponseMsg(reqID, red);

            response.__SetBindingSpecificContext(bindingSpecCtx);

            return(response);
        }
Exemplo n.º 2
0
        private ResponseMsg handleRequest(RequestMsg request)
        {
            try
            {
                ServerCallContext.__SetThreadLevelContext(request);
                try
                {
                    var response = doWork(request);

                    var rhdr = ServerCallContext.GetResponseHeadersOrNull();

                    if (rhdr != null && response != null)
                    {
                        response.Headers = rhdr;
                    }

                    return(response);
                }
                finally
                {
                    ServerCallContext.__ResetThreadLevelContext();
                }
            }
            catch (Exception error)
            {
                if (request.OneWay)
                {         //because it is one-way, the caller will never know about it
                    this.WriteLog(LogSrc.Server,
                                  MessageType.Error,
                                  string.Format(StringConsts.GLUE_SERVER_ONE_WAY_CALL_ERROR + error.ToMessageWithType()),
                                  from: "SrvrHndlr.handleRequest(ReqMsg)",
                                  exception: error
                                  );
                    return(null);
                }
                else
                {
                    var red      = new WrappedExceptionData(error);
                    var response = new ResponseMsg(request.RequestID, red);
                    response.__SetBindingSpecificContext(request);
                    return(response);
                }
            }
        }
Exemplo n.º 3
0
        private ResponseMsg doWork(RequestMsg request)
        {
            var contract = request.Contract;                                                       //this throws when contract can't be found
            var server   = getServerImplementer(request.ServerTransport.ServerEndpoint, contract); //throws when no implementor match found

            if (server.AuthenticationSupport)
            {
                interpretAuthenticationHeader(request);
            }


            //Authorizes user to the whole server contract and implementing class
            Security.Permission.AuthorizeAndGuardAction(server.Contract);
            Security.Permission.AuthorizeAndGuardAction(server.Implementation);

            serverImplementer.mapping mapped = server.SpecToMethodInfos(request.Method);


            Security.Permission.AuthorizeAndGuardAction(mapped.miContract);
            Security.Permission.AuthorizeAndGuardAction(mapped.miImplementation);


            Guid?checkedOutID;
            bool lockTaken;
            var  instance = getServerInstance(server, request, out checkedOutID, out lockTaken);       //throws when instance expired or cant be locked

            try
            {
                Guid?instanceID = null;
                bool isCtor     = false;
                bool isDctor    = false;

                if (server.InstanceMode == ServerInstanceMode.Stateful ||
                    server.InstanceMode == ServerInstanceMode.AutoConstructedStateful)
                {
                    instanceID = request.RemoteInstance;
                    isCtor     = Attribute.IsDefined(mapped.miContract, typeof(ConstructorAttribute));
                    isDctor    = Attribute.IsDefined(mapped.miContract, typeof(DestructorAttribute));


                    if (isCtor && isDctor)
                    {
                        throw new ServerMethodInvocationException(StringConsts.GLUE_AMBIGUOUS_CTOR_DCTOR_DEFINITION_ERROR
                                                                  .Args(contract.FullName, request.MethodName));
                    }

                    if (server.InstanceMode != ServerInstanceMode.AutoConstructedStateful &&
                        !instanceID.HasValue &&
                        !isCtor)
                    {
                        throw new ServerMethodInvocationException(StringConsts.GLUE_NO_SERVER_INSTANCE_ERROR
                                                                  .Args(contract.FullName, request.MethodName));
                    }
                }

                //========================================================================================================
                object result;
                try
                {
                    var any = request as RequestAnyMsg;
                    if (any != null)
                    {
                        result = mapped.miContract.Invoke(instance, any.Arguments);       //do actual contract-implementing method work
                    }
                    else
                    {
                        //call functor using typed RequestMsg derivative
                        if (mapped.fBody == null)
                        {
                            throw new ServerMethodInvocationException(StringConsts.GLUE_NO_ARGS_MARSHAL_LAMBDA_ERROR
                                                                      .Args(contract.FullName, request.MethodName));
                        }
                        result = mapped.fBody(instance, request);      //do actual contract-implementing method work via Lambda
                    }
                }
                catch (Exception bodyError)
                {
                    Exception err = bodyError;
                    if (err is TargetInvocationException)        //unwrap the inner error which is wrapped by Invoke()
                    {
                        if (err.InnerException != null)
                        {
                            err = err.InnerException;
                        }
                    }

                    throw new ServerMethodInvocationException(StringConsts.GLUE_SERVER_CONTRACT_METHOD_INVOCATION_ERROR
                                                              .Args(contract.FullName, request.MethodName, err.ToMessageWithType()),
                                                              err);
                }
                //========================================================================================================

                if (server.InstanceMode == ServerInstanceMode.Stateful ||
                    server.InstanceMode == ServerInstanceMode.AutoConstructedStateful)
                {
                    if (isCtor || (server.InstanceMode == ServerInstanceMode.AutoConstructedStateful && !isDctor && !instanceID.HasValue))
                    {
                        instanceID = Guid.NewGuid();
                        App.ObjectStore.CheckIn(instanceID.Value, instance, server.InstanceTimeoutMs);
                    }
                    else
                    if (isDctor)
                    {
                        if (instanceID.HasValue)
                        {
                            App.ObjectStore.Delete(instanceID.Value);
                            instanceID   = null;
                            checkedOutID = null;
                        }
                    }
                }


                if (request.OneWay)
                {
                    return(null);
                }

                var response = new ResponseMsg(request.RequestID, instanceID, result);
                response.__SetBindingSpecificContext(request);
                return(response);
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(instance);
                }
                if (checkedOutID.HasValue)
                {
                    App.ObjectStore.CheckIn(checkedOutID.Value, server.InstanceTimeoutMs);
                }
            }
        }