private IMessage SerializeAndEmbedHeadersIfApplicable(IMessage message)
            {
                var transformed = new MessageValues(message);

                object payload;

                if (embedHeaders)
                {
                    transformed.TryGetValue(MessageHeaders.CONTENT_TYPE, out var contentType);

                    // transform content type headers to String, so that they can be properly
                    // embedded in JSON
                    if (contentType != null)
                    {
                        transformed[MessageHeaders.CONTENT_TYPE] = contentType.ToString();
                    }

                    payload = EmbeddedHeaderUtils.EmbedHeaders(transformed, embeddedHeaders);
                }
                else
                {
                    payload = transformed.Payload;
                }

                return(IntegrationServices.MessageBuilderFactory.WithPayload(payload).CopyHeaders(transformed.Headers).Build());
            }
            public override IMessage PreSend(IMessage message, IMessageChannel channel)
            {
                if (message.Payload is byte[] &&
                    !message.Headers.ContainsKey(BinderHeaders.NATIVE_HEADERS_PRESENT) &&
                    EmbeddedHeaderUtils.MayHaveEmbeddedHeaders((byte[])message.Payload))
                {
                    MessageValues messageValues;
                    try
                    {
                        messageValues = EmbeddedHeaderUtils.ExtractHeaders((IMessage <byte[]>)message, true);
                    }
                    catch (Exception)
                    {
                        /*
                         * debug() rather then error() since we don't know for sure that it
                         * really is a message with embedded headers, it just meets the
                         * criteria in EmbeddedHeaderUtils.mayHaveEmbeddedHeaders().
                         */

                        // this.logger?.LogDebug(EmbeddedHeaderUtils.DecodeExceptionMessage(message), e);
                        messageValues = new MessageValues(message);
                    }

                    return(messageValues.ToMessage());
                }

                return(message);
            }
예제 #3
0
        public static byte[] EmbedHeaders(MessageValues original, params string[] headers)
        {
            try
            {
                var headerValues  = new byte[headers.Length][];
                var n             = 0;
                var headerCount   = 0;
                var headersLength = 0;
                foreach (var header in headers)
                {
                    original.TryGetValue(header, out var value);
                    if (value != null)
                    {
                        var json = JsonConvert.SerializeObject(value);
                        headerValues[n] = Encoding.UTF8.GetBytes(json);
                        headerCount++;
                        headersLength += header.Length + headerValues[n++].Length;
                    }
                    else
                    {
                        headerValues[n++] = null;
                    }
                }

                // 0xff, n(1), [ [lenHdr(1), hdr, lenValue(4), value] ... ]
                var byteBuffer = new MemoryStream();
                byteBuffer.WriteByte((byte)0xff); // signal new format
                byteBuffer.WriteByte((byte)headerCount);
                for (var i = 0; i < headers.Length; i++)
                {
                    if (headerValues[i] != null)
                    {
                        byteBuffer.WriteByte((byte)headers[i].Length);

                        var buffer = Encoding.UTF8.GetBytes(headers[i]);
                        byteBuffer.Write(buffer, 0, buffer.Length);

                        buffer = GetBigEndianBytes(headerValues[i].Length);
                        byteBuffer.Write(buffer, 0, buffer.Length);

                        byteBuffer.Write(headerValues[i], 0, headerValues[i].Length);
                    }
                }

                var payloadBuffer = (byte[])original.Payload;
                byteBuffer.Write(payloadBuffer, 0, payloadBuffer.Length);

                return(byteBuffer.ToArray());
            }
            catch (Exception)
            {
                // Log
                throw;
            }
        }
예제 #4
0
        private static MessageValues BuildMessageValues(byte[] payload, Dictionary <string, object> headers, bool copyRequestHeaders, IMessageHeaders requestHeaders)
        {
            var messageValues = new MessageValues(payload, headers);

            if (copyRequestHeaders && requestHeaders != null)
            {
                messageValues.CopyHeadersIfAbsent(requestHeaders);
            }

            return(messageValues);
        }
예제 #5
0
        public void TestEmbedded()
        {
            var searchDirectories            = GetSearchDirectories("TestBinder");
            IServiceProvider serviceProvider = CreateStreamsContainer(
                searchDirectories,
                "spring:cloud:stream:bindings:foo:consumer:headerMode=" + HeaderMode.EmbeddedHeaders.ToString()).BuildServiceProvider();
            var messageConverter = serviceProvider.GetService <ISmartMessageConverter>();

            Assert.NotNull(messageConverter);

            var binder = serviceProvider.GetService <IBinder>() as AbstractPollableMessageSourceBinder;

            Assert.NotNull(binder);

            var configurer = serviceProvider.GetService <MessageConverterConfigurer>();

            Assert.NotNull(configurer);

            var setter        = binder.GetType().GetProperty("MessageSourceDelegate").GetSetMethod();
            var messageSource = new TestFuncMessageSource(() =>
            {
                var original = new MessageValues(
                    Encoding.UTF8.GetBytes("foo"),
                    new Dictionary <string, object>()
                {
                    { MessageHeaders.CONTENT_TYPE, "application/octet-stream" }
                });
                var payload = new byte[0];
                try
                {
                    payload = EmbeddedHeaderUtils.EmbedHeaders(original, MessageHeaders.CONTENT_TYPE);
                }
                catch (Exception e)
                {
                    Assert.NotNull(e);
                }

                return(Message.Create <byte[]>(payload));
            });

            setter.Invoke(binder, new object[] { messageSource });

            var options = serviceProvider.GetService <IOptions <BindingServiceOptions> >();

            options.Value.Bindings.TryGetValue("foo", out var bindingOptions);
            Assert.Equal(HeaderMode.EmbeddedHeaders, bindingOptions.Consumer.HeaderMode);

            var pollableSource = new DefaultPollableMessageSource(serviceProvider.GetService <IApplicationContext>(), messageConverter);

            configurer.ConfigurePolledMessageSource(pollableSource, "foo");
            pollableSource.AddInterceptor(new TestEmbededChannelInterceptor());

            binder.BindConsumer("foo", "bar", pollableSource, bindingOptions.Consumer);

            var handler = new TestConvertSimpleHandler();

            Assert.True(pollableSource.Poll(handler));

            Assert.IsType <string>(handler.Payload);
            var str = handler.Payload as string;

            Assert.Equal("FOO", str);
            handler.Message.Headers.TryGetValue(MessageHeaders.CONTENT_TYPE, out var contentType);
            Assert.Equal("application/octet-stream", contentType.ToString());
        }