Backend Plugins: Support handling of streaming resource response (#22580)

Use v0.19.0 of SDK.
Support handling of streaming resource response.
Disable gzip/compression middleware for resources 
to allow chunked/streaming response to clients the gzip
middleware had to be disabled since it buffers the full
response before sending it to the client.

Closes #22569

Co-Authored-By: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Marcus Efraimsson
2020-03-06 01:44:07 +07:00
committed by GitHub
co-authored by Arve Knudsen
parent f95c8b785c
commit 4ff613a432
17 changed files with 518 additions and 241 deletions
+15 -16
View File
@@ -72,7 +72,7 @@ func (p *BackendPlugin) start(ctx context.Context) error {
if rawBackend != nil {
if plugin, ok := rawBackend.(CorePlugin); ok {
p.core = plugin
client.DatasourcePlugin = plugin
client.CorePlugin = plugin
}
}
@@ -186,8 +186,8 @@ func (p *BackendPlugin) checkHealth(ctx context.Context) (*pluginv2.CheckHealth_
if st, ok := status.FromError(err); ok {
if st.Code() == codes.Unimplemented {
return &pluginv2.CheckHealth_Response{
Status: pluginv2.CheckHealth_Response_UNKNOWN,
Info: "Health check not implemented",
Status: pluginv2.CheckHealth_Response_UNKNOWN,
Message: "Health check not implemented",
}, nil
}
}
@@ -197,9 +197,13 @@ func (p *BackendPlugin) checkHealth(ctx context.Context) (*pluginv2.CheckHealth_
return res, nil
}
func (p *BackendPlugin) callResource(ctx context.Context, req CallResourceRequest) (*CallResourceResult, error) {
func (p *BackendPlugin) callResource(ctx context.Context, req CallResourceRequest) (callResourceResultStream, error) {
p.logger.Debug("Calling resource", "path", req.Path, "method", req.Method)
if p.core == nil || p.client == nil || p.client.Exited() {
return nil, errors.New("plugin not running, cannot call resource")
}
reqHeaders := map[string]*pluginv2.CallResource_StringList{}
for k, v := range req.Headers {
reqHeaders[k] = &pluginv2.CallResource_StringList{Values: v}
@@ -238,12 +242,14 @@ func (p *BackendPlugin) callResource(ctx context.Context, req CallResourceReques
}
}
protoResp, err := p.core.CallResource(ctx, protoReq)
protoStream, err := p.core.CallResource(ctx, protoReq)
if err != nil {
if st, ok := status.FromError(err); ok {
if st.Code() == codes.Unimplemented {
return &CallResourceResult{
Status: http.StatusNotImplemented,
return &singleCallResourceResult{
result: &CallResourceResult{
Status: http.StatusNotImplemented,
},
}, nil
}
}
@@ -251,15 +257,8 @@ func (p *BackendPlugin) callResource(ctx context.Context, req CallResourceReques
return nil, errutil.Wrap("Failed to call resource", err)
}
respHeaders := map[string][]string{}
for key, values := range protoResp.Headers {
respHeaders[key] = values.Values
}
return &CallResourceResult{
Headers: respHeaders,
Body: protoResp.Body,
Status: int(protoResp.Code),
return &callResourceResultStreamImpl{
stream: protoStream,
}, nil
}