微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用高级Ocelot请求聚合时,聚合器得到空响应

如何解决使用高级Ocelot请求聚合时,聚合器得到空响应

我的ocelot配置如下(仅相关部分)

"Routes": [
    {
      "DownstreamPathTemplate": "/api/service1/json/{pageSize}/{pageNo}/all/{partnerId}","DownstreamScheme": "http","UpstreamPathTemplate": "/a","UpstreamHttpMethod": [ "Get" ],"ServiceName": "Service1","LoadBalancerOptions": {
        "Type": "LeastConnection"
      },"Key": "v0-service1","Priority": 1
    },{
      "DownstreamPathTemplate": "/api/service2/json/{pageSize}/{pageNo}/{partnerId}","UpstreamPathTemplate": "/b","ServiceName": "Service2","Key": "v0-service2","Priority": 1
    }
    ],"Aggregates": [
    {
      "RouteKeys": [
        "v0-service1","v0-service2"
      ],"UpstreamPathTemplate": "/api/services/{partnerId}?pageNo={pageNo}&pageSize={pageSize}","Aggregator": "GetDataAggregator"
    }
]

目前,聚合器的定义如下:

public class GetoffersAggregator : IDefinedAggregator
{
    public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
    {
        var readers = responses.Select(r => new StreamReader(r.Response.Body)).ToList();
        var objects = await Task.WhenAll(readers.Select(r => r.ReadToEndAsync()));

        readers.ForEach(r => r.dispose());

        throw new NotImplementedException();
    }
}

现在,如果我在两个下游服务中都设置了一个断点,则在我致电"/api/services/{partnerId}?pageNo={pageNo}&pageSize={pageSize}"时会遇到断点。问题在于两个响应均为404(即使api网关控制台也记录了200 OK响应,这是正确的,因为两个断点都已命中,服务正在返回数据)。如果我检查传递给聚合器的HttpContext,则可以看到请求对象包含完全错误的地址。看起来好像Ocelot正确地调用了我的端点,但同时又调用了一些不存在的端点,并将它们的结果传递给了我的聚合器。有什么想法吗?

编辑:

我可以在HttpContext的Items属性内看到我的服务响应。该死,确实看起来像是库作者方面的一个严重错误,或者是设计使然?

解决方法

我遇到了同样的情况,您只需要更新您引用数据的方式。 数据实际上存在于 response[index].Items.DownstreamResponse().Content.

这是我所做的似乎有效的一个小例子。由于下游内容是压缩的,我有两个辅助函数可以解压缩并将内容转换为 Json 对象。

internal class DemoAggregator : IDefinedAggregator
    {
        public async Task<DownstreamResponse> Aggregate(List<HttpContext> responses)
        {
            List<Header> header = new List<Header>();
            try
            {
                var headers = responses.SelectMany(x => x.Items.DownstreamResponse().Headers).ToList();

                var oneByteArray = await responses[0].Items.DownstreamResponse().Content.ReadAsByteArrayAsync();
                var oneData = Decompress(oneByteArray);
                var oneObj = ConvertToJson(oneData);
                var oneContent = new StringContent(JsonConvert.SerializeObject(oneObj),Encoding.UTF8,"application/json");

                return new DownstreamResponse(oneContent,HttpStatusCode.OK,headers,"OK");
            }
            catch (Exception ex)
            {
                return new DownstreamResponse(null,System.Net.HttpStatusCode.InternalServerError,header,null);
            }
        }

        private static byte[] Decompress(byte[] data)
        {
            using (var compressedStream = new MemoryStream(data))
            using (var zipStream = new GZipStream(compressedStream,CompressionMode.Decompress))
            using (var resultStream = new MemoryStream())
            {
                zipStream.CopyTo(resultStream);
                return resultStream.ToArray();
            }
        }

        private static JObject ConvertToJson(byte[] data)
        {
            JObject jObj;
            using (var ms = new MemoryStream(data))
            using (var streamReader = new StreamReader(ms))
            using (var jsonReader = new JsonTextReader(streamReader))
            {
                jObj = (JObject)JToken.ReadFrom(jsonReader);
            }
            return jObj;
        }
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。