如何解决使用高级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 举报,一经查实,本站将立刻删除。