Пример #1
0
        public IList<MemoryStream> GetBytes(Protocol local, Requestor requestor)
        {
            if (local == null) throw new ArgumentNullException("local");
            if (requestor == null) throw new ArgumentNullException("requestor");

            if (requestBytes == null)
            {
                using (var bbo = new ByteBufferOutputStream())
                {
                    var o = new BinaryEncoder(bbo);

                    // use local protocol to write request
                    Message m = GetMessage(local);
                    Context.Message = m;

                    requestor.WriteRequest(m.Request, request, o); // write request payload

                    o.Flush();
                    List<MemoryStream> payload = bbo.GetBufferList();

                    requestor.WriteHandshake(o); // prepend handshake if needed

                    Context.RequestPayload = payload;

                    IDictionary<string, object> responseCallMeta = Context.ResponseCallMeta;
                    Requestor.MetaWriter.Write(responseCallMeta, o);

                    o.WriteString(m.Name); // write message name
                    o.Flush();

                    bbo.Append(payload);

                    requestBytes = bbo.GetBufferList();
                }
            }

            return requestBytes;
        }
Пример #2
0
        public IList<MemoryStream> Respond(IList<MemoryStream> buffers,
                                          Transceiver connection)
        {
            Decoder input = new BinaryDecoder(new ByteBufferInputStream(buffers));

            var bbo = new ByteBufferOutputStream();
            var output = new BinaryEncoder(bbo);
            Exception error = null;
            var context = new RpcContext();
            List<MemoryStream> handshake = null;

            bool wasConnected = connection != null && connection.IsConnected;
            try
            {
                Protocol remote = Handshake(input, output, connection);
                output.Flush();
                if (remote == null) // handshake failed
                    return bbo.GetBufferList();
                handshake = bbo.GetBufferList();

                // read request using remote protocol specification
                context.RequestCallMeta = META_READER.Read(null, input);
                String messageName = input.ReadString();
                if (messageName.Equals("")) // a handshake ping
                    return handshake;
                Message rm = remote.Messages[messageName];
                if (rm == null)
                    throw new AvroRuntimeException("No such remote message: " + messageName);
                Message m = Local.Messages[messageName];
                if (m == null)
                    throw new AvroRuntimeException("No message named " + messageName
                                                   + " in " + Local);

                Object request = ReadRequest(rm.Request, m.Request, input);

                context.Message = rm;

                // create response using local protocol specification
                if ((m.Oneway.GetValueOrDefault() != rm.Oneway.GetValueOrDefault()) && wasConnected)
                    throw new AvroRuntimeException("Not both one-way: " + messageName);

                Object response = null;

                try
                {
                    response = Respond(m, request);
                    context.Response = response;
                }
                catch (Exception e)
                {
                    error = e;
                    context.Error = error;
                    log.Warn("user error", e);
                }

                if (m.Oneway.GetValueOrDefault() && wasConnected) // no response data
                    return null;

                output.WriteBoolean(error != null);
                if (error == null)
                    WriteResponse(m.Response, response, output);
                else
                {
                    try 
                    {
                        WriteError(m.SupportedErrors, error, output);
                    } 
                    catch (Exception)
                    {    
                        // Presumably no match on the exception, throw the original
                        throw error;
                    }
                }
            }
            catch (Exception e)
            {
                // system error
                log.Warn("system error", e);
                context.Error = e;
                bbo = new ByteBufferOutputStream();
                output = new BinaryEncoder(bbo);
                output.WriteBoolean(true);

                WriteError(errorSchema /*Protocol.SYSTEM_ERRORS*/, e.ToString(), output);
                if (null == handshake)
                {
                    handshake = new ByteBufferOutputStream().GetBufferList();
                }
            }

            output.Flush();
            List<MemoryStream> payload = bbo.GetBufferList();

            // Grab meta-data from plugins
            context.ResponsePayload = payload;

            META_WRITER.Write(context.ResponseCallMeta, output);
            output.Flush();
            // Prepend handshake and append payload
            bbo.Prepend(handshake);
            bbo.Append(payload);

            return bbo.GetBufferList();
        }