mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Ship call logs to the user as text/plain instead of JSON (#615)
* Ship call logs to the user as text/plain instead of JSON * Fixing swagger doc * c.String instead of c.JSON * Make Logs API backward compatible * Loop over accepted MIME types * Bump swagger API version * Fix client build script previous version was producing the following "couldn't find a swagger spec" * Logs API regression test * Write response body without buffering * Switch JSON and text/plain cases * Handle Accepted content types properly * More solid response content type handling * Write HTTP 406 with corresponding error body * Remove unused import * Use handleErrorResponse
This commit is contained in:
committed by
Reed Allman
parent
9e9cb136ed
commit
60d2ca234f
@@ -2,13 +2,33 @@ package server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"errors"
|
||||
"github.com/fnproject/fn/api"
|
||||
"github.com/fnproject/fn/api/models"
|
||||
"github.com/gin-gonic/gin"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// note: for backward compatibility, will go away later
|
||||
type callLogResponse struct {
|
||||
Message string `json:"message"`
|
||||
Log *models.CallLog `json:"log"`
|
||||
}
|
||||
|
||||
func writeJSON(c *gin.Context, callID, appName string, logReader io.Reader) {
|
||||
var b bytes.Buffer
|
||||
b.ReadFrom(logReader)
|
||||
c.JSON(http.StatusOK, callLogResponse{"Successfully loaded log",
|
||||
&models.CallLog{
|
||||
CallID: callID,
|
||||
AppName: appName,
|
||||
Log: b.String(),
|
||||
}})
|
||||
}
|
||||
|
||||
func (s *Server) handleCallLogGet(c *gin.Context) {
|
||||
ctx := c.Request.Context()
|
||||
|
||||
@@ -21,18 +41,30 @@ func (s *Server) handleCallLogGet(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO this API needs to change to text/plain / gzip anyway, punting
|
||||
// optimization, but we can write this direct to the wire, too... seems like
|
||||
// we should write some kind of writev json thing for go since we keep
|
||||
// hitting this :(
|
||||
var b bytes.Buffer
|
||||
b.ReadFrom(logReader)
|
||||
mimeTypes, _ := c.Request.Header["Accept"]
|
||||
|
||||
callObj := models.CallLog{
|
||||
CallID: callID,
|
||||
AppName: appName,
|
||||
Log: b.String(),
|
||||
if len(mimeTypes) == 0 {
|
||||
writeJSON(c, callID, appName, logReader)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, callLogResponse{"Successfully loaded log", &callObj})
|
||||
for _, mimeType := range mimeTypes {
|
||||
if strings.Contains(mimeType, "application/json") {
|
||||
writeJSON(c, callID, appName, logReader)
|
||||
return
|
||||
}
|
||||
if strings.Contains(mimeType, "text/plain") {
|
||||
io.Copy(c.Writer, logReader)
|
||||
return
|
||||
|
||||
}
|
||||
if strings.Contains(mimeType, "*/*") {
|
||||
writeJSON(c, callID, appName, logReader)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// if we've reached this point it means that Fn didn't recognize Accepted content type
|
||||
handleErrorResponse(c, models.NewAPIError(http.StatusNotAcceptable,
|
||||
errors.New("unable to respond within acceptable response content types")))
|
||||
}
|
||||
|
||||
@@ -524,8 +524,3 @@ type callsResponse struct {
|
||||
NextCursor string `json:"next_cursor"`
|
||||
Calls []*models.Call `json:"calls"`
|
||||
}
|
||||
|
||||
type callLogResponse struct {
|
||||
Message string `json:"message"`
|
||||
Log *models.CallLog `json:"log"`
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ languages.each do |l|
|
||||
destdir = "tmp/fn_#{lshort}"
|
||||
if l == 'go'
|
||||
# This is using https://goswagger.io/ instead
|
||||
stream_exec "docker run --rm -v ${PWD}/#{clone_dir}:/go/src/github.com/fnproject/fn_go -w /go/src/github.com/fnproject/fn_go quay.io/goswagger/swagger generate client -f #{swaggerUrl} -A fn "
|
||||
stream_exec "docker run --rm -v ${PWD}/#{clone_dir}:/go/src/github.com/fnproject/fn_go -v ${GOPATH}/src/github.com/fnproject/fn/docs/swagger.yml:/go/src/github.com/fnproject/fn/swagger.yml -w /go/src/github.com/fnproject/fn_go quay.io/goswagger/swagger generate client -f /go/src/github.com/fnproject/fn/swagger.yml -A fn "
|
||||
else
|
||||
gen = JSON.parse(HTTP.post("https://generator.swagger.io/api/gen/clients/#{l}",
|
||||
json: {
|
||||
|
||||
@@ -2,7 +2,7 @@ swagger: '2.0'
|
||||
info:
|
||||
title: fn
|
||||
description: The open source serverless platform.
|
||||
version: "0.2.2"
|
||||
version: "0.2.3"
|
||||
# the domain of the service
|
||||
host: "127.0.0.1:8080"
|
||||
# array of all schemes that your API supports
|
||||
@@ -371,6 +371,7 @@ paths:
|
||||
tags:
|
||||
- Call
|
||||
- Log
|
||||
produces: ['text/plain',]
|
||||
parameters:
|
||||
- name: app
|
||||
description: App Name
|
||||
@@ -386,7 +387,7 @@ paths:
|
||||
200:
|
||||
description: Log found
|
||||
schema:
|
||||
$ref: '#/definitions/LogWrapper'
|
||||
type: string
|
||||
404:
|
||||
description: Log not found.
|
||||
schema:
|
||||
@@ -636,25 +637,6 @@ definitions:
|
||||
$ref: '#/definitions/Call'
|
||||
description: "Call object."
|
||||
|
||||
|
||||
LogWrapper:
|
||||
type: object
|
||||
required:
|
||||
- log
|
||||
properties:
|
||||
log:
|
||||
$ref: '#/definitions/Log'
|
||||
description: "Call log entry."
|
||||
|
||||
Log:
|
||||
type: object
|
||||
properties:
|
||||
call_id:
|
||||
type: string
|
||||
description: Call UUID ID
|
||||
log:
|
||||
type: string # maybe bytes, long logs wouldn't fit into string type
|
||||
|
||||
Call:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user