예제 #1
0
        private static void ThrowForUnboundResponseHandler(HttpOperationHandler handler, HttpParameter parameter, string operationName)
        {
            Fx.Assert(handler != null, "The 'handler' parameter should not be null.");
            Fx.Assert(parameter != null, "The 'parameter' parameter should not be null.");
            Fx.Assert(operationName != null, "The 'operationName' parameter should not be null.");

            string exceptionMessage = null;

            if (parameter.ValueConverter.CanConvertFromString)
            {
                exceptionMessage = SR.ResponseHandlerWithNoPossibleBindingForStringConvertableType(
                    HttpOperationHandler.HttpOperationHandlerType.Name,
                    handler.ToString(),
                    operationName,
                    parameter.Name,
                    parameter.Type.Name,
                    handler.GetType().Name);
            }
            else
            {
                exceptionMessage = SR.ResponseHandlerWithNoPossibleBindingForNonStringConvertableType(
                    HttpOperationHandler.HttpOperationHandlerType.Name,
                    handler.ToString(),
                    operationName,
                    parameter.Name,
                    parameter.Type.Name,
                    handler.GetType().Name);
            }

            Fx.Assert(exceptionMessage != null, "The 'exceptionMessage' variable should have been set.");
            throw Fx.Exception.AsError(new InvalidOperationException(exceptionMessage));
        }
        public void OutputParametersReturnsReflectedHttpParameters()
        {
            List <Type> types = new List <Type>();

            TestDataAssert.Execute(
                TestData.RepresentativeValueAndRefTypeTestDataCollection,
                (type, obj) =>
            {
                if (!types.Contains(type))
                {
                    types.Add(type);

                    for (int i = 2; i <= 17; i++)
                    {
                        if (types.Count - i < 0)
                        {
                            break;
                        }

                        Type[] typeArray = types.Skip(types.Count - i).ToArray();
                        HttpOperationHandler genericHandler = GetGenericHandlerForTypes(typeArray);

                        for (int j = 0; j < genericHandler.OutputParameters.Count; j++)
                        {
                            HttpParameter parameter = genericHandler.OutputParameters[j];
                            Assert.AreEqual("output", parameter.Name, "The HttpParameter.Name should have been 'input'.");
                            Assert.AreEqual(typeArray.Last(), parameter.Type, "The HttpParameter.Type should have been the last type from the array.");
                        }
                    }
                }
            });
        }
예제 #3
0
        private static void ThrowForUnboundParameter(HttpOperationHandler handler, HttpParameter parameter, HandlerType handlerType, string operationName)
        {
            Fx.Assert(handler != null, "The 'handler' parameter should not be null.");
            Fx.Assert(parameter != null, "The 'parameter' parameter should not be null.");
            Fx.Assert(operationName != null, "The 'operationName' parameter should not be null.");

            if (handler == responseMessageSinkHandler)
            {
                throw Fx.Exception.AsError(
                          new InvalidOperationException(
                              SR.ResponseSinkHandlerWithNoHttpResponseMessageSource(
                                  HttpOperationHandler.HttpOperationHandlerType.Name,
                                  HttpTypeHelper.HttpResponseMessageType.Name,
                                  operationName)));
            }

            switch (handlerType)
            {
            case HandlerType.Request:
                ThrowForUnboundRequestHandler(handler, parameter, operationName);
                break;

            case HandlerType.ServiceOperation:
                ThrowForUnboundServiceOperation(parameter, operationName);
                break;

            case HandlerType.Response:
                ThrowForUnboundResponseHandler(handler, parameter, operationName);
                break;

            default:
                Fx.Assert("The handlerType should have been one of the above cases.");
                break;
            }
        }
        public void Constructor()
        {
            HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
            SHttpOperationDescription operation = new SHttpOperationDescription()
            {
                ReturnValue = HttpParameter.ResponseMessage
            };
            OperationHandlerPipelineInfo  pipelineInfo     = new OperationHandlerPipelineInfo(handlers, handlers, operation);
            MOperationHandlerPipelineInfo molePipelineInfo = new MOperationHandlerPipelineInfo(pipelineInfo);
            HttpRequestMessage            requestAtCall    = null;

            object[] valuesAtCall = null;

            molePipelineInfo.GetEmptyPipelineValuesArray = () => new object[0];
            molePipelineInfo.SetHttpRequestMessageHttpRequestMessageObjectArray = (req, values) =>
            {
                requestAtCall = req;
                valuesAtCall  = values;
            };
            HttpRequestMessage request = new HttpRequestMessage();

            OperationHandlerPipelineContext context = new OperationHandlerPipelineContext(pipelineInfo, request);

            Assert.IsNotNull(requestAtCall, "HttpRequestMessage was not set in pipeline info.");
            Assert.IsNotNull(valuesAtCall, "Values were not set in pipeline info.");
            HttpAssert.AreEqual(request, requestAtCall);
        }
        public void GetHttpResponseMessageCallsPipelineInfo()
        {
            HttpRequestMessage  request  = new HttpRequestMessage();
            HttpResponseMessage response = new HttpResponseMessage()
            {
                RequestMessage = request
            };

            HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
            SHttpOperationDescription operation = new SHttpOperationDescription()
            {
                ReturnValue = HttpParameter.ResponseMessage
            };
            OperationHandlerPipelineInfo  pipelineInfo     = new OperationHandlerPipelineInfo(handlers, handlers, operation);
            MOperationHandlerPipelineInfo molePipelineInfo = new MOperationHandlerPipelineInfo(pipelineInfo);

            molePipelineInfo.GetEmptyPipelineValuesArray = () => new object[0];
            molePipelineInfo.SetHttpRequestMessageHttpRequestMessageObjectArray = (req, values) => { };
            molePipelineInfo.GetHttpResponseMessageObjectArray = (values) => response;
            OperationHandlerPipelineContext context = new OperationHandlerPipelineContext(pipelineInfo, request);

            HttpResponseMessage responseReturned = context.GetHttpResponseMessage();

            Assert.IsNotNull(responseReturned, "HttpResponseMessage was not returned.");
            HttpAssert.AreEqual(response, responseReturned);
        }
예제 #6
0
            internal OperationHandlerInfo(int offset, HttpOperationHandler handler)
            {
                Fx.Assert(handler != null, "The 'handler' parameter should not be null.");

                this.PipelineValuesOffset = offset;
                this.HandlerInputCount    = handler.InputParameters.Count;
                this.OutputParameterInfo  = new OutputParameterInfo[handler.OutputParameters.Count];
            }
예제 #7
0
 public void Constructor()
 {
     HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
     SHttpOperationDescription operation = new SHttpOperationDescription()
     {
         ReturnValue = HttpParameter.ResponseMessage
     };
     OperationHandlerPipeline pipeline = new OperationHandlerPipeline(handlers, handlers, operation);
 }
예제 #8
0
        public void ConstructorThrowsWithNullResponseHandlers()
        {
            HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
            SHttpOperationDescription operation = new SHttpOperationDescription()
            {
                ReturnValue = HttpParameter.ResponseMessage
            };

            ExceptionAssert.ThrowsArgumentNull("responseHttpOperationHandlers", () => new OperationHandlerPipeline(handlers, null, operation));
        }
예제 #9
0
        public void ExecuteRequestPipeline()
        {
            HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
            SHttpOperationDescription operation = new SHttpOperationDescription()
            {
                ReturnValue = HttpParameter.ResponseMessage
            };
            OperationHandlerPipeline pipeline = new OperationHandlerPipeline(handlers, handlers, operation);

            HttpRequestMessage request = new HttpRequestMessage();
            OperationHandlerPipelineContext context = pipeline.ExecuteRequestPipeline(request, new object[0]);

            Assert.IsNotNull(context, "Execute returned null context.");
        }
예제 #10
0
        internal HttpResponseMessage ExecuteResponsePipeline(OperationHandlerPipelineContext pipelineContext, object[] parameters, object result)
        {
            Fx.Assert(pipelineContext != null, "The 'pipelineContext' parameter should not be null.");
            Fx.Assert(parameters != null, "The 'parameters' parameter should not be null.");

            object[] pipelineParameters = new object[parameters.Length + 1];
            pipelineParameters[0] = result;
            Array.Copy(parameters, 0, pipelineParameters, 1, parameters.Length);
            pipelineContext.SetOutputValuesAndAdvance(pipelineParameters);

            for (int handlerIndex = 0; handlerIndex < this.responseHandlersCount; handlerIndex++)
            {
                HttpOperationHandler handler      = this.responseHandlers[handlerIndex];
                object[]             inputValues  = pipelineContext.GetInputValues();
                object[]             outputValues = handler.Handle(inputValues);
                pipelineContext.SetOutputValuesAndAdvance(outputValues);
            }

            return(pipelineContext.GetHttpResponseMessage());
        }
예제 #11
0
        public void InputParametersReturnsReflectedHttpParameters()
        {
            List <Type> types = new List <Type>();

            TestDataAssert.Execute(
                TestData.RepresentativeValueAndRefTypeTestDataCollection,
                (type, obj) =>
            {
                if (!types.Contains(type))
                {
                    types.Add(type);

                    for (int i = 2; i <= 17; i++)
                    {
                        if (types.Count - i < 0)
                        {
                            break;
                        }

                        Type[] typeArray = types.Skip(types.Count - i).ToArray();
                        HttpOperationHandler genericHandler = GetGenericHandlerForTypes(typeArray);

                        for (int j = 0; j < genericHandler.InputParameters.Count; j++)
                        {
                            HttpParameter parameter = genericHandler.InputParameters[j];
                            Assert.AreEqual(typeArray[j], parameter.Type, "The HttpParameter.Type should have been the same type as from the array.");
                            if (i == 2)
                            {
                                Assert.AreEqual("input", parameter.Name, "The HttpParameter.Name should have been 'input'.");
                            }
                            else
                            {
                                string expectedName = "input" + (j + 1).ToString();
                                Assert.AreEqual(expectedName, parameter.Name, string.Format("The HttpParameter.Name should have been '{0}'.", expectedName));
                            }
                        }
                    }
                }
            });
        }
예제 #12
0
        public void ExecuteResponsePipeline()
        {
            HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
            SHttpOperationDescription operation = new SHttpOperationDescription()
            {
                ReturnValue = HttpParameter.ResponseMessage
            };
            OperationHandlerPipeline pipeline = new OperationHandlerPipeline(handlers, handlers, operation);

            HttpRequestMessage  request  = new HttpRequestMessage();
            HttpResponseMessage response = new HttpResponseMessage()
            {
                RequestMessage = request
            };

            OperationHandlerPipelineContext context = pipeline.ExecuteRequestPipeline(request, new object[0]);

            //// TODO: what is the convention for returning an HttpResponse from the operation?
            HttpResponseMessage actualResponse = pipeline.ExecuteResponsePipeline(context, new object[0], response);

            Assert.IsNotNull(actualResponse, "Execute returned null response.");
        }
예제 #13
0
        internal OperationHandlerPipelineContext ExecuteRequestPipeline(HttpRequestMessage request, object[] parameters)
        {
            Fx.Assert(request != null, "The 'request' parameter should not be null.");
            Fx.Assert(parameters != null, "The 'parameters' parameter should not be null.");

            OperationHandlerPipelineContext pipelineContext = new OperationHandlerPipelineContext(this.pipelineContextInfo, request);

            for (int handlerIndex = 0; handlerIndex < this.requestHandlersCount; handlerIndex++)
            {
                HttpOperationHandler handler      = this.requestHandlers[handlerIndex];
                object[]             inputValues  = pipelineContext.GetInputValues();
                object[]             outputValues = handler.Handle(inputValues);
                pipelineContext.SetOutputValuesAndAdvance(outputValues);
            }

            object[] pipelineParameters = pipelineContext.GetInputValues();

            Fx.Assert(pipelineParameters.Length == parameters.Length, "The two parameter object arrays should have the same length.");
            Array.Copy(pipelineParameters, parameters, parameters.Length);

            return(pipelineContext);
        }
        public void SetOutputValuesAndAdvanceCallsPipelineInfo()
        {
            HttpRequestMessage  request  = new HttpRequestMessage();
            HttpResponseMessage response = new HttpResponseMessage()
            {
                RequestMessage = request
            };

            HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
            SHttpOperationDescription operation = new SHttpOperationDescription()
            {
                ReturnValue = HttpParameter.ResponseMessage
            };
            OperationHandlerPipelineInfo pipelineInfo = new OperationHandlerPipelineInfo(handlers, handlers, operation);

            int indexAtCall = -1;

            object[] valuesAtCall         = null;
            object[] pipelineValuesAtCall = null;

            MOperationHandlerPipelineInfo molePipelineInfo = new MOperationHandlerPipelineInfo(pipelineInfo);

            molePipelineInfo.GetEmptyPipelineValuesArray = () => new object[0];
            molePipelineInfo.SetHttpRequestMessageHttpRequestMessageObjectArray    = (req, values) => { };
            molePipelineInfo.SetOutputValuesFromHandlerInt32ObjectArrayObjectArray = (index, values, pipelineValues) =>
            {
                indexAtCall          = index;
                valuesAtCall         = values;
                pipelineValuesAtCall = pipelineValues;
            };

            OperationHandlerPipelineContext context = new OperationHandlerPipelineContext(pipelineInfo, request);

            context.SetOutputValuesAndAdvance(new object[0]);

            Assert.AreEqual(1, indexAtCall, "Handler index was not set.");
            Assert.IsNotNull(valuesAtCall, "Values were not set.");
            Assert.IsNotNull(pipelineValuesAtCall, "Pipeline values were not set.");
        }
예제 #15
0
        private static OperationHandlerInfo[] GenerateHandlerInfo(List <HttpOperationHandler> handlers, List <HttpParameterBinding> bindings, string operationName, out int pipelineValuesArraySize)
        {
            Fx.Assert(handlers != null, "The 'handlers' parameter should not be null.");
            Fx.Assert(bindings != null, "The 'bindings' parameter should not be null.");
            Fx.Assert(operationName != null, "The 'bindings' parameter should not be null.");

            pipelineValuesArraySize = 0;
            OperationHandlerInfo[] handlerInfo = new OperationHandlerInfo[handlers.Count];

            // First, construct the OperationHandlerInfo[] to determine each handlers's offset
            //  in the pipelineValuesArray.
            for (int handlerIndex = 0; handlerIndex < handlers.Count; handlerIndex++)
            {
                HttpOperationHandler handler = handlers[handlerIndex];
                OperationHandlerInfo info    = new OperationHandlerInfo(pipelineValuesArraySize, handler);
                handlerInfo[handlerIndex] = info;
                pipelineValuesArraySize  += info.HandlerInputCount;

                handlers[handlerIndex].OperationName = operationName;
            }

            // Second, map the HttpParameterBindings into the OutputParameterInfo array indices.
            for (int handlerIndex = 0; handlerIndex < handlers.Count; handlerIndex++)
            {
                HttpOperationHandler handler = handlers[handlerIndex];

                for (int paramIndex = 0; paramIndex < handler.OutputParameters.Count; paramIndex++)
                {
                    OperationHandlerInfo info = handlerInfo[handlerIndex];
                    info.OutputParameterInfo[paramIndex] = new OutputParameterInfo(
                        bindings.Where(binding => binding.OutputHandlerIndex == handlerIndex &&
                                       binding.OutputParameterIndex == paramIndex)
                        .Select(binding => handlerInfo[binding.InputHandlerIndex].PipelineValuesOffset +
                                binding.InputParameterIndex));
                }
            }

            return(handlerInfo);
        }
        public void GetInputValuesCallsPipelineInfo()
        {
            HttpOperationHandler[]    handlers  = new HttpOperationHandler[0];
            SHttpOperationDescription operation = new SHttpOperationDescription()
            {
                ReturnValue = HttpParameter.ResponseMessage
            };
            OperationHandlerPipelineInfo  pipelineInfo     = new OperationHandlerPipelineInfo(handlers, handlers, operation);
            MOperationHandlerPipelineInfo molePipelineInfo = new MOperationHandlerPipelineInfo(pipelineInfo);

            molePipelineInfo.GetEmptyPipelineValuesArray = () => new object[0];
            molePipelineInfo.SetHttpRequestMessageHttpRequestMessageObjectArray = (req, values) => { };

            bool calledForValues    = false;
            int  handlerIndexAtCall = -1;

            object[] valuesAtCall = null;
            molePipelineInfo.GetInputValuesForHandlerInt32ObjectArray = (index, values) =>
            {
                calledForValues    = true;
                handlerIndexAtCall = index;
                valuesAtCall       = values;
                return(new object[0]);
            };

            HttpRequestMessage request = new HttpRequestMessage();
            OperationHandlerPipelineContext context = new OperationHandlerPipelineContext(pipelineInfo, request);

            object[] returnedValues = context.GetInputValues();

            Assert.IsTrue(calledForValues, "PipelineInfo was not called for its values.");
            Assert.AreEqual(1, handlerIndexAtCall, "Handler index should have been 0.");
            Assert.IsNotNull(valuesAtCall, "Values at call should have not been null.");
            Assert.IsNotNull(returnedValues, "Returned values were null.");
            Assert.AreEqual(0, returnedValues.Length, "Returned values were incorrect length.");
        }
예제 #17
0
 public void ConstructorThrowsWithNullOperation()
 {
     HttpOperationHandler[] handlers = new HttpOperationHandler[0];
     ExceptionAssert.ThrowsArgumentNull("operation", () => new OperationHandlerPipeline(handlers, handlers, null));
 }
예제 #18
0
        private static List <HttpParameterBinding> BindHandlers(List <HttpOperationHandler> handlers, string operationName, int serviceOperationIndex)
        {
            Fx.Assert(handlers != null, "The 'handlers' parameter should not be null.");
            Fx.Assert(operationName != null, "The 'operationName' parameter should not be null.");

            List <HttpParameterBinding> pipelineBindings = new List <HttpParameterBinding>();

            for (int inHandlerIndex = handlers.Count - 1; inHandlerIndex >= 1; inHandlerIndex--)
            {
                HttpOperationHandler inHandler     = handlers[inHandlerIndex];
                HandlerType          inHandlerType = GetHandlerType(inHandlerIndex, serviceOperationIndex);

                for (int inParamIndex = 0; inParamIndex < inHandler.InputParameters.Count; inParamIndex++)
                {
                    HttpParameter inParam = inHandler.InputParameters[inParamIndex];
                    List <HttpParameterBinding> bindings          = new List <HttpParameterBinding>();
                    List <HttpParameterBinding> tentativeBindings = new List <HttpParameterBinding>();

                    for (int outHandlerIndex = inHandlerIndex - 1; outHandlerIndex >= 0; outHandlerIndex--)
                    {
                        HttpOperationHandler outHandler     = handlers[outHandlerIndex];
                        HandlerType          outHandlerType = GetHandlerType(outHandlerIndex, serviceOperationIndex);

                        for (int outParamIndex = 0; outParamIndex < outHandler.OutputParameters.Count; outParamIndex++)
                        {
                            HttpParameter outParam = outHandler.OutputParameters[outParamIndex];

                            if (inParam.IsAssignableFromParameter(outParam.Type))
                            {
                                HttpParameterBinding binding = new HttpParameterBinding();
                                binding.InputHandler         = inHandler;
                                binding.InputHandlerIndex    = inHandlerIndex;
                                binding.InputParameter       = inParam;
                                binding.InputParameterIndex  = inParamIndex;
                                binding.InputHandlerType     = inHandlerType;
                                binding.OutputHandler        = outHandler;
                                binding.OutputHandlerIndex   = outHandlerIndex;
                                binding.OutputParameter      = outParam;
                                binding.OutputParameterIndex = outParamIndex;
                                binding.OutputHandlerType    = outHandlerType;

                                // If their names match or the input is either HttpRequesMessage,
                                //  HttpResponseMessage, or HttpContent, then go ahead and bind
                                if (string.Equals(outParam.Name, inParam.Name, StringComparison.OrdinalIgnoreCase) ||
                                    HttpTypeHelper.IsHttp(inParam.Type))
                                {
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    // Otherwise we will tentatively bind if this is
                                    //  not a string conversion assignment
                                    if (outParam.Type != TypeHelper.StringType ||
                                        !inParam.ValueConverter.CanConvertFromString)
                                    {
                                        tentativeBindings.Add(binding);
                                    }
                                }
                            }
                        }
                    }

                    if (bindings.Count > 0)
                    {
                        pipelineBindings.AddRange(bindings);
                    }
                    else if (tentativeBindings.Count == 1)
                    {
                        pipelineBindings.AddRange(tentativeBindings);
                    }
                    else if (tentativeBindings.Count > 1)
                    {
                        ThrowForMulitpleTypeOnlyBindings(tentativeBindings, operationName);
                    }
                    else
                    {
                        ThrowForUnboundParameter(inHandler, inParam, inHandlerType, operationName);
                    }
                }
            }

            return(pipelineBindings);
        }
예제 #19
0
        private static void ThrowForMulitpleTypeOnlyBindings(List <HttpParameterBinding> tentativeBindings, string operationName)
        {
            Fx.Assert(tentativeBindings != null, "The 'tentativeBindings' parameter should not be null.");
            Fx.Assert(tentativeBindings.Count > 0, "The 'tentativeBindings' list should not be empty.");
            Fx.Assert(operationName != null, "The 'operationName' parameter should not be null.");

            string               exceptionMessage = null;
            HandlerType          inHandlerType    = tentativeBindings[0].InputHandlerType;
            HttpOperationHandler inHandler        = tentativeBindings[0].InputHandler;
            HttpParameter        inParameter      = tentativeBindings[0].InputParameter;

            switch (inHandlerType)
            {
            case HandlerType.Request:
                exceptionMessage = SR.RequestHandlerWithMultipleTypeOnlyBindings(
                    HttpOperationHandler.HttpOperationHandlerType.Name,
                    inHandler.ToString(),
                    operationName,
                    inParameter.Name,
                    inParameter.Type.Name);
                break;

            case HandlerType.ServiceOperation:
                exceptionMessage = SR.ServiceOperationWithMultipleTypeOnlyBindings(
                    operationName,
                    inParameter.Name,
                    inParameter.Type.Name,
                    HttpOperationHandler.HttpOperationHandlerType.Name);
                break;

            case HandlerType.Response:
                exceptionMessage = SR.ResponseHandlerWithMultipleTypeOnlyBindings(
                    HttpOperationHandler.HttpOperationHandlerType.Name,
                    inHandler.ToString(),
                    operationName,
                    inParameter.Name,
                    inParameter.Type.Name);
                break;

            default:
                Fx.Assert("The handlerType should have been one of the above cases.");
                break;
            }

            StringBuilder stringBuilder = new StringBuilder(exceptionMessage);

            foreach (HttpParameterBinding binding in tentativeBindings)
            {
                string               parameterMessage = null;
                HandlerType          outHandlerType   = binding.OutputHandlerType;
                HttpOperationHandler outHandler       = binding.OutputHandler;
                HttpParameter        outParameter     = binding.OutputParameter;

                switch (outHandlerType)
                {
                case HandlerType.Request:
                    parameterMessage = SR.RequestHandlerTypeOnlyOutputParameter(
                        HttpOperationHandler.HttpOperationHandlerType.Name,
                        outHandler.ToString(),
                        outParameter.Name,
                        outParameter.Type.Name);
                    break;

                case HandlerType.ServiceOperation:
                    parameterMessage = SR.ServiceOperationTypeOnlyOutputParameter(
                        outParameter.Name,
                        outParameter.Type.Name);
                    break;

                case HandlerType.Response:
                    parameterMessage = SR.ResponseHandlerTypeOnlyOutputParameter(
                        HttpOperationHandler.HttpOperationHandlerType.Name,
                        outHandler.ToString(),
                        outParameter.Name,
                        outParameter.Type.Name);
                    break;

                default:
                    Fx.Assert("The handlerType should have been one of the above cases.");
                    break;
                }

                stringBuilder.Append(Environment.NewLine);
                stringBuilder.Append(parameterMessage);
            }

            throw Fx.Exception.AsError(new InvalidOperationException(stringBuilder.ToString()));
        }