Skip to content
Snippets Groups Projects
Commit b2bcbd05 authored by Lyuben Penkovski's avatar Lyuben Penkovski
Browse files

Merge branch '12-retrieve-task-result' into 'main'

HTTP endpoint to retreive task results

Closes #12

See merge request !7
parents 19ac326f 8bc0a3ec
No related branches found
No related tags found
1 merge request!7HTTP endpoint to retreive task results
Pipeline #50892 passed with stage
in 48 seconds
Showing
with 345 additions and 25 deletions
......@@ -90,7 +90,7 @@ func main() {
healthSvc goahealth.Service
)
{
taskSvc = task.New(storage, storage, logger)
taskSvc = task.New(storage, storage, cache, logger)
healthSvc = health.New()
}
......
......@@ -37,6 +37,16 @@ var _ = Service("task", func() {
Response(StatusOK)
})
})
Method("TaskResult", func() {
Description("TaskResult retrieves task result from the Cache service.")
Payload(TaskResultRequest)
Result(Any)
HTTP(func() {
GET("/v1/taskResult/{taskID}")
Response(StatusOK)
})
})
})
var _ = Service("health", func() {
......
......@@ -15,3 +15,8 @@ var CreateResult = Type("CreateResult", func() {
Field(1, "taskID", String, "Unique task identifier.")
Required("taskID")
})
var TaskResultRequest = Type("TaskResultRequest", func() {
Field(1, "taskID", String, "Unique task identifier.")
Required("taskID")
})
......@@ -25,14 +25,14 @@ import (
//
func UsageCommands() string {
return `health (liveness|readiness)
task create
task (create|task-result)
`
}
// UsageExamples produces an example of a valid invocation of the CLI tool.
func UsageExamples() string {
return os.Args[0] + ` health liveness` + "\n" +
os.Args[0] + ` task create --body "Nam et." --task-name "Minus reprehenderit non quo nihil adipisci." --cache-namespace "Pariatur sequi et." --cache-scope "Corrupti facere sequi tempora eius assumenda molestiae."` + "\n" +
os.Args[0] + ` task create --body "Eaque excepturi suscipit veritatis nemo." --task-name "Corrupti facere sequi tempora eius assumenda molestiae." --cache-namespace "Laborum sapiente." --cache-scope "Nam et."` + "\n" +
""
}
......@@ -59,6 +59,9 @@ func ParseEndpoint(
taskCreateTaskNameFlag = taskCreateFlags.String("task-name", "REQUIRED", "Task name.")
taskCreateCacheNamespaceFlag = taskCreateFlags.String("cache-namespace", "", "")
taskCreateCacheScopeFlag = taskCreateFlags.String("cache-scope", "", "")
taskTaskResultFlags = flag.NewFlagSet("task-result", flag.ExitOnError)
taskTaskResultTaskIDFlag = taskTaskResultFlags.String("task-id", "REQUIRED", "Unique task identifier.")
)
healthFlags.Usage = healthUsage
healthLivenessFlags.Usage = healthLivenessUsage
......@@ -66,6 +69,7 @@ func ParseEndpoint(
taskFlags.Usage = taskUsage
taskCreateFlags.Usage = taskCreateUsage
taskTaskResultFlags.Usage = taskTaskResultUsage
if err := flag.CommandLine.Parse(os.Args[1:]); err != nil {
return nil, nil, err
......@@ -116,6 +120,9 @@ func ParseEndpoint(
case "create":
epf = taskCreateFlags
case "task-result":
epf = taskTaskResultFlags
}
}
......@@ -154,6 +161,9 @@ func ParseEndpoint(
case "create":
endpoint = c.Create()
data, err = taskc.BuildCreatePayload(*taskCreateBodyFlag, *taskCreateTaskNameFlag, *taskCreateCacheNamespaceFlag, *taskCreateCacheScopeFlag)
case "task-result":
endpoint = c.TaskResult()
data, err = taskc.BuildTaskResultPayload(*taskTaskResultTaskIDFlag)
}
}
}
......@@ -206,6 +216,7 @@ Usage:
COMMAND:
create: Create a task and put it in a queue for execution.
task-result: TaskResult retrieves task result from the Cache service.
Additional help:
%[1]s task COMMAND --help
......@@ -221,6 +232,17 @@ Create a task and put it in a queue for execution.
-cache-scope STRING:
Example:
%[1]s task create --body "Nam et." --task-name "Minus reprehenderit non quo nihil adipisci." --cache-namespace "Pariatur sequi et." --cache-scope "Corrupti facere sequi tempora eius assumenda molestiae."
%[1]s task create --body "Eaque excepturi suscipit veritatis nemo." --task-name "Corrupti facere sequi tempora eius assumenda molestiae." --cache-namespace "Laborum sapiente." --cache-scope "Nam et."
`, os.Args[0])
}
func taskTaskResultUsage() {
fmt.Fprintf(os.Stderr, `%[1]s [flags] task task-result -task-id STRING
TaskResult retrieves task result from the Cache service.
-task-id STRING: Unique task identifier.
Example:
%[1]s task task-result --task-id "Et ipsa voluptate."
`, os.Args[0])
}
{"swagger":"2.0","info":{"title":"Task Service","description":"The task service is executing tasks created from policies.","version":""},"host":"localhost:8082","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/v1/task/{taskName}":{"post":{"tags":["task"],"summary":"Create task","description":"Create a task and put it in a queue for execution.","operationId":"task#Create","parameters":[{"name":"taskName","in":"path","description":"Task name.","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache key namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache key scope","required":false,"type":"string"},{"name":"any","in":"body","description":"Data contains JSON payload that will be used for task execution.","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/TaskCreateResponseBody","required":["taskID"]}}},"schemes":["http"]}}},"definitions":{"TaskCreateResponseBody":{"title":"TaskCreateResponseBody","type":"object","properties":{"taskID":{"type":"string","description":"Unique task identifier.","example":"Eaque excepturi suscipit veritatis nemo."}},"example":{"taskID":"Corrupti quia autem dolorum sunt aperiam quaerat."},"required":["taskID"]}}}
\ No newline at end of file
{"swagger":"2.0","info":{"title":"Task Service","description":"The task service is executing tasks created from policies.","version":""},"host":"localhost:8082","consumes":["application/json","application/xml","application/gob"],"produces":["application/json","application/xml","application/gob"],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}},"schemes":["http"]}},"/v1/task/{taskName}":{"post":{"tags":["task"],"summary":"Create task","description":"Create a task and put it in a queue for execution.","operationId":"task#Create","parameters":[{"name":"taskName","in":"path","description":"Task name.","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache key namespace","required":false,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache key scope","required":false,"type":"string"},{"name":"any","in":"body","description":"Data contains JSON payload that will be used for task execution.","required":true,"schema":{"type":"string","format":"binary"}}],"responses":{"200":{"description":"OK response.","schema":{"$ref":"#/definitions/TaskCreateResponseBody","required":["taskID"]}}},"schemes":["http"]}},"/v1/taskResult/{taskID}":{"get":{"tags":["task"],"summary":"TaskResult task","description":"TaskResult retrieves task result from the Cache service.","operationId":"task#TaskResult","parameters":[{"name":"taskID","in":"path","description":"Unique task identifier.","required":true,"type":"string"}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"binary"}}},"schemes":["http"]}}},"definitions":{"TaskCreateResponseBody":{"title":"TaskCreateResponseBody","type":"object","properties":{"taskID":{"type":"string","description":"Unique task identifier.","example":"Vel odio et doloribus est quod laborum."}},"example":{"taskID":"Harum aut autem aliquam dolorem non soluta."},"required":["taskID"]}}}
\ No newline at end of file
......@@ -74,6 +74,27 @@ paths:
- taskID
schemes:
- http
/v1/taskResult/{taskID}:
get:
tags:
- task
summary: TaskResult task
description: TaskResult retrieves task result from the Cache service.
operationId: task#TaskResult
parameters:
- name: taskID
in: path
description: Unique task identifier.
required: true
type: string
responses:
"200":
description: OK response.
schema:
type: string
format: binary
schemes:
- http
definitions:
TaskCreateResponseBody:
title: TaskCreateResponseBody
......@@ -82,8 +103,8 @@ definitions:
taskID:
type: string
description: Unique task identifier.
example: Eaque excepturi suscipit veritatis nemo.
example: Vel odio et doloribus est quod laborum.
example:
taskID: Corrupti quia autem dolorum sunt aperiam quaerat.
taskID: Harum aut autem aliquam dolorem non soluta.
required:
- taskID
{"openapi":"3.0.3","info":{"title":"Task Service","description":"The task service is executing tasks created from policies.","version":"1.0"},"servers":[{"url":"http://localhost:8082","description":"Task Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}},"/v1/task/{taskName}":{"post":{"tags":["task"],"summary":"Create task","description":"Create a task and put it in a queue for execution.","operationId":"task#Create","parameters":[{"name":"taskName","in":"path","description":"Task name.","required":true,"schema":{"type":"string","description":"Task name.","example":"Vel odio et doloribus est quod laborum."},"example":"Harum aut autem aliquam dolorem non soluta."},{"name":"x-cache-namespace","in":"header","description":"Cache key namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache key namespace","example":"login"},"example":"login"},{"name":"x-cache-scope","in":"header","description":"Cache key scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache key scope","example":"user"},"example":"user"}],"requestBody":{"description":"Data contains JSON payload that will be used for task execution.","required":true,"content":{"application/json":{"schema":{"type":"string","description":"Data contains JSON payload that will be used for task execution.","example":"Eveniet et eligendi sint quibusdam quia maxime.","format":"binary"},"example":"Ipsam et est accusantium."}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateResult"},"example":{"taskID":"Facere quibusdam voluptate beatae."}}}}}}}},"components":{"schemas":{"CreateResult":{"type":"object","properties":{"taskID":{"type":"string","description":"Unique task identifier.","example":"Et ipsa voluptate."}},"example":{"taskID":"Quo qui fuga impedit eos fuga et."},"required":["taskID"]}}},"tags":[{"name":"health","description":"Health service provides health check endpoints."},{"name":"task","description":"Task service provides endpoints to work with tasks."}]}
\ No newline at end of file
{"openapi":"3.0.3","info":{"title":"Task Service","description":"The task service is executing tasks created from policies.","version":"1.0"},"servers":[{"url":"http://localhost:8082","description":"Task Server"}],"paths":{"/liveness":{"get":{"tags":["health"],"summary":"Liveness health","operationId":"health#Liveness","responses":{"200":{"description":"OK response."}}}},"/readiness":{"get":{"tags":["health"],"summary":"Readiness health","operationId":"health#Readiness","responses":{"200":{"description":"OK response."}}}},"/v1/task/{taskName}":{"post":{"tags":["task"],"summary":"Create task","description":"Create a task and put it in a queue for execution.","operationId":"task#Create","parameters":[{"name":"taskName","in":"path","description":"Task name.","required":true,"schema":{"type":"string","description":"Task name.","example":"Aut qui aut itaque et commodi vel."},"example":"Sapiente et."},{"name":"x-cache-namespace","in":"header","description":"Cache key namespace","allowEmptyValue":true,"schema":{"type":"string","description":"Cache key namespace","example":"login"},"example":"login"},{"name":"x-cache-scope","in":"header","description":"Cache key scope","allowEmptyValue":true,"schema":{"type":"string","description":"Cache key scope","example":"user"},"example":"user"}],"requestBody":{"description":"Data contains JSON payload that will be used for task execution.","required":true,"content":{"application/json":{"schema":{"type":"string","description":"Data contains JSON payload that will be used for task execution.","example":"Excepturi aut consequatur animi rerum.","format":"binary"},"example":"Dolorem illo officiis ipsa impedit harum et."}}},"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateResult"},"example":{"taskID":"Corrupti quia autem dolorum sunt aperiam quaerat."}}}}}}},"/v1/taskResult/{taskID}":{"get":{"tags":["task"],"summary":"TaskResult task","description":"TaskResult retrieves task result from the Cache service.","operationId":"task#TaskResult","parameters":[{"name":"taskID","in":"path","description":"Unique task identifier.","required":true,"schema":{"type":"string","description":"Unique task identifier.","example":"Delectus natus eos."},"example":"Quae ut dolores ab."}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"Illum quidem sapiente sed velit.","format":"binary"},"example":"Omnis commodi reiciendis eum non."}}}}}}},"components":{"schemas":{"CreateResult":{"type":"object","properties":{"taskID":{"type":"string","description":"Unique task identifier.","example":"Dolores atque error ab."}},"example":{"taskID":"Laboriosam perspiciatis vitae numquam."},"required":["taskID"]}}},"tags":[{"name":"health","description":"Health service provides health check endpoints."},{"name":"task","description":"Task service provides endpoints to work with tasks."}]}
\ No newline at end of file
......@@ -40,8 +40,8 @@ paths:
schema:
type: string
description: Task name.
example: Vel odio et doloribus est quod laborum.
example: Harum aut autem aliquam dolorem non soluta.
example: Aut qui aut itaque et commodi vel.
example: Sapiente et.
- name: x-cache-namespace
in: header
description: Cache key namespace
......@@ -68,9 +68,9 @@ paths:
schema:
type: string
description: Data contains JSON payload that will be used for task execution.
example: Eveniet et eligendi sint quibusdam quia maxime.
example: Excepturi aut consequatur animi rerum.
format: binary
example: Ipsam et est accusantium.
example: Dolorem illo officiis ipsa impedit harum et.
responses:
"200":
description: OK response.
......@@ -79,7 +79,34 @@ paths:
schema:
$ref: '#/components/schemas/CreateResult'
example:
taskID: Facere quibusdam voluptate beatae.
taskID: Corrupti quia autem dolorum sunt aperiam quaerat.
/v1/taskResult/{taskID}:
get:
tags:
- task
summary: TaskResult task
description: TaskResult retrieves task result from the Cache service.
operationId: task#TaskResult
parameters:
- name: taskID
in: path
description: Unique task identifier.
required: true
schema:
type: string
description: Unique task identifier.
example: Delectus natus eos.
example: Quae ut dolores ab.
responses:
"200":
description: OK response.
content:
application/json:
schema:
type: string
example: Illum quidem sapiente sed velit.
format: binary
example: Omnis commodi reiciendis eum non.
components:
schemas:
CreateResult:
......@@ -88,9 +115,9 @@ components:
taskID:
type: string
description: Unique task identifier.
example: Et ipsa voluptate.
example: Dolores atque error ab.
example:
taskID: Quo qui fuga impedit eos fuga et.
taskID: Laboriosam perspiciatis vitae numquam.
required:
- taskID
tags:
......
......@@ -22,7 +22,7 @@ func BuildCreatePayload(taskCreateBody string, taskCreateTaskName string, taskCr
{
err = json.Unmarshal([]byte(taskCreateBody), &body)
if err != nil {
return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Nam et.\"")
return nil, fmt.Errorf("invalid JSON for body, \nerror: %s, \nexample of valid JSON:\n%s", err, "\"Eaque excepturi suscipit veritatis nemo.\"")
}
}
var taskName string
......@@ -51,3 +51,16 @@ func BuildCreatePayload(taskCreateBody string, taskCreateTaskName string, taskCr
return res, nil
}
// BuildTaskResultPayload builds the payload for the task TaskResult endpoint
// from CLI flags.
func BuildTaskResultPayload(taskTaskResultTaskID string) (*task.TaskResultRequest, error) {
var taskID string
{
taskID = taskTaskResultTaskID
}
v := &task.TaskResultRequest{}
v.TaskID = taskID
return v, nil
}
......@@ -20,6 +20,10 @@ type Client struct {
// Create Doer is the HTTP client used to make requests to the Create endpoint.
CreateDoer goahttp.Doer
// TaskResult Doer is the HTTP client used to make requests to the TaskResult
// endpoint.
TaskResultDoer goahttp.Doer
// RestoreResponseBody controls whether the response bodies are reset after
// decoding so they can be read again.
RestoreResponseBody bool
......@@ -41,6 +45,7 @@ func NewClient(
) *Client {
return &Client{
CreateDoer: doer,
TaskResultDoer: doer,
RestoreResponseBody: restoreBody,
scheme: scheme,
host: host,
......@@ -72,3 +77,22 @@ func (c *Client) Create() goa.Endpoint {
return decodeResponse(resp)
}
}
// TaskResult returns an endpoint that makes HTTP requests to the task service
// TaskResult server.
func (c *Client) TaskResult() goa.Endpoint {
var (
decodeResponse = DecodeTaskResultResponse(c.decoder, c.RestoreResponseBody)
)
return func(ctx context.Context, v interface{}) (interface{}, error) {
req, err := c.BuildTaskResultRequest(ctx, v)
if err != nil {
return nil, err
}
resp, err := c.TaskResultDoer.Do(req)
if err != nil {
return nil, goahttp.ErrRequestError("task", "TaskResult", err)
}
return decodeResponse(resp)
}
}
......@@ -106,3 +106,63 @@ func DecodeCreateResponse(decoder func(*http.Response) goahttp.Decoder, restoreB
}
}
}
// BuildTaskResultRequest instantiates a HTTP request object with method and
// path set to call the "task" service "TaskResult" endpoint
func (c *Client) BuildTaskResultRequest(ctx context.Context, v interface{}) (*http.Request, error) {
var (
taskID string
)
{
p, ok := v.(*task.TaskResultRequest)
if !ok {
return nil, goahttp.ErrInvalidType("task", "TaskResult", "*task.TaskResultRequest", v)
}
taskID = p.TaskID
}
u := &url.URL{Scheme: c.scheme, Host: c.host, Path: TaskResultTaskPath(taskID)}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, goahttp.ErrInvalidURL("task", "TaskResult", u.String(), err)
}
if ctx != nil {
req = req.WithContext(ctx)
}
return req, nil
}
// DecodeTaskResultResponse returns a decoder for responses returned by the
// task TaskResult endpoint. restoreBody controls whether the response body
// should be restored after having been read.
func DecodeTaskResultResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (interface{}, error) {
return func(resp *http.Response) (interface{}, error) {
if restoreBody {
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
defer func() {
resp.Body = ioutil.NopCloser(bytes.NewBuffer(b))
}()
} else {
defer resp.Body.Close()
}
switch resp.StatusCode {
case http.StatusOK:
var (
body interface{}
err error
)
err = decoder(resp).Decode(&body)
if err != nil {
return nil, goahttp.ErrDecodingError("task", "TaskResult", err)
}
return body, nil
default:
body, _ := ioutil.ReadAll(resp.Body)
return nil, goahttp.ErrInvalidResponse("task", "TaskResult", resp.StatusCode, string(body))
}
}
}
......@@ -15,3 +15,8 @@ import (
func CreateTaskPath(taskName string) string {
return fmt.Sprintf("/v1/task/%v", taskName)
}
// TaskResultTaskPath returns the URL path to the task service TaskResult HTTP endpoint.
func TaskResultTaskPath(taskID string) string {
return fmt.Sprintf("/v1/taskResult/%v", taskID)
}
......@@ -66,3 +66,31 @@ func DecodeCreateRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.
return payload, nil
}
}
// EncodeTaskResultResponse returns an encoder for responses returned by the
// task TaskResult endpoint.
func EncodeTaskResultResponse(encoder func(context.Context, http.ResponseWriter) goahttp.Encoder) func(context.Context, http.ResponseWriter, interface{}) error {
return func(ctx context.Context, w http.ResponseWriter, v interface{}) error {
res, _ := v.(interface{})
enc := encoder(ctx, w)
body := res
w.WriteHeader(http.StatusOK)
return enc.Encode(body)
}
}
// DecodeTaskResultRequest returns a decoder for requests sent to the task
// TaskResult endpoint.
func DecodeTaskResultRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (interface{}, error) {
return func(r *http.Request) (interface{}, error) {
var (
taskID string
params = mux.Vars(r)
)
taskID = params["taskID"]
payload := NewTaskResultRequest(taskID)
return payload, nil
}
}
......@@ -15,3 +15,8 @@ import (
func CreateTaskPath(taskName string) string {
return fmt.Sprintf("/v1/task/%v", taskName)
}
// TaskResultTaskPath returns the URL path to the task service TaskResult HTTP endpoint.
func TaskResultTaskPath(taskID string) string {
return fmt.Sprintf("/v1/taskResult/%v", taskID)
}
......@@ -18,8 +18,9 @@ import (
// Server lists the task service endpoint HTTP handlers.
type Server struct {
Mounts []*MountPoint
Create http.Handler
Mounts []*MountPoint
Create http.Handler
TaskResult http.Handler
}
// ErrorNamer is an interface implemented by generated error structs that
......@@ -56,8 +57,10 @@ func New(
return &Server{
Mounts: []*MountPoint{
{"Create", "POST", "/v1/task/{taskName}"},
{"TaskResult", "GET", "/v1/taskResult/{taskID}"},
},
Create: NewCreateHandler(e.Create, mux, decoder, encoder, errhandler, formatter),
Create: NewCreateHandler(e.Create, mux, decoder, encoder, errhandler, formatter),
TaskResult: NewTaskResultHandler(e.TaskResult, mux, decoder, encoder, errhandler, formatter),
}
}
......@@ -67,11 +70,13 @@ func (s *Server) Service() string { return "task" }
// Use wraps the server handlers with the given middleware.
func (s *Server) Use(m func(http.Handler) http.Handler) {
s.Create = m(s.Create)
s.TaskResult = m(s.TaskResult)
}
// Mount configures the mux to serve the task endpoints.
func Mount(mux goahttp.Muxer, h *Server) {
MountCreateHandler(mux, h.Create)
MountTaskResultHandler(mux, h.TaskResult)
}
// Mount configures the mux to serve the task endpoints.
......@@ -129,3 +134,54 @@ func NewCreateHandler(
}
})
}
// MountTaskResultHandler configures the mux to serve the "task" service
// "TaskResult" endpoint.
func MountTaskResultHandler(mux goahttp.Muxer, h http.Handler) {
f, ok := h.(http.HandlerFunc)
if !ok {
f = func(w http.ResponseWriter, r *http.Request) {
h.ServeHTTP(w, r)
}
}
mux.Handle("GET", "/v1/taskResult/{taskID}", f)
}
// NewTaskResultHandler creates a HTTP handler which loads the HTTP request and
// calls the "task" service "TaskResult" endpoint.
func NewTaskResultHandler(
endpoint goa.Endpoint,
mux goahttp.Muxer,
decoder func(*http.Request) goahttp.Decoder,
encoder func(context.Context, http.ResponseWriter) goahttp.Encoder,
errhandler func(context.Context, http.ResponseWriter, error),
formatter func(err error) goahttp.Statuser,
) http.Handler {
var (
decodeRequest = DecodeTaskResultRequest(mux, decoder)
encodeResponse = EncodeTaskResultResponse(encoder)
encodeError = goahttp.ErrorEncoder(encoder, formatter)
)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue(r.Context(), goahttp.AcceptTypeKey, r.Header.Get("Accept"))
ctx = context.WithValue(ctx, goa.MethodKey, "TaskResult")
ctx = context.WithValue(ctx, goa.ServiceKey, "task")
payload, err := decodeRequest(r)
if err != nil {
if err := encodeError(ctx, w, err); err != nil {
errhandler(ctx, w, err)
}
return
}
res, err := endpoint(ctx, payload)
if err != nil {
if err := encodeError(ctx, w, err); err != nil {
errhandler(ctx, w, err)
}
return
}
if err := encodeResponse(ctx, w, res); err != nil {
errhandler(ctx, w, err)
}
})
}
......@@ -39,3 +39,11 @@ func NewCreateRequest(body interface{}, taskName string, cacheNamespace *string,
return res
}
// NewTaskResultRequest builds a task service TaskResult endpoint payload.
func NewTaskResultRequest(taskID string) *task.TaskResultRequest {
v := &task.TaskResultRequest{}
v.TaskID = taskID
return v
}
......@@ -15,13 +15,15 @@ import (
// Client is the "task" service client.
type Client struct {
CreateEndpoint goa.Endpoint
CreateEndpoint goa.Endpoint
TaskResultEndpoint goa.Endpoint
}
// NewClient initializes a "task" service client given the endpoints.
func NewClient(create goa.Endpoint) *Client {
func NewClient(create, taskResult goa.Endpoint) *Client {
return &Client{
CreateEndpoint: create,
CreateEndpoint: create,
TaskResultEndpoint: taskResult,
}
}
......@@ -34,3 +36,13 @@ func (c *Client) Create(ctx context.Context, p *CreateRequest) (res *CreateResul
}
return ires.(*CreateResult), nil
}
// TaskResult calls the "TaskResult" endpoint of the "task" service.
func (c *Client) TaskResult(ctx context.Context, p *TaskResultRequest) (res interface{}, err error) {
var ires interface{}
ires, err = c.TaskResultEndpoint(ctx, p)
if err != nil {
return
}
return ires.(interface{}), nil
}
......@@ -15,19 +15,22 @@ import (
// Endpoints wraps the "task" service endpoints.
type Endpoints struct {
Create goa.Endpoint
Create goa.Endpoint
TaskResult goa.Endpoint
}
// NewEndpoints wraps the methods of the "task" service with endpoints.
func NewEndpoints(s Service) *Endpoints {
return &Endpoints{
Create: NewCreateEndpoint(s),
Create: NewCreateEndpoint(s),
TaskResult: NewTaskResultEndpoint(s),
}
}
// Use applies the given middleware to all the "task" service endpoints.
func (e *Endpoints) Use(m func(goa.Endpoint) goa.Endpoint) {
e.Create = m(e.Create)
e.TaskResult = m(e.TaskResult)
}
// NewCreateEndpoint returns an endpoint function that calls the method
......@@ -38,3 +41,12 @@ func NewCreateEndpoint(s Service) goa.Endpoint {
return s.Create(ctx, p)
}
}
// NewTaskResultEndpoint returns an endpoint function that calls the method
// "TaskResult" of service "task".
func NewTaskResultEndpoint(s Service) goa.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
p := req.(*TaskResultRequest)
return s.TaskResult(ctx, p)
}
}
......@@ -15,6 +15,8 @@ import (
type Service interface {
// Create a task and put it in a queue for execution.
Create(context.Context, *CreateRequest) (res *CreateResult, err error)
// TaskResult retrieves task result from the Cache service.
TaskResult(context.Context, *TaskResultRequest) (res interface{}, err error)
}
// ServiceName is the name of the service as defined in the design. This is the
......@@ -25,7 +27,7 @@ const ServiceName = "task"
// MethodNames lists the service method names as defined in the design. These
// are the same values that are set in the endpoint request contexts under the
// MethodKey key.
var MethodNames = [1]string{"Create"}
var MethodNames = [2]string{"Create", "TaskResult"}
// CreateRequest is the payload type of the task service Create method.
type CreateRequest struct {
......@@ -44,3 +46,9 @@ type CreateResult struct {
// Unique task identifier.
TaskID string
}
// TaskResultRequest is the payload type of the task service TaskResult method.
type TaskResultRequest struct {
// Unique task identifier.
TaskID string
}
......@@ -7,6 +7,7 @@ require (
github.com/cenkalti/backoff/v4 v4.1.3
github.com/google/uuid v1.3.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/stretchr/testify v1.7.0
go.mongodb.org/mongo-driver v1.8.4
go.uber.org/zap v1.21.0
goa.design/goa/v3 v3.7.0
......@@ -14,6 +15,7 @@ require (
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 // indirect
github.com/dimfeld/httptreemux/v5 v5.4.0 // indirect
github.com/go-stack/stack v1.8.0 // indirect
......@@ -25,6 +27,7 @@ require (
github.com/klauspost/compress v1.13.6 // indirect
github.com/manveru/faker v0.0.0-20171103152722-9fbc68a78c4d // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/smartystreets/assertions v1.2.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
......@@ -41,4 +44,5 @@ require (
golang.org/x/tools v0.1.10 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment