Example #1
0
        internal void Invoke(ILocatorPrx l)
        {
            if (_locatorPrx == null || !_locatorPrx.Equals(l))
            {
                _locatorPrx = l;
                var requestFrame = new OutgoingRequestFrame(l, _operation, _idempotent, _context, _payload);

                l.InvokeAsync(requestFrame).ContinueWith(
                    task =>
                {
                    try
                    {
                        SetResult(task.Result);
                    }
                    catch (AggregateException ae)
                    {
                        Exception(ae.InnerException);
                    }
                },
                    TaskScheduler.Current);
            }
            else
            {
                Debug.Assert(_exception != null);
                throw _exception;
            }
        }
Example #2
0
        public void Invoke(string operation,
                           bool idempotent,
                           bool oneway,
                           IReadOnlyDictionary <string, string>?context,
                           bool synchronous,
                           OutgoingRequestFrame request)
        {
            try
            {
                Proxy.IceReference.GetProtocol().CheckSupported();

                IsIdempotent = idempotent;
                IsOneway     = oneway;
                context ??= ProxyAndCurrentContext();
                Observer = ObserverHelper.GetInvocationObserver(Proxy, operation, context);

                switch (Proxy.IceReference.GetMode())
                {
                case InvocationMode.BatchOneway:
                case InvocationMode.BatchDatagram:
                {
                    Debug.Assert(false);     // not implemented
                    break;
                }
                }

                RequestFrame = request;
                Invoke(synchronous);
            }
            catch (System.Exception ex)
            {
                Abort(ex);
            }
        }
Example #3
0
        public static IMyClassPrx Run(TestHelper helper)
        {
            Communicator?communicator = helper.Communicator;

            TestHelper.Assert(communicator != null);
            bool        ice1   = helper.Protocol == Protocol.Ice1;
            var         cl     = IMyClassPrx.Parse(helper.GetTestProxy("test", 0), communicator);
            IMyClassPrx oneway = cl.Clone(oneway: true);

            System.IO.TextWriter output = helper.Output;
            output.Write("testing InvokeAsync... ");
            output.Flush();

            {
                var request = OutgoingRequestFrame.WithEmptyArgs(oneway, "opOneway", idempotent: false);
                IncomingResponseFrame response;
                try
                {
                    response = oneway.InvokeAsync(request, oneway: true).Result;
                }
                catch
                {
                    TestHelper.Assert(false);
                }

                request = OutgoingRequestFrame.WithArgs(cl,
                                                        "opString",
                                                        idempotent: false,
                                                        compress: false,
                                                        format: default,
Example #4
0
 public Task <TReturnValue> InvokeAsync(IObjectPrx prx,
                                        TParamList paramList,
                                        IReadOnlyDictionary <string, string>?context,
                                        IProgress <bool>?progress,
                                        CancellationToken cancel) =>
 InvokeAsync(prx, OutgoingRequestFrame.WithParamList(
                 prx, _operationName, _idempotent, _format, context, paramList, _writer), progress, cancel);
Example #5
0
 public async ValueTask<OutgoingResponseFrame> DispatchAsync(
     IncomingRequestFrame incomingRequest,
     Current current)
 {
     ILocatorPrx? locator = null;
     Exception? exception = null;
     while (true)
     {
         // Get the locator to send the request to (this will return the void locator if no locator is found)
         ILocatorPrx newLocator = await GetLocatorAsync().ConfigureAwait(false);
         if (locator != newLocator)
         {
             var outgoingRequest = new OutgoingRequestFrame(
                 newLocator, current.Operation, current.IsIdempotent, current.Context, incomingRequest.Payload);
             try
             {
                 IncomingResponseFrame incomingResponse =
                     await newLocator.InvokeAsync(outgoingRequest).ConfigureAwait(false);
                 return new OutgoingResponseFrame(current.Protocol, current.Encoding, incomingResponse.Payload);
             }
             catch (DispatchException)
             {
                 throw;
             }
             catch (NoEndpointException)
             {
                 throw new ObjectNotExistException(current);
             }
             catch (ObjectAdapterDeactivatedException)
             {
                 throw new ObjectNotExistException(current);
             }
             catch (CommunicatorDestroyedException)
             {
                 throw new ObjectNotExistException(current);
             }
             catch (Exception ex)
             {
                 lock (_mutex)
                 {
                     locator = newLocator;
                     // If the current locator is equal to the one we use to send the request,
                     // clear it and retry, this will trigger the lookup of a new locator.
                     if (_locator == newLocator)
                     {
                         _locator = null;
                     }
                 }
                 exception = ex;
             }
         }
         else
         {
             // We got the same locator after a previous failure, throw the saved exception now.
             Debug.Assert(exception != null);
             throw exception;
         }
     }
 }
Example #6
0
 public OutgoingAsync(IObjectPrx prx, IOutgoingAsyncCompletionCallback completionCallback,
                      OutgoingRequestFrame requestFrame, bool oneway = false) :
     base(prx, completionCallback, requestFrame)
 {
     Encoding    = Proxy.Encoding;
     Synchronous = false;
     IsOneway    = oneway;
 }
Example #7
0
        private protected Task InvokeAsync(IObjectPrx prx, OutgoingRequestFrame request, IProgress <bool>?progress,
                                           CancellationToken cancel)
        {
            bool isOneway = _oneway || prx.IsOneway;

            return(ReadVoidReturnValueAsync(prx.InvokeAsync(request, isOneway, progress, cancel),
                                            prx.Communicator,
                                            isOneway));
Example #8
0
        private protected Task InvokeAsync(IObjectPrx prx, OutgoingRequestFrame request, IProgress <bool>?progress,
                                           CancellationToken cancel)
        {
            var completed = new IObjectPrx.InvokeTaskCompletionCallback(progress, cancel);

            new OutgoingAsync(prx, completed, request, oneway: prx.IsOneway).Invoke(
                request.Operation, request.Context, synchronous: false);

            return(ReadVoidReturnValueAsync(prx, completed.Task));
Example #9
0
 public TReturnValue Invoke(IObjectPrx prx, TParamList paramList, IReadOnlyDictionary <string, string>?context) =>
 Invoke(prx, OutgoingRequestFrame.WithParamList(prx,
                                                _operationName,
                                                _idempotent,
                                                _compress,
                                                _format,
                                                context,
                                                paramList,
                                                _writer));
Example #10
0
        private protected void Invoke(IObjectPrx prx, OutgoingRequestFrame request)
        {
            bool isOneway = _oneway || prx.IsOneway;
            IncomingResponseFrame response = prx.Invoke(request, isOneway);

            if (!isOneway)
            {
                response.ReadVoidReturnValue(prx.Communicator);
            }
        }
Example #11
0
 public void Invoke(string operation,
                    bool idempotent,
                    bool oneway,
                    IReadOnlyDictionary <string, string>?context,
                    bool synchronous,
                    OutgoingRequestFrame request,
                    System.Func <Ice.InputStream, T>?read = null)
 {
     Read = read;
     base.Invoke(operation, idempotent, oneway, context, synchronous, request);
 }
Example #12
0
 protected ProxyOutgoingAsyncBase(IObjectPrx prx,
                                  IOutgoingAsyncCompletionCallback completionCallback,
                                  OutgoingRequestFrame requestFrame) :
     base(prx.Communicator, completionCallback)
 {
     Proxy        = prx;
     IsOneway     = false;
     _cnt         = 0;
     _sent        = false;
     RequestFrame = requestFrame;
 }
Example #13
0
        public static IMyClassPrx Run(TestHelper helper)
        {
            Communicator?communicator = helper.Communicator;

            TestHelper.Assert(communicator != null);
            bool        ice1   = helper.Protocol == Protocol.Ice1;
            var         cl     = IMyClassPrx.Parse(helper.GetTestProxy("test", 0), communicator);
            IMyClassPrx oneway = cl.Clone(oneway: true);

            System.IO.TextWriter output = helper.Output;
            output.Write("testing Invoke... ");
            output.Flush();

            {
                var request = OutgoingRequestFrame.WithEmptyArgs(oneway, "opOneway", idempotent: false);

                // Whether the proxy is oneway or not does not matter for Invoke's oneway parameter.

                IncomingResponseFrame response = cl.Invoke(request, oneway: true);
                if (ice1)
                {
                    TestHelper.Assert(response.ResultType == ResultType.Success);
                }

                request  = OutgoingRequestFrame.WithEmptyArgs(oneway, "opOneway", idempotent: false);
                response = cl.Invoke(request, oneway: false);
                if (ice1)
                {
                    TestHelper.Assert(response.ResultType == ResultType.Failure);
                }

                request  = OutgoingRequestFrame.WithEmptyArgs(oneway, "opOneway", idempotent: false);
                response = oneway.Invoke(request, oneway: true);
                if (ice1)
                {
                    TestHelper.Assert(response.ResultType == ResultType.Success);
                }

                request  = OutgoingRequestFrame.WithEmptyArgs(oneway, "opOneway", idempotent: false);
                response = oneway.Invoke(request, oneway: false);
                if (ice1)
                {
                    TestHelper.Assert(response.ResultType == ResultType.Failure);
                }

                request = OutgoingRequestFrame.WithArgs(cl,
                                                        "opString",
                                                        idempotent: false,
                                                        compress: false,
                                                        format: default,
Example #14
0
 private protected void Invoke(IObjectPrx prx, OutgoingRequestFrame request)
 {
     try
     {
         var completed = new IObjectPrx.InvokeTaskCompletionCallback(null, default);
         new OutgoingAsync(prx, completed, request, oneway: prx.IsOneway).Invoke(
             request.Operation, request.Context, synchronous: true);
         IncomingResponseFrame response = completed.Task.Result;
         if (!prx.IsOneway)
         {
             response.ReadVoidReturnValue();
         }
     }
     catch (AggregateException ex)
     {
         Debug.Assert(ex.InnerException != null);
         throw ex.InnerException;
     }
 }
Example #15
0
        internal async Task Invoke(ILocatorPrx l)
        {
            if (_locatorPrx == null || !_locatorPrx.Equals(l))
            {
                _locatorPrx = l;
                var requestFrame = new OutgoingRequestFrame(l, _current.Operation, _current.IsIdempotent,
                    _current.Context, _payload);

                try
                {
                    SetResult(await l.InvokeAsync(requestFrame).ConfigureAwait(false));
                }
                catch (Exception ex)
                {
                    Exception(ex);
                }
            }
            else
            {
                Debug.Assert(_exception != null);
                throw _exception;
            }
        }
Example #16
0
 public OutgoingAsyncT(IObjectPrx prx, IOutgoingAsyncCompletionCallback completionCallback,
                       OutgoingRequestFrame requestFrame) :
     base(prx, completionCallback, requestFrame)
 {
 }
Example #17
0
        public static Test.IMyClassPrx allTests(global::Test.TestHelper helper)
        {
            Communicator communicator = helper.communicator();
            var          cl           = Test.IMyClassPrx.Parse($"test:{helper.getTestEndpoint(0)}", communicator);
            var          oneway       = cl.Clone(oneway: true);

            var output = helper.getWriter();

            output.Write("testing Invoke... ");
            output.Flush();

            {
                var request = OutgoingRequestFrame.Empty(oneway, "opOneway", idempotent: false);

                // Whether the proxy is oneway or not does not matter for Invoke's oneway parameter.

                var response = cl.Invoke(request, oneway: true);
                test(response.ReplyStatus == ReplyStatus.OK);

                response = cl.Invoke(request, oneway: false);
                test(response.ReplyStatus == ReplyStatus.UserException);

                response = oneway.Invoke(request, oneway: true);
                test(response.ReplyStatus == ReplyStatus.OK);

                response = oneway.Invoke(request, oneway: false);
                test(response.ReplyStatus == ReplyStatus.UserException);

                request = new OutgoingRequestFrame(cl, "opString", idempotent: false);
                request.StartParameters();
                request.WriteString(testString);
                request.EndParameters();
                response = cl.Invoke(request);
                var result = response.ReadResult();
                test(result.ResultType == ResultType.Success);
                string s = result.InputStream.ReadString();
                test(s.Equals(testString));
                s = result.InputStream.ReadString();
                result.InputStream.EndEncapsulation();
                test(s.Equals(testString));
            }

            for (int i = 0; i < 2; ++i)
            {
                Dictionary <string, string>?ctx = null;
                if (i == 1)
                {
                    ctx          = new Dictionary <string, string>();
                    ctx["raise"] = "";
                }

                var request  = OutgoingRequestFrame.Empty(cl, "opException", idempotent: false, context: ctx);
                var response = cl.Invoke(request);
                var result   = response.ReadResult();
                test(result.ResultType == ResultType.Failure);
                try
                {
                    result.InputStream.ThrowException();
                }
                catch (Test.MyException)
                {
                    result.InputStream.EndEncapsulation();
                }
                catch (System.Exception)
                {
                    test(false);
                }
            }

            output.WriteLine("ok");

            output.Write("testing InvokeAsync... ");
            output.Flush();

            {
                var request = OutgoingRequestFrame.Empty(oneway, "opOneway", idempotent: false);
                try
                {
                    oneway.InvokeAsync(request, oneway: true).Wait();
                }
                catch (System.Exception)
                {
                    test(false);
                }

                request = new OutgoingRequestFrame(cl, "opString", idempotent: false);
                request.StartParameters();
                request.WriteString(testString);
                request.EndParameters();

                var response = cl.InvokeAsync(request).Result;
                var result   = response.ReadResult();
                test(result.ResultType == ResultType.Success);
                string s = result.InputStream.ReadString();
                test(s.Equals(testString));
                s = result.InputStream.ReadString();
                result.InputStream.EndEncapsulation();
                test(s.Equals(testString));
            }

            {
                var request  = OutgoingRequestFrame.Empty(cl, "opException", idempotent: false);
                var response = cl.InvokeAsync(request).Result;
                var result   = response.ReadResult();
                test(result.ResultType == ResultType.Failure);

                try
                {
                    result.InputStream.ThrowException();
                }
                catch (Test.MyException)
                {
                    result.InputStream.EndEncapsulation();
                }
                catch (System.Exception)
                {
                    test(false);
                }
            }

            output.WriteLine("ok");
            return(cl);
        }
Example #18
0
        public static IMyObjectPrx Run(TestHelper helper)
        {
            bool ice2 = helper.Protocol == Protocol.Ice2;
            var  prx  = IMyObjectPrx.Parse(helper.GetTestProxy("test"), helper.Communicator !);

            System.IO.TextWriter output = helper.Output;

            output.Write("testing retry... ");
            output.Flush();
            TestHelper.Assert(prx.AddWithRetry(33, 12) == 45);
            output.WriteLine("ok");

            output.Write("testing remote exception... ");
            output.Flush();
            try
            {
                prx.BadAdd(33, 12);
                TestHelper.Assert(false);
            }
            catch (InvalidInputException)
            {
                // expected
            }
            output.WriteLine("ok");

            output.Write("testing ONE... ");
            output.Flush();
            try
            {
                prx.NotExistAdd(33, 12);
                TestHelper.Assert(false);
            }
            catch (ObjectNotExistException)
            {
                // expected
            }
            output.WriteLine("ok");

            output.Write("testing exceptions raised by the interceptor... ");
            output.Flush();
            var exceptions = new List <(string operation, string kind)>
            {
                ("raiseBeforeDispatch", "invalidInput"),
                ("raiseBeforeDispatch", "notExist"),
                ("raiseAfterDispatch", "invalidInput"),
                ("raiseAfterDispatch", "notExist")
            };

            foreach ((string operation, string kind) in exceptions)
            {
                var ctx = new Dictionary <string, string>
                {
                    { operation, kind }
                };

                try
                {
                    prx.IcePing(ctx);
                    TestHelper.Assert(false);
                }
                catch (InvalidInputException) when(kind == "invalidInput")
                {
                }
                catch (ObjectNotExistException) when(kind == "notExist")
                {
                }
            }
            output.WriteLine("ok");

            output.Write("testing invocation interceptors... ");
            output.Flush();
            {
                var tasks             = new List <Task>();
                var invocationContext = new AsyncLocal <int>();
                using var communicator = new Communicator(prx.Communicator.GetProperties());

                communicator.DefaultInvocationInterceptors = ImmutableList.Create <InvocationInterceptor>(
                    (target, request, next, cancel) =>
                {
                    request.WritableContext["interceptor-1"] = "interceptor-1";
                    if (ice2)
                    {
                        request.BinaryContextOverride.Add(110, ostr => ostr.WriteInt(110));
                    }
                    return(next(target, request, cancel));
                },
                    async(target, request, next, cancel) =>
                {
                    TestHelper.Assert(request.Context["interceptor-1"] == "interceptor-1");
                    request.WritableContext["interceptor-2"] = "interceptor-2";
                    if (ice2)
                    {
                        request.BinaryContextOverride.Add(120, ostr => ostr.WriteInt(120));
                    }
                    IncomingResponseFrame response = await next(target, request, cancel);
                    TestHelper.Assert(invocationContext.Value == int.Parse(request.Context["local-user"]));
                    if (ice2)
                    {
                        TestHelper.Assert(response.BinaryContext.ContainsKey(110));
                        TestHelper.Assert(response.BinaryContext[110].Read(istr => istr.ReadInt()) == 110);
                        TestHelper.Assert(response.BinaryContext.ContainsKey(120));
                        TestHelper.Assert(response.BinaryContext[120].Read(istr => istr.ReadInt()) == 120);
                    }
                    return(response);
                });

                communicator.ActivateAsync().GetAwaiter().GetResult();

                for (int i = 0; i < 10; ++i)
                {
                    invocationContext.Value = i;
                    var  prx1 = IMyObjectPrx.Parse(prx.ToString() !, communicator);
                    Task t    = prx1.Op1Async(new Dictionary <string, string> {
                        { "local-user", $"{i}" }
                    });
                    tasks.Add(t);
                }
                Task.WaitAll(tasks.ToArray());
            }

            {
                IncomingResponseFrame?response = null;
                int invocations = 0;
                // An interceptor can stop the chain and directly return a response without calling next,
                // the first invocation calls next and subsequent invocations reuse the first response.
                using var communicator = new Communicator(prx.Communicator.GetProperties());

                communicator.DefaultInvocationInterceptors = ImmutableList.Create <InvocationInterceptor>(
                    (target, request, next, cancel) =>
                {
                    request.WritableContext["interceptor-1"] = "interceptor-1";
                    return(next(target, request, cancel));
                },
                    async(target, request, next, cancel) =>
                {
                    if (response == null)
                    {
                        response = await next(target, request, cancel);
                    }
                    return(response);
                },
                    (target, request, next, cancel) =>
                {
                    invocations++;
                    TestHelper.Assert(response == null);
                    return(next(target, request, cancel));
                });

                TestHelper.Assert(communicator.DefaultInvocationInterceptors.Count == 3);
                communicator.ActivateAsync().GetAwaiter().GetResult();
                TestHelper.Assert(communicator.DefaultInvocationInterceptors.Count == 4);

                var prx1 = IMyObjectPrx.Parse(prx.ToString() !, communicator);

                // Truly reference equal
                TestHelper.Assert(prx1.InvocationInterceptors == communicator.DefaultInvocationInterceptors);

                prx1.Op1(new Dictionary <string, string> {
                    { "local-user", "10" }
                });
                prx1.Op1(new Dictionary <string, string> {
                    { "local-user", "11" }
                });
                prx1.Op1(new Dictionary <string, string> {
                    { "local-user", "12" }
                });
                TestHelper.Assert(invocations == 1);
            }

            {
                // throwing from an interceptor stops the interceptor chain
                using var communicator = new Communicator(prx.Communicator.GetProperties());
                communicator.DefaultInvocationInterceptors = ImmutableList.Create <InvocationInterceptor>(
                    (target, request, next, cancel) =>
                {
                    request.WritableContext["interceptor-1"] = "interceptor-1";
                    return(next(target, request, cancel));
                },
                    (target, request, next, cancel) =>
                {
                    TestHelper.Assert(request.Context["interceptor-1"] == "interceptor-1");
                    throw new InvalidOperationException("stop interceptor chain");
                },
                    (target, request, next, cancel) =>
                {
                    TestHelper.Assert(false);
                    return(next(target, request, cancel));
                });
                communicator.ActivateAsync().GetAwaiter().GetResult();

                var prx1 = IMyObjectPrx.Parse(prx.ToString() !, communicator);
                try
                {
                    prx1.Op1();
                    TestHelper.Assert(false);
                }
                catch (InvalidOperationException)
                {
                }
            }
            output.WriteLine("ok");

            output.Write("testing binary context... ");
            output.Flush();

            if (ice2)
            {
                for (int size = 128; size < 4096; size *= 2)
                {
                    var token = new Token(1, "mytoken", Enumerable.Range(0, size).Select(i => (byte)2).ToArray());

                    {
                        using var request = OutgoingRequestFrame.WithArgs(prx,
                                                                          "opWithBinaryContext",
                                                                          idempotent: false,
                                                                          compress: false,
                                                                          format: default,
                                                                          context: null,
                                                                          token,
                                                                          Token.IceWriter);
                        request.BinaryContextOverride.Add(1, ostr => ostr.WriteStruct(token));
                        request.BinaryContextOverride.Add(3, ostr => ostr.WriteShort((short)size));
                        request.BinaryContextOverride.Add(
                            2,
                            ostr => ostr.WriteSequence(
                                Enumerable.Range(0, 10).Select(i => $"string-{i}").ToArray(),
                                (ostr, s) => ostr.WriteString(s)));

                        using IncomingResponseFrame response = prx.InvokeAsync(request).Result;
                    }

                    {
                        // repeat with compressed frame
                        using OutgoingRequestFrame request = OutgoingRequestFrame.WithArgs(prx,
                                                                                           "opWithBinaryContext",
                                                                                           idempotent: false,
                                                                                           compress: false,
                                                                                           format: default,
                                                                                           context: null,
                                                                                           token,
                                                                                           Token.IceWriter);
                        request.BinaryContextOverride.Add(1, ostr => ostr.WriteStruct(token));
                        request.BinaryContextOverride.Add(3, ostr => ostr.WriteShort((short)size));
                        request.BinaryContextOverride.Add(
                            2,
                            ostr => ostr.WriteSequence(
                                Enumerable.Range(0, 10).Select(i => $"string-{i}").ToArray(),
                                (ostr, s) => ostr.WriteString(s)));

                        TestHelper.Assert(request.CompressPayload() == CompressionResult.Success);
                        using IncomingResponseFrame response = prx.InvokeAsync(request).Result;
                    }

                    {
                        // repeat compressed the frame before writing the context
                        using OutgoingRequestFrame request = OutgoingRequestFrame.WithArgs(prx,
                                                                                           "opWithBinaryContext",
                                                                                           idempotent: false,
                                                                                           compress: false,
                                                                                           format: default,
                                                                                           context: null,
                                                                                           token,
                                                                                           Token.IceWriter);

                        TestHelper.Assert(request.CompressPayload() == CompressionResult.Success);

                        request.BinaryContextOverride.Add(1, ostr => ostr.WriteStruct(token));
                        request.BinaryContextOverride.Add(3, ostr => ostr.WriteShort((short)size));
                        request.BinaryContextOverride.Add(
                            2,
                            ostr => ostr.WriteSequence(
                                Enumerable.Range(0, 10).Select(i => $"string-{i}").ToArray(),
                                (ostr, s) => ostr.WriteString(s)));

                        using IncomingResponseFrame response = prx.InvokeAsync(request).Result;
                    }
                }
            }
            else
            {
                var token = new Token(1, "mytoken", Enumerable.Range(0, 256).Select(i => (byte)2).ToArray());
                using var request = OutgoingRequestFrame.WithArgs(prx,
                                                                  "opWithBinaryContext",
                                                                  idempotent: false,
                                                                  compress: false,
                                                                  format: default,
                                                                  context: null,
                                                                  token,
                                                                  Token.IceWriter);
                try
                {
                    request.BinaryContextOverride.Add(1, ostr => ostr.WriteStruct(token));
                    TestHelper.Assert(false);
                }
                catch (NotSupportedException)
                {
                }
                using IncomingResponseFrame response = prx.InvokeAsync(request).Result;
            }
            output.WriteLine("ok");

            output.Write("testing per proxy invocation interceptors... ");
            output.Flush();
            {
                var communicator = helper.Communicator !;

                SortedDictionary <string, string>?context = prx.Op2();
                TestHelper.Assert(context["context1"] == "plug-in");
                TestHelper.Assert(context["context2"] == "plug-in");
                TestHelper.Assert(!context.ContainsKey("context3"));
                prx = prx.Clone(invocationInterceptors: ImmutableList.Create <InvocationInterceptor>(
                                    (target, request, next, cancel) =>
                {
                    request.WritableContext["context2"] = "proxy";
                    request.WritableContext["context3"] = "proxy";
                    return(next(target, request, cancel));
                }).AddRange(communicator.DefaultInvocationInterceptors));
                context = prx.Op2();
                TestHelper.Assert(context["context1"] == "plug-in");
                TestHelper.Assert(context["context2"] == "plug-in");
                TestHelper.Assert(context["context3"] == "proxy");

                // Calling next twice doesn't change the result
                prx = prx.Clone(invocationInterceptors: ImmutableList.Create <InvocationInterceptor>(
                                    (target, request, next, cancel) =>
                {
                    request.WritableContext["context2"] = "proxy";
                    request.WritableContext["context3"] = "proxy";
                    _ = next(target, request, cancel);
                    return(next(target, request, cancel));
                }).AddRange(communicator.DefaultInvocationInterceptors));
                context = prx.Op2();
                TestHelper.Assert(context["context1"] == "plug-in");
                TestHelper.Assert(context["context2"] == "plug-in");
                TestHelper.Assert(context["context3"] == "proxy");

                // Cloning the proxy preserve its interceptors
                prx     = prx.Clone(invocationTimeout: TimeSpan.FromSeconds(10));
                context = prx.Op2();
                TestHelper.Assert(context["context1"] == "plug-in");
                TestHelper.Assert(context["context2"] == "plug-in");
                TestHelper.Assert(context["context3"] == "proxy");

                // The server increments the result with each call when using the invocation interceptor we
                // return a cached response, and we will see the same result with each call.
                IncomingResponseFrame?response = null;
                prx = prx.Clone(invocationInterceptors: ImmutableList.Create <InvocationInterceptor>(
                                    async(target, request, next, cancel) =>
                {
                    response ??= await next(target, request, cancel);
                    return(response);
                }).AddRange(communicator.DefaultInvocationInterceptors));
                TestHelper.Assert(prx.Op3() == 0);
                TestHelper.Assert(prx.Op3() == 0);

                // After clearing the invocation interceptors we should see the result increase with each call
                prx = prx.Clone(invocationInterceptors: communicator.DefaultInvocationInterceptors);
                TestHelper.Assert(prx.Op3() == 1);
                TestHelper.Assert(prx.Op3() == 2);
            }
            output.WriteLine("ok");
            return(prx);
        }
Example #19
0
        public static IMyObjectPrx Run(TestHelper helper)
        {
            bool ice2 = helper.Protocol == Protocol.Ice2;
            var  prx  = IMyObjectPrx.Parse(helper.GetTestProxy("test"), helper.Communicator !);

            System.IO.TextWriter output = helper.Output;

            output.Write("testing retry... ");
            output.Flush();
            TestHelper.Assert(prx.AddWithRetry(33, 12) == 45);
            output.WriteLine("ok");

            output.Write("testing remote exception... ");
            output.Flush();
            try
            {
                prx.BadAdd(33, 12);
                TestHelper.Assert(false);
            }
            catch (InvalidInputException)
            {
                // expected
            }
            output.WriteLine("ok");

            output.Write("testing ONE... ");
            output.Flush();
            try
            {
                prx.NotExistAdd(33, 12);
                TestHelper.Assert(false);
            }
            catch (ObjectNotExistException)
            {
                // expected
            }
            output.WriteLine("ok");

            output.Write("testing exceptions raised by the interceptor... ");
            output.Flush();
            var exceptions = new List <(string operation, string kind)>
            {
                ("raiseBeforeDispatch", "invalidInput"),
                ("raiseBeforeDispatch", "notExist"),
                ("raiseAfterDispatch", "invalidInput"),
                ("raiseAfterDispatch", "notExist")
            };

            foreach ((string operation, string kind) in exceptions)
            {
                var ctx = new Dictionary <string, string>
                {
                    { operation, kind }
                };

                try
                {
                    prx.IcePing(ctx);
                    TestHelper.Assert(false);
                }
                catch (InvalidInputException) when(kind == "invalidInput")
                {
                }
                catch (ObjectNotExistException) when(kind == "notExist")
                {
                }
            }
            output.WriteLine("ok");

            output.Write("testing invocation interceptors... ");
            output.Flush();
            {
                var tasks             = new List <Task>();
                var invocationContext = new AsyncLocal <int>();
                using var communicator = new Communicator(
                          prx.Communicator.GetProperties(),
                          invocationInterceptors: new InvocationInterceptor[]
                {
                    (target, request, next, cancel) =>
                    {
                        if (ice2)
                        {
                            request.ContextOverride["interceptor-1"] = "interceptor-1";
                            request.AddBinaryContextEntry(110, 110, (ostr, v) => ostr.WriteInt(v));
                        }
                        return(next(target, request, cancel));
                    },
                    async(target, request, next, cancel) =>
                    {
                        if (ice2)
                        {
                            TestHelper.Assert(request.Context["interceptor-1"] == "interceptor-1");
                            request.ContextOverride["interceptor-2"] = "interceptor-2";
                            request.AddBinaryContextEntry(120, 120, (ostr, v) => ostr.WriteInt(v));
                        }
                        IncomingResponseFrame response = await next(target, request, cancel);
                        TestHelper.Assert(invocationContext.Value == int.Parse(request.Context["local-user"]));
                        if (ice2)
                        {
                            TestHelper.Assert(response.BinaryContext.ContainsKey(110));
                            TestHelper.Assert(response.BinaryContext[110].Read(istr => istr.ReadInt()) == 110);
                            TestHelper.Assert(response.BinaryContext.ContainsKey(120));
                            TestHelper.Assert(response.BinaryContext[120].Read(istr => istr.ReadInt()) == 120);
                        }
                        return(response);
                    }
                });

                for (int i = 0; i < 10; ++i)
                {
                    invocationContext.Value = i;
                    var  prx1 = IMyObjectPrx.Parse(prx.ToString() !, communicator);
                    Task t    = prx1.Op1Async(new Dictionary <string, string> {
                        { "local-user", $"{i}" }
                    });
                    tasks.Add(t);
                }
                Task.WaitAll(tasks.ToArray());
            }

            {
                IncomingResponseFrame?response = null;
                int invocations = 0;
                // An interceptor can stop the chain and directly return a response without calling next,
                // the first invocation calls next and subsequent invocations reuse the first response.
                using var communicator = new Communicator(
                          prx.Communicator.GetProperties(),
                          invocationInterceptors: new InvocationInterceptor[]
                {
                    (target, request, next, cancel) =>
                    {
                        if (ice2)
                        {
                            request.ContextOverride["interceptor-1"] = "interceptor-1";
                        }
                        return(next(target, request, cancel));
                    },
                    async(target, request, next, cancel) =>
                    {
                        if (response == null)
                        {
                            response = await next(target, request, cancel);
                        }
                        return(response);
                    },
                    (target, request, next, cancel) =>
                    {
                        invocations++;
                        TestHelper.Assert(response == null);
                        return(next(target, request, cancel));
                    }
                });

                var prx1 = IMyObjectPrx.Parse(prx.ToString() !, communicator);
                prx1.Op1(new Dictionary <string, string> {
                    { "local-user", "10" }
                });
                prx1.Op1(new Dictionary <string, string> {
                    { "local-user", "11" }
                });
                prx1.Op1(new Dictionary <string, string> {
                    { "local-user", "12" }
                });
                TestHelper.Assert(invocations == 1);
            }

            {
                // throwing from an interceptor stops the interceptor chain
                using var communicator = new Communicator(
                          prx.Communicator.GetProperties(),
                          invocationInterceptors: new InvocationInterceptor[]
                {
                    (target, request, next, cancel) =>
                    {
                        request.ContextOverride["interceptor-1"] = "interceptor-1";
                        return(next(target, request, cancel));
                    },
                    (target, request, next, cancel) =>
                    {
                        TestHelper.Assert(request.Context["interceptor-1"] == "interceptor-1");
                        throw new InvalidOperationException("stop interceptor chain");
                    },
                    (target, request, next, cancel) =>
                    {
                        TestHelper.Assert(false);
                        return(next(target, request, cancel));
                    }
                });

                var prx1 = IMyObjectPrx.Parse(prx.ToString() !, communicator);
                try
                {
                    prx1.Op1();
                    TestHelper.Assert(false);
                }
                catch (InvalidOperationException)
                {
                }
            }
            output.WriteLine("ok");

            output.Write("testing binary context... ");
            output.Flush();

            if (ice2)
            {
                for (int size = 128; size < 4096; size *= 2)
                {
                    var token   = new Token(1, "mytoken", Enumerable.Range(0, size).Select(i => (byte)2).ToArray());
                    var request = OutgoingRequestFrame.WithArgs(prx,
                                                                "opWithBinaryContext",
                                                                idempotent: false,
                                                                compress: false,
                                                                format: default,
Example #20
0
        private void Run(IMyObjectPrx prx, Interceptor interceptor)
        {
            System.IO.TextWriter output = GetWriter();
            output.Write("testing simple interceptor... ");
            output.Flush();
            Assert(interceptor.GetLastOperation() == null);
            Assert(!interceptor.AsyncCompletion);
            prx.IcePing();
            Assert(interceptor.GetLastOperation() !.Equals("ice_ping"));
            Assert(!interceptor.AsyncCompletion);
            string typeId = prx.IceId();

            Assert(interceptor.GetLastOperation() !.Equals("ice_id"));
            Assert(!interceptor.AsyncCompletion);
            Assert(prx.IceIsA(typeId));
            Assert(interceptor.GetLastOperation() !.Equals("ice_isA"));
            Assert(!interceptor.AsyncCompletion);
            Assert(prx.Add(33, 12) == 45);
            Assert(interceptor.GetLastOperation() !.Equals("add"));
            Assert(!interceptor.AsyncCompletion);
            output.WriteLine("ok");
            output.Write("testing retry... ");
            output.Flush();
            Assert(prx.AddWithRetry(33, 12) == 45);
            Assert(interceptor.GetLastOperation() !.Equals("addWithRetry"));
            Assert(!interceptor.AsyncCompletion);
            output.WriteLine("ok");
            output.Write("testing remote exception... ");
            output.Flush();
            try
            {
                prx.BadAdd(33, 12);
                Assert(false);
            }
            catch (InvalidInputException)
            {
                // expected
            }
            Assert(interceptor.GetLastOperation() !.Equals("badAdd"));
            Assert(!interceptor.AsyncCompletion);
            output.WriteLine("ok");
            output.Write("testing ONE... ");
            output.Flush();
            interceptor.Clear();
            try
            {
                prx.NotExistAdd(33, 12);
                Assert(false);
            }
            catch (ObjectNotExistException)
            {
                // expected
            }
            Assert(interceptor.GetLastOperation() !.Equals("notExistAdd"));
            Assert(!interceptor.AsyncCompletion);
            output.WriteLine("ok");

            output.Write("testing exceptions raised by the interceptor... ");
            output.Flush();
            TestInterceptorExceptions(prx);
            output.WriteLine("ok");

            output.Write("testing binary context... ");
            output.Flush();
            bool ice2 = Communicator() !.DefaultProtocol != Protocol.Ice1;

            if (ice2)
            {
                for (int size = 128; size < 4096; size *= 2)
                {
                    var token   = new Token(1, "mytoken", Enumerable.Range(0, size).Select(i => (byte)2).ToArray());
                    var request = OutgoingRequestFrame.WithParamList(prx,
                                                                     "opWithBinaryContext",
                                                                     idempotent: false,
                                                                     compress: false,
                                                                     format: default,
Example #21
0
        public static async Task RunAsync(TestHelper helper)
        {
            Communicator communicator = helper.Communicator;

            bool        ice1   = helper.Protocol == Protocol.Ice1;
            var         cl     = IMyClassPrx.Parse(helper.GetTestProxy("test", 0), communicator);
            IMyClassPrx oneway = cl.Clone(oneway: true);

            System.IO.TextWriter output = helper.Output;
            output.Write("testing InvokeAsync... ");
            output.Flush();

            {
                using var request = OutgoingRequestFrame.WithEmptyArgs(oneway, "opOneway", idempotent: false);

                try
                {
                    using IncomingResponseFrame response = oneway.InvokeAsync(request, oneway: true).Result;
                }
                catch
                {
                    TestHelper.Assert(false);
                }
            }

            {
                using var request = OutgoingRequestFrame.WithArgs(cl,
                                                                  "opString",
                                                                  idempotent: false,
                                                                  compress: false,
                                                                  format: default,
                                                                  context: null,
                                                                  TestString,
                                                                  OutputStream.IceWriterFromString);

                using IncomingResponseFrame response = cl.InvokeAsync(request).Result;
                (string s1, string s2) = response.ReadReturnValue(cl, istr =>
                {
                    string s1 = istr.ReadString();
                    string s2 = istr.ReadString();
                    return(s1, s2);
                });
                TestHelper.Assert(s1.Equals(TestString));
                TestHelper.Assert(s2.Equals(TestString));
            }

            {
                using var request = OutgoingRequestFrame.WithEmptyArgs(cl, "opException", idempotent: false);
                using IncomingResponseFrame response = cl.InvokeAsync(request).Result;

                try
                {
                    response.ReadVoidReturnValue(cl);
                    TestHelper.Assert(false);
                }
                catch (MyException)
                {
                }
                catch
                {
                    TestHelper.Assert(false);
                }
            }

            output.WriteLine("ok");
            await cl.ShutdownAsync();
        }
Example #22
0
 public TReturnValue Invoke(IObjectPrx prx, IReadOnlyDictionary <string, string>?context) =>
 Invoke(prx, OutgoingRequestFrame.WithEmptyParamList(prx, _operationName, _idempotent, context));
Example #23
0
        private async ValueTask InvokeAllAsync(OutgoingRequestFrame outgoingRequest, int requestId)
        {
            // The object adapter DirectCount was incremented by the caller and we are responsible to decrement it
            // upon completion.

            Ice.Instrumentation.IDispatchObserver?dispatchObserver = null;
            try
            {
                if (_traceLevels.Protocol >= 1)
                {
                    // TODO we need a better API for tracing
                    List <System.ArraySegment <byte> > requestData =
                        Ice1Definitions.GetRequestData(outgoingRequest, requestId);
                    TraceUtil.TraceSend(_adapter.Communicator, VectoredBufferExtensions.ToArray(requestData), _logger,
                                        _traceLevels);
                }

                var incomingRequest = new IncomingRequestFrame(_adapter.Communicator, outgoingRequest);
                var current         = new Current(_adapter, incomingRequest, requestId);

                // Then notify and set dispatch observer, if any.
                Ice.Instrumentation.ICommunicatorObserver?communicatorObserver = _adapter.Communicator.Observer;
                if (communicatorObserver != null)
                {
                    dispatchObserver = communicatorObserver.GetDispatchObserver(current, incomingRequest.Size);
                    dispatchObserver?.Attach();
                }

                bool amd = true;
                try
                {
                    IObject?servant = current.Adapter.Find(current.Identity, current.Facet);

                    if (servant == null)
                    {
                        amd = false;
                        throw new ObjectNotExistException(current.Identity, current.Facet, current.Operation);
                    }

                    ValueTask <OutgoingResponseFrame> vt = servant.DispatchAsync(incomingRequest, current);
                    amd = !vt.IsCompleted;
                    if (requestId != 0)
                    {
                        OutgoingResponseFrame response = await vt.ConfigureAwait(false);

                        dispatchObserver?.Reply(response.Size);
                        SendResponse(requestId, response, amd);
                    }
                }
                catch (System.Exception ex)
                {
                    if (requestId != 0)
                    {
                        RemoteException actualEx;
                        if (ex is RemoteException remoteEx && !remoteEx.ConvertToUnhandled)
                        {
                            actualEx = remoteEx;
                        }
                        else
                        {
                            actualEx = new UnhandledException(current.Identity, current.Facet, current.Operation, ex);
                        }

                        Incoming.ReportException(actualEx, dispatchObserver, current);
                        var response = new OutgoingResponseFrame(current, actualEx);
                        dispatchObserver?.Reply(response.Size);
                        SendResponse(requestId, response, amd);
                    }
                }
            }
Example #24
0
        public static IMyClassPrx allTests(TestHelper helper)
        {
            Communicator?communicator = helper.Communicator();

            TestHelper.Assert(communicator != null);
            var         cl     = IMyClassPrx.Parse($"test:{helper.GetTestEndpoint(0)}", communicator);
            IMyClassPrx oneway = cl.Clone(oneway: true);

            System.IO.TextWriter output = helper.GetWriter();
            output.Write("testing Invoke... ");
            output.Flush();

            {
                var request = OutgoingRequestFrame.WithEmptyParamList(oneway, "opOneway", idempotent: false);

                // Whether the proxy is oneway or not does not matter for Invoke's oneway parameter.

                IncomingResponseFrame response = cl.Invoke(request, oneway: true);
                TestHelper.Assert(response.ReplyStatus == ReplyStatus.OK);

                response = cl.Invoke(request, oneway: false);
                TestHelper.Assert(response.ReplyStatus == ReplyStatus.UserException);

                response = oneway.Invoke(request, oneway: true);
                TestHelper.Assert(response.ReplyStatus == ReplyStatus.OK);

                response = oneway.Invoke(request, oneway: false);
                TestHelper.Assert(response.ReplyStatus == ReplyStatus.UserException);

                request = OutgoingRequestFrame.WithParamList(cl, "opString", idempotent: false,
                                                             format: null, context: null, _testString, OutputStream.IceWriterFromString);
                response = cl.Invoke(request);
                (string s1, string s2) = response.ReadReturnValue(communicator, istr =>
                {
                    string s1 = istr.ReadString();
                    string s2 = istr.ReadString();
                    return(s1, s2);
                });
                TestHelper.Assert(s1.Equals(_testString) && s2.Equals(_testString));
            }

            for (int i = 0; i < 2; ++i)
            {
                Dictionary <string, string>?ctx = null;
                if (i == 1)
                {
                    ctx = new Dictionary <string, string>
                    {
                        ["raise"] = ""
                    };
                }

                var request = OutgoingRequestFrame.WithEmptyParamList(cl, "opException", idempotent: false, context: ctx);
                IncomingResponseFrame response = cl.Invoke(request);
                try
                {
                    response.ReadVoidReturnValue(communicator);
                }
                catch (MyException)
                {
                    // expected
                }
                catch (System.Exception)
                {
                    TestHelper.Assert(false);
                }
            }

            output.WriteLine("ok");

            output.Write("testing InvokeAsync... ");
            output.Flush();

            {
                var request = OutgoingRequestFrame.WithEmptyParamList(oneway, "opOneway", idempotent: false);
                IncomingResponseFrame response;
                try
                {
                    response = oneway.InvokeAsync(request, oneway: true).AsTask().Result;
                }
                catch (System.Exception)
                {
                    TestHelper.Assert(false);
                }

                request = OutgoingRequestFrame.WithParamList(cl, "opString", idempotent: false,
                                                             format: null, context: null, _testString, OutputStream.IceWriterFromString);

                response = cl.InvokeAsync(request).AsTask().Result;
                (string s1, string s2) = response.ReadReturnValue(communicator, istr =>
                {
                    string s1 = istr.ReadString();
                    string s2 = istr.ReadString();
                    return(s1, s2);
                });
                TestHelper.Assert(s1.Equals(_testString));
                TestHelper.Assert(s2.Equals(_testString));
            }

            {
                var request = OutgoingRequestFrame.WithEmptyParamList(cl, "opException", idempotent: false);
                IncomingResponseFrame response = cl.InvokeAsync(request).AsTask().Result;

                try
                {
                    response.ReadVoidReturnValue(communicator);
                    TestHelper.Assert(false);
                }
                catch (MyException)
                {
                }
                catch (System.Exception)
                {
                    TestHelper.Assert(false);
                }
            }

            output.WriteLine("ok");
            return(cl);
        }