Skip to content
Snippets Groups Projects
Commit 6924e7b5 authored by Yordan Kinkov's avatar Yordan Kinkov
Browse files

Merge branch '2-implement-cache-get-endpoint' into 'main'

Resolve "Create cache GET endpoint"

Closes #2

See merge request !2
parents 20e3225f 6a32695f
Branches
Tags
1 merge request!2Resolve "Create cache GET endpoint"
Pipeline #49748 passed
Showing
with 854 additions and 5 deletions
...@@ -14,12 +14,16 @@ import ( ...@@ -14,12 +14,16 @@ import (
goa "goa.design/goa/v3/pkg" goa "goa.design/goa/v3/pkg"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
goacache "code.vereign.com/gaiax/tsa/cache/gen/cache"
goahealth "code.vereign.com/gaiax/tsa/cache/gen/health" goahealth "code.vereign.com/gaiax/tsa/cache/gen/health"
goacachesrv "code.vereign.com/gaiax/tsa/cache/gen/http/cache/server"
goahealthsrv "code.vereign.com/gaiax/tsa/cache/gen/http/health/server" goahealthsrv "code.vereign.com/gaiax/tsa/cache/gen/http/health/server"
goaopenapisrv "code.vereign.com/gaiax/tsa/cache/gen/http/openapi/server" goaopenapisrv "code.vereign.com/gaiax/tsa/cache/gen/http/openapi/server"
"code.vereign.com/gaiax/tsa/cache/gen/openapi" "code.vereign.com/gaiax/tsa/cache/gen/openapi"
"code.vereign.com/gaiax/tsa/cache/internal/clients/redis"
"code.vereign.com/gaiax/tsa/cache/internal/config" "code.vereign.com/gaiax/tsa/cache/internal/config"
"code.vereign.com/gaiax/tsa/cache/internal/service" "code.vereign.com/gaiax/tsa/cache/internal/service"
"code.vereign.com/gaiax/tsa/cache/internal/service/cache"
"code.vereign.com/gaiax/tsa/cache/internal/service/health" "code.vereign.com/gaiax/tsa/cache/internal/service/health"
"code.vereign.com/gaiax/tsa/golib/graceful" "code.vereign.com/gaiax/tsa/golib/graceful"
) )
...@@ -40,20 +44,27 @@ func main() { ...@@ -40,20 +44,27 @@ func main() {
logger.Info("start cache service", zap.String("version", Version), zap.String("goa", goa.Version())) logger.Info("start cache service", zap.String("version", Version), zap.String("goa", goa.Version()))
// create redis client
redis := redis.New(cfg.Redis.Addr, cfg.Redis.User, cfg.Redis.Pass, cfg.Redis.DB, cfg.Redis.TTL)
// create services // create services
var ( var (
cacheSvc goacache.Service
healthSvc goahealth.Service healthSvc goahealth.Service
) )
{ {
cacheSvc = cache.New(redis, logger)
healthSvc = health.New() healthSvc = health.New()
} }
// create endpoints // create endpoints
var ( var (
cacheEndpoints *goacache.Endpoints
healthEndpoints *goahealth.Endpoints healthEndpoints *goahealth.Endpoints
openapiEndpoints *openapi.Endpoints openapiEndpoints *openapi.Endpoints
) )
{ {
cacheEndpoints = goacache.NewEndpoints(cacheSvc)
healthEndpoints = goahealth.NewEndpoints(healthSvc) healthEndpoints = goahealth.NewEndpoints(healthSvc)
openapiEndpoints = openapi.NewEndpoints(nil) openapiEndpoints = openapi.NewEndpoints(nil)
} }
...@@ -72,15 +83,18 @@ func main() { ...@@ -72,15 +83,18 @@ func main() {
mux := goahttp.NewMuxer() mux := goahttp.NewMuxer()
var ( var (
cacheServer *goacachesrv.Server
healthServer *goahealthsrv.Server healthServer *goahealthsrv.Server
openapiServer *goaopenapisrv.Server openapiServer *goaopenapisrv.Server
) )
{ {
cacheServer = goacachesrv.New(cacheEndpoints, mux, dec, enc, nil, errFormatter)
healthServer = goahealthsrv.New(healthEndpoints, mux, dec, enc, nil, errFormatter) healthServer = goahealthsrv.New(healthEndpoints, mux, dec, enc, nil, errFormatter)
openapiServer = goaopenapisrv.New(openapiEndpoints, mux, dec, enc, nil, errFormatter, nil, nil) openapiServer = goaopenapisrv.New(openapiEndpoints, mux, dec, enc, nil, errFormatter, nil, nil)
} }
// Configure the mux. // Configure the mux.
goacachesrv.Mount(mux, cacheServer)
goahealthsrv.Mount(mux, healthServer) goahealthsrv.Mount(mux, healthServer)
goaopenapisrv.Mount(mux, openapiServer) goaopenapisrv.Mount(mux, openapiServer)
......
...@@ -10,7 +10,7 @@ var _ = API("cache", func() { ...@@ -10,7 +10,7 @@ var _ = API("cache", func() {
Description("Cache Server") Description("Cache Server")
Host("development", func() { Host("development", func() {
Description("Local development server") Description("Local development server")
URI("http://localhost:8080") URI("http://localhost:8083")
}) })
}) })
}) })
...@@ -37,6 +37,33 @@ var _ = Service("health", func() { ...@@ -37,6 +37,33 @@ var _ = Service("health", func() {
}) })
}) })
var _ = Service("cache", func() {
Description("Cache service allows storing and retrieving data from distributed cache.")
Method("Get", func() {
Description("Get value from the cache. The result is a sequence of bytes which the client must decode.")
Payload(CacheGetRequest)
Result(Bytes)
HTTP(func() {
GET("/v1/cache")
Header("key:x-cache-key", String, "Cache entry key", func() {
Example("did:web:example.com")
})
Header("namespace:x-cache-namespace", String, "Cache entry namespace", func() {
Example("Login")
})
Header("scope:x-cache-scope", String, "Cache entry scope", func() {
Example("administration")
})
Response(StatusOK)
})
})
})
var _ = Service("openapi", func() { var _ = Service("openapi", func() {
Description("The openapi service serves the OpenAPI(v3) definition.") Description("The openapi service serves the OpenAPI(v3) definition.")
Meta("swagger:generate", "false") Meta("swagger:generate", "false")
......
// nolint:revive
package design
import . "goa.design/goa/v3/dsl"
var CacheGetRequest = Type("CacheGetRequest", func() {
Field(1, "key", String)
Field(2, "namespace", String)
Field(3, "scope", String) // Initial implementation with a single scope
Required("key", "namespace", "scope")
})
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache client
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package cache
import (
"context"
goa "goa.design/goa/v3/pkg"
)
// Client is the "cache" service client.
type Client struct {
GetEndpoint goa.Endpoint
}
// NewClient initializes a "cache" service client given the endpoints.
func NewClient(get goa.Endpoint) *Client {
return &Client{
GetEndpoint: get,
}
}
// Get calls the "Get" endpoint of the "cache" service.
func (c *Client) Get(ctx context.Context, p *CacheGetRequest) (res []byte, err error) {
var ires interface{}
ires, err = c.GetEndpoint(ctx, p)
if err != nil {
return
}
return ires.([]byte), nil
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache endpoints
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package cache
import (
"context"
goa "goa.design/goa/v3/pkg"
)
// Endpoints wraps the "cache" service endpoints.
type Endpoints struct {
Get goa.Endpoint
}
// NewEndpoints wraps the methods of the "cache" service with endpoints.
func NewEndpoints(s Service) *Endpoints {
return &Endpoints{
Get: NewGetEndpoint(s),
}
}
// Use applies the given middleware to all the "cache" service endpoints.
func (e *Endpoints) Use(m func(goa.Endpoint) goa.Endpoint) {
e.Get = m(e.Get)
}
// NewGetEndpoint returns an endpoint function that calls the method "Get" of
// service "cache".
func NewGetEndpoint(s Service) goa.Endpoint {
return func(ctx context.Context, req interface{}) (interface{}, error) {
p := req.(*CacheGetRequest)
return s.Get(ctx, p)
}
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache service
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package cache
import (
"context"
)
// Cache service allows storing and retrieving data from distributed cache.
type Service interface {
// Get value from the cache. The result is a sequence of bytes which the client
// must decode.
Get(context.Context, *CacheGetRequest) (res []byte, err error)
}
// ServiceName is the name of the service as defined in the design. This is the
// same value that is set in the endpoint request contexts under the ServiceKey
// key.
const ServiceName = "cache"
// 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{"Get"}
// CacheGetRequest is the payload type of the cache service Get method.
type CacheGetRequest struct {
Key string
Namespace string
Scope string
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache HTTP client CLI support package
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package client
import (
cache "code.vereign.com/gaiax/tsa/cache/gen/cache"
)
// BuildGetPayload builds the payload for the cache Get endpoint from CLI flags.
func BuildGetPayload(cacheGetKey string, cacheGetNamespace string, cacheGetScope string) (*cache.CacheGetRequest, error) {
var key string
{
key = cacheGetKey
}
var namespace string
{
namespace = cacheGetNamespace
}
var scope string
{
scope = cacheGetScope
}
v := &cache.CacheGetRequest{}
v.Key = key
v.Namespace = namespace
v.Scope = scope
return v, nil
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache client HTTP transport
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package client
import (
"context"
"net/http"
goahttp "goa.design/goa/v3/http"
goa "goa.design/goa/v3/pkg"
)
// Client lists the cache service endpoint HTTP clients.
type Client struct {
// Get Doer is the HTTP client used to make requests to the Get endpoint.
GetDoer goahttp.Doer
// RestoreResponseBody controls whether the response bodies are reset after
// decoding so they can be read again.
RestoreResponseBody bool
scheme string
host string
encoder func(*http.Request) goahttp.Encoder
decoder func(*http.Response) goahttp.Decoder
}
// NewClient instantiates HTTP clients for all the cache service servers.
func NewClient(
scheme string,
host string,
doer goahttp.Doer,
enc func(*http.Request) goahttp.Encoder,
dec func(*http.Response) goahttp.Decoder,
restoreBody bool,
) *Client {
return &Client{
GetDoer: doer,
RestoreResponseBody: restoreBody,
scheme: scheme,
host: host,
decoder: dec,
encoder: enc,
}
}
// Get returns an endpoint that makes HTTP requests to the cache service Get
// server.
func (c *Client) Get() goa.Endpoint {
var (
encodeRequest = EncodeGetRequest(c.encoder)
decodeResponse = DecodeGetResponse(c.decoder, c.RestoreResponseBody)
)
return func(ctx context.Context, v interface{}) (interface{}, error) {
req, err := c.BuildGetRequest(ctx, v)
if err != nil {
return nil, err
}
err = encodeRequest(req, v)
if err != nil {
return nil, err
}
resp, err := c.GetDoer.Do(req)
if err != nil {
return nil, goahttp.ErrRequestError("cache", "Get", err)
}
return decodeResponse(resp)
}
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache HTTP client encoders and decoders
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package client
import (
"bytes"
"context"
"io/ioutil"
"net/http"
"net/url"
cache "code.vereign.com/gaiax/tsa/cache/gen/cache"
goahttp "goa.design/goa/v3/http"
)
// BuildGetRequest instantiates a HTTP request object with method and path set
// to call the "cache" service "Get" endpoint
func (c *Client) BuildGetRequest(ctx context.Context, v interface{}) (*http.Request, error) {
u := &url.URL{Scheme: c.scheme, Host: c.host, Path: GetCachePath()}
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, goahttp.ErrInvalidURL("cache", "Get", u.String(), err)
}
if ctx != nil {
req = req.WithContext(ctx)
}
return req, nil
}
// EncodeGetRequest returns an encoder for requests sent to the cache Get
// server.
func EncodeGetRequest(encoder func(*http.Request) goahttp.Encoder) func(*http.Request, interface{}) error {
return func(req *http.Request, v interface{}) error {
p, ok := v.(*cache.CacheGetRequest)
if !ok {
return goahttp.ErrInvalidType("cache", "Get", "*cache.CacheGetRequest", v)
}
{
head := p.Key
req.Header.Set("x-cache-key", head)
}
{
head := p.Namespace
req.Header.Set("x-cache-namespace", head)
}
{
head := p.Scope
req.Header.Set("x-cache-scope", head)
}
return nil
}
}
// DecodeGetResponse returns a decoder for responses returned by the cache Get
// endpoint. restoreBody controls whether the response body should be restored
// after having been read.
func DecodeGetResponse(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 []byte
err error
)
err = decoder(resp).Decode(&body)
if err != nil {
return nil, goahttp.ErrDecodingError("cache", "Get", err)
}
return body, nil
default:
body, _ := ioutil.ReadAll(resp.Body)
return nil, goahttp.ErrInvalidResponse("cache", "Get", resp.StatusCode, string(body))
}
}
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// HTTP request path constructors for the cache service.
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package client
// GetCachePath returns the URL path to the cache service Get HTTP endpoint.
func GetCachePath() string {
return "/v1/cache"
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache HTTP client types
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package client
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache HTTP server encoders and decoders
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package server
import (
"context"
"net/http"
goahttp "goa.design/goa/v3/http"
goa "goa.design/goa/v3/pkg"
)
// EncodeGetResponse returns an encoder for responses returned by the cache Get
// endpoint.
func EncodeGetResponse(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.([]byte)
enc := encoder(ctx, w)
body := res
w.WriteHeader(http.StatusOK)
return enc.Encode(body)
}
}
// DecodeGetRequest returns a decoder for requests sent to the cache Get
// endpoint.
func DecodeGetRequest(mux goahttp.Muxer, decoder func(*http.Request) goahttp.Decoder) func(*http.Request) (interface{}, error) {
return func(r *http.Request) (interface{}, error) {
var (
key string
namespace string
scope string
err error
)
key = r.Header.Get("x-cache-key")
if key == "" {
err = goa.MergeErrors(err, goa.MissingFieldError("x-cache-key", "header"))
}
namespace = r.Header.Get("x-cache-namespace")
if namespace == "" {
err = goa.MergeErrors(err, goa.MissingFieldError("x-cache-namespace", "header"))
}
scope = r.Header.Get("x-cache-scope")
if scope == "" {
err = goa.MergeErrors(err, goa.MissingFieldError("x-cache-scope", "header"))
}
if err != nil {
return nil, err
}
payload := NewGetCacheGetRequest(key, namespace, scope)
return payload, nil
}
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// HTTP request path constructors for the cache service.
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package server
// GetCachePath returns the URL path to the cache service Get HTTP endpoint.
func GetCachePath() string {
return "/v1/cache"
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache HTTP server
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package server
import (
"context"
"net/http"
cache "code.vereign.com/gaiax/tsa/cache/gen/cache"
goahttp "goa.design/goa/v3/http"
goa "goa.design/goa/v3/pkg"
)
// Server lists the cache service endpoint HTTP handlers.
type Server struct {
Mounts []*MountPoint
Get http.Handler
}
// ErrorNamer is an interface implemented by generated error structs that
// exposes the name of the error as defined in the design.
type ErrorNamer interface {
ErrorName() string
}
// MountPoint holds information about the mounted endpoints.
type MountPoint struct {
// Method is the name of the service method served by the mounted HTTP handler.
Method string
// Verb is the HTTP method used to match requests to the mounted handler.
Verb string
// Pattern is the HTTP request path pattern used to match requests to the
// mounted handler.
Pattern string
}
// New instantiates HTTP handlers for all the cache service endpoints using the
// provided encoder and decoder. The handlers are mounted on the given mux
// using the HTTP verb and path defined in the design. errhandler is called
// whenever a response fails to be encoded. formatter is used to format errors
// returned by the service methods prior to encoding. Both errhandler and
// formatter are optional and can be nil.
func New(
e *cache.Endpoints,
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,
) *Server {
return &Server{
Mounts: []*MountPoint{
{"Get", "GET", "/v1/cache"},
},
Get: NewGetHandler(e.Get, mux, decoder, encoder, errhandler, formatter),
}
}
// Service returns the name of the service served.
func (s *Server) Service() string { return "cache" }
// Use wraps the server handlers with the given middleware.
func (s *Server) Use(m func(http.Handler) http.Handler) {
s.Get = m(s.Get)
}
// Mount configures the mux to serve the cache endpoints.
func Mount(mux goahttp.Muxer, h *Server) {
MountGetHandler(mux, h.Get)
}
// Mount configures the mux to serve the cache endpoints.
func (s *Server) Mount(mux goahttp.Muxer) {
Mount(mux, s)
}
// MountGetHandler configures the mux to serve the "cache" service "Get"
// endpoint.
func MountGetHandler(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/cache", f)
}
// NewGetHandler creates a HTTP handler which loads the HTTP request and calls
// the "cache" service "Get" endpoint.
func NewGetHandler(
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 = DecodeGetRequest(mux, decoder)
encodeResponse = EncodeGetResponse(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, "Get")
ctx = context.WithValue(ctx, goa.ServiceKey, "cache")
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)
}
})
}
// Code generated by goa v3.7.0, DO NOT EDIT.
//
// cache HTTP server types
//
// Command:
// $ goa gen code.vereign.com/gaiax/tsa/cache/design
package server
import (
cache "code.vereign.com/gaiax/tsa/cache/gen/cache"
)
// NewGetCacheGetRequest builds a cache service Get endpoint payload.
func NewGetCacheGetRequest(key string, namespace string, scope string) *cache.CacheGetRequest {
v := &cache.CacheGetRequest{}
v.Key = key
v.Namespace = namespace
v.Scope = scope
return v
}
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"net/http" "net/http"
"os" "os"
cachec "code.vereign.com/gaiax/tsa/cache/gen/http/cache/client"
healthc "code.vereign.com/gaiax/tsa/cache/gen/http/health/client" healthc "code.vereign.com/gaiax/tsa/cache/gen/http/health/client"
goahttp "goa.design/goa/v3/http" goahttp "goa.design/goa/v3/http"
goa "goa.design/goa/v3/pkg" goa "goa.design/goa/v3/pkg"
...@@ -24,12 +25,14 @@ import ( ...@@ -24,12 +25,14 @@ import (
// //
func UsageCommands() string { func UsageCommands() string {
return `health (liveness|readiness) return `health (liveness|readiness)
cache get
` `
} }
// UsageExamples produces an example of a valid invocation of the CLI tool. // UsageExamples produces an example of a valid invocation of the CLI tool.
func UsageExamples() string { func UsageExamples() string {
return os.Args[0] + ` health liveness` + "\n" + return os.Args[0] + ` health liveness` + "\n" +
os.Args[0] + ` cache get --key "Officiis fuga architecto cum." --namespace "Sint adipisci." --scope "Debitis id reprehenderit incidunt necessitatibus assumenda."` + "\n" +
"" ""
} }
...@@ -48,11 +51,21 @@ func ParseEndpoint( ...@@ -48,11 +51,21 @@ func ParseEndpoint(
healthLivenessFlags = flag.NewFlagSet("liveness", flag.ExitOnError) healthLivenessFlags = flag.NewFlagSet("liveness", flag.ExitOnError)
healthReadinessFlags = flag.NewFlagSet("readiness", flag.ExitOnError) healthReadinessFlags = flag.NewFlagSet("readiness", flag.ExitOnError)
cacheFlags = flag.NewFlagSet("cache", flag.ContinueOnError)
cacheGetFlags = flag.NewFlagSet("get", flag.ExitOnError)
cacheGetKeyFlag = cacheGetFlags.String("key", "REQUIRED", "")
cacheGetNamespaceFlag = cacheGetFlags.String("namespace", "REQUIRED", "")
cacheGetScopeFlag = cacheGetFlags.String("scope", "REQUIRED", "")
) )
healthFlags.Usage = healthUsage healthFlags.Usage = healthUsage
healthLivenessFlags.Usage = healthLivenessUsage healthLivenessFlags.Usage = healthLivenessUsage
healthReadinessFlags.Usage = healthReadinessUsage healthReadinessFlags.Usage = healthReadinessUsage
cacheFlags.Usage = cacheUsage
cacheGetFlags.Usage = cacheGetUsage
if err := flag.CommandLine.Parse(os.Args[1:]); err != nil { if err := flag.CommandLine.Parse(os.Args[1:]); err != nil {
return nil, nil, err return nil, nil, err
} }
...@@ -70,6 +83,8 @@ func ParseEndpoint( ...@@ -70,6 +83,8 @@ func ParseEndpoint(
switch svcn { switch svcn {
case "health": case "health":
svcf = healthFlags svcf = healthFlags
case "cache":
svcf = cacheFlags
default: default:
return nil, nil, fmt.Errorf("unknown service %q", svcn) return nil, nil, fmt.Errorf("unknown service %q", svcn)
} }
...@@ -95,6 +110,13 @@ func ParseEndpoint( ...@@ -95,6 +110,13 @@ func ParseEndpoint(
} }
case "cache":
switch epn {
case "get":
epf = cacheGetFlags
}
} }
} }
if epf == nil { if epf == nil {
...@@ -125,6 +147,13 @@ func ParseEndpoint( ...@@ -125,6 +147,13 @@ func ParseEndpoint(
endpoint = c.Readiness() endpoint = c.Readiness()
data = nil data = nil
} }
case "cache":
c := cachec.NewClient(scheme, host, doer, enc, dec, restore)
switch epn {
case "get":
endpoint = c.Get()
data, err = cachec.BuildGetPayload(*cacheGetKeyFlag, *cacheGetNamespaceFlag, *cacheGetScopeFlag)
}
} }
} }
if err != nil { if err != nil {
...@@ -167,3 +196,29 @@ Example: ...@@ -167,3 +196,29 @@ Example:
%[1]s health readiness %[1]s health readiness
`, os.Args[0]) `, os.Args[0])
} }
// cacheUsage displays the usage of the cache command and its subcommands.
func cacheUsage() {
fmt.Fprintf(os.Stderr, `Cache service allows storing and retrieving data from distributed cache.
Usage:
%[1]s [globalflags] cache COMMAND [flags]
COMMAND:
get: Get value from the cache. The result is a sequence of bytes which the client must decode.
Additional help:
%[1]s cache COMMAND --help
`, os.Args[0])
}
func cacheGetUsage() {
fmt.Fprintf(os.Stderr, `%[1]s [flags] cache get -key STRING -namespace STRING -scope STRING
Get value from the cache. The result is a sequence of bytes which the client must decode.
-key STRING:
-namespace STRING:
-scope STRING:
Example:
%[1]s cache get --key "Officiis fuga architecto cum." --namespace "Sint adipisci." --scope "Debitis id reprehenderit incidunt necessitatibus assumenda."
`, os.Args[0])
}
{"swagger":"2.0","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":""},"host":"localhost:8080","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"]}}}} {"swagger":"2.0","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":""},"host":"localhost:8083","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/cache":{"get":{"tags":["cache"],"summary":"Get cache","description":"Get value from the cache. The result is a sequence of bytes which the client must decode.","operationId":"cache#Get","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","required":true,"type":"string"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","required":true,"type":"string"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","required":true,"type":"string"}],"responses":{"200":{"description":"OK response.","schema":{"type":"string","format":"byte"}}},"schemes":["http"]}}}}
\ No newline at end of file \ No newline at end of file
...@@ -3,7 +3,7 @@ info: ...@@ -3,7 +3,7 @@ info:
title: Cache Service title: Cache Service
description: The cache service exposes interface for working with Redis. description: The cache service exposes interface for working with Redis.
version: "" version: ""
host: localhost:8080 host: localhost:8083
consumes: consumes:
- application/json - application/json
- application/xml - application/xml
...@@ -35,3 +35,35 @@ paths: ...@@ -35,3 +35,35 @@ paths:
description: OK response. description: OK response.
schemes: schemes:
- http - http
/v1/cache:
get:
tags:
- cache
summary: Get cache
description: Get value from the cache. The result is a sequence of bytes which
the client must decode.
operationId: cache#Get
parameters:
- name: x-cache-key
in: header
description: Cache entry key
required: true
type: string
- name: x-cache-namespace
in: header
description: Cache entry namespace
required: true
type: string
- name: x-cache-scope
in: header
description: Cache entry scope
required: true
type: string
responses:
"200":
description: OK response.
schema:
type: string
format: byte
schemes:
- http
{"openapi":"3.0.3","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":"1.0"},"servers":[{"url":"http://localhost:8080","description":"Cache 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."}}}}},"components":{},"tags":[{"name":"health","description":"Health service provides health check endpoints."}]} {"openapi":"3.0.3","info":{"title":"Cache Service","description":"The cache service exposes interface for working with Redis.","version":"1.0"},"servers":[{"url":"http://localhost:8083","description":"Cache 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/cache":{"get":{"tags":["cache"],"summary":"Get cache","description":"Get value from the cache. The result is a sequence of bytes which the client must decode.","operationId":"cache#Get","parameters":[{"name":"x-cache-key","in":"header","description":"Cache entry key","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry key","example":"did:web:example.com"},"example":"did:web:example.com"},{"name":"x-cache-namespace","in":"header","description":"Cache entry namespace","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry namespace","example":"Login"},"example":"Login"},{"name":"x-cache-scope","in":"header","description":"Cache entry scope","allowEmptyValue":true,"required":true,"schema":{"type":"string","description":"Cache entry scope","example":"administration"},"example":"administration"}],"responses":{"200":{"description":"OK response.","content":{"application/json":{"schema":{"type":"string","example":"UmVwdWRpYW5kYWUgZW9zIGNvbnNlcXVhdHVyIHNpbnQgZG9sb3J1bSBvY2NhZWNhdGku","format":"binary"},"example":"Vm9sdXB0YXR1bSBtb2RpIHRlbmV0dXIgdGVtcG9yZSBxdWlhIGVzdCByYXRpb25lLg=="}}}}}}},"components":{},"tags":[{"name":"health","description":"Health service provides health check endpoints."},{"name":"cache","description":"Cache service allows storing and retrieving data from distributed cache."}]}
\ No newline at end of file \ No newline at end of file
...@@ -4,7 +4,7 @@ info: ...@@ -4,7 +4,7 @@ info:
description: The cache service exposes interface for working with Redis. description: The cache service exposes interface for working with Redis.
version: "1.0" version: "1.0"
servers: servers:
- url: http://localhost:8080 - url: http://localhost:8083
description: Cache Server description: Cache Server
paths: paths:
/liveness: /liveness:
...@@ -25,7 +25,158 @@ paths: ...@@ -25,7 +25,158 @@ paths:
responses: responses:
"200": "200":
description: OK response. description: OK response.
/v1/cache:
get:
tags:
- cache
summary: Get cache
description: Get value from the cache. The result is a sequence of bytes which
the client must decode.
operationId: cache#Get
parameters:
- name: x-cache-key
in: header
description: Cache entry key
allowEmptyValue: true
required: true
schema:
type: string
description: Cache entry key
example: did:web:example.com
example: did:web:example.com
- name: x-cache-namespace
in: header
description: Cache entry namespace
allowEmptyValue: true
required: true
schema:
type: string
description: Cache entry namespace
example: Login
example: Login
- name: x-cache-scope
in: header
description: Cache entry scope
allowEmptyValue: true
required: true
schema:
type: string
description: Cache entry scope
example: administration
example: administration
responses:
"200":
description: OK response.
content:
application/json:
schema:
type: string
example:
- 82
- 101
- 112
- 117
- 100
- 105
- 97
- 110
- 100
- 97
- 101
- 32
- 101
- 111
- 115
- 32
- 99
- 111
- 110
- 115
- 101
- 113
- 117
- 97
- 116
- 117
- 114
- 32
- 115
- 105
- 110
- 116
- 32
- 100
- 111
- 108
- 111
- 114
- 117
- 109
- 32
- 111
- 99
- 99
- 97
- 101
- 99
- 97
- 116
- 105
- 46
format: binary
example:
- 86
- 111
- 108
- 117
- 112
- 116
- 97
- 116
- 117
- 109
- 32
- 109
- 111
- 100
- 105
- 32
- 116
- 101
- 110
- 101
- 116
- 117
- 114
- 32
- 116
- 101
- 109
- 112
- 111
- 114
- 101
- 32
- 113
- 117
- 105
- 97
- 32
- 101
- 115
- 116
- 32
- 114
- 97
- 116
- 105
- 111
- 110
- 101
- 46
components: {} components: {}
tags: tags:
- name: health - name: health
description: Health service provides health check endpoints. description: Health service provides health check endpoints.
- name: cache
description: Cache service allows storing and retrieving data from distributed cache.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment