Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • fb6-wp11-devops/webservice
  • maha1056/devops-pipeline
  • ludo8147/webservice
  • s52888/webservice
  • masi9606/webservice
  • kibu5600/webservice
  • s78689/webservice
  • s50860/webservice
  • s92604/devops-webservice
  • s76867/webservice-devops
  • s92274/webservice
  • s80066/webservice
  • masa1998/webservice
  • s91190/app-service
  • s84985/webservice
  • s75359/webservice
  • ouch4861/webservice-ws-24-oc
  • s92274/webservice-msws-24
  • ewbo4360/webservice
19 results
Show changes
......@@ -45,6 +45,7 @@ build-linux: export GOOS := linux
build-linux: export GOARCH := amd64
build-linux: export CGO_ENABLED := 0
build-linux: $(BIN_DIR)/artifact.bin
sha256sum $(BIN_DIR)/artifact.bin
.PHONY: test
......
......@@ -86,6 +86,13 @@ curl \
http://localhost:8080/state/bar
```
Find out MIME type and size of an entry:
```bash
curl \
-X HEAD \
http://localhost:8080/state/bar
```
Obtain an entry:
```bash
curl \
......
......@@ -25,12 +25,17 @@ func SetRoutes( router *f.App, config *configuration.Config, store state.Store,
return err
}
metricsTextTemplate, err := template.New( "metrics" ).Parse( metricsText )
if err != nil {
return err
}
if config.LogLevel == "debug" {
router.All( "*", func( c *f.Ctx ) error {
log.Printf( "%s %s mime:%s agent:%s",
c.Method(),
c.Path(),
c.Get( f.HeaderContentType ),
c.Get( f.HeaderContentType, c.Get( f.HeaderAccept, "" ) ),
c.Get( f.HeaderUserAgent ),
)
return c.Next()
......@@ -90,6 +95,35 @@ func SetRoutes( router *f.App, config *configuration.Config, store state.Store,
})
router.Get( "/metrics", func( c *f.Ctx ) error {
headers := c.GetReqHeaders()
acceptHeader := strings.Join( headers[ "Accept" ], " " )
buffer := &bytes.Buffer{}
if strings.Contains( acceptHeader , "json" ) {
// FUTUREWORK: implement https://opentelemetry.io/docs/specs/otlp/#otlphttp
return c.SendStatus( http.StatusNotAcceptable )
} else {
names, err := store.List()
if err != nil {
return c.SendStatus( http.StatusInternalServerError )
}
data := metricsTextData{
Count: len( names ),
}
err = metricsTextTemplate.Execute( buffer, data )
if err != nil {
return err
}
c.Set( "Content-Type", "text/plain; charset=utf-8" )
return c.Send( buffer.Bytes() )
}
})
router.Get( "/env", func( c *f.Ctx ) error {
c.Type( "txt", "utf-8" )
......@@ -114,6 +148,22 @@ func SetRoutes( router *f.App, config *configuration.Config, store state.Store,
statePathGroup := router.Group( "/state" )
statePathGroup.Options( "/:name", func( c *f.Ctx ) error {
name := strings.Clone( c.Params( "name" ) )
existingItem, err := store.Fetch( name )
if err != nil {
return c.SendStatus( http.StatusInternalServerError )
}
if existingItem == nil {
return c.SendStatus( http.StatusNotFound )
}
c.Set( "Allow", "OPTIONS, GET, PUT, DELETE, HEAD" )
return c.SendStatus( http.StatusNoContent )
})
statePathGroup.Get( "/:name", func( c *f.Ctx ) error {
existingItem, err := store.Fetch( c.Params( "name" ) )
if err != nil {
......@@ -194,12 +244,24 @@ func SetRoutes( router *f.App, config *configuration.Config, store state.Store,
})
statePathGroup.Use( "*", func( c *f.Ctx ) error {
if method := c.Method(); method == "OPTIONS" {
c.Set( "Allow", "GET, PUT, DELETE, OPTIONS" )
return c.SendStatus( http.StatusNoContent )
statePathGroup.Head( "/:name", func( c *f.Ctx ) error {
name := strings.Clone( c.Params( "name" ) )
existingItem, err := store.Fetch( name )
if err != nil {
return c.SendStatus( http.StatusInternalServerError )
}
if existingItem == nil {
return c.SendStatus( http.StatusNotFound )
}
c.Set( "Content-Type", existingItem.MimeType() )
c.Set( "Content-Length", fmt.Sprintf( "%d", len( existingItem.Data() ) ) )
return c.SendStatus( http.StatusOK )
})
statePathGroup.Use( "*", func( c *f.Ctx ) error {
return c.SendStatus( http.StatusNotFound )
})
......
......@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"strconv"
"strings"
"time"
"math/rand"
......@@ -167,7 +168,7 @@ func TestState( t *testing.T ){
const statePath2 = "/state/another-test"
const statePath2Mime = "application/octet-stream"
const statePath2BodySize = 64
const statePath2BodySize = 128
statePath2Body := generateRandomBytes( statePath2BodySize )
req := ht.NewRequest( "GET", statePath1, nil )
......@@ -211,6 +212,15 @@ func TestState( t *testing.T ){
res, _ = router.Test( req, -1 )
assert.Equal( t, http.StatusCreated, res.StatusCode )
req = ht.NewRequest( "HEAD", statePath2, nil )
res, _ = router.Test( req, -1 )
contentLength, err := strconv.ParseInt( res.Header[ "Content-Length" ][0], 10, 64 )
assert.Nil( t, err )
assert.Equal( t, http.StatusOK, res.StatusCode )
assert.Equal( t, statePath2Mime, res.Header[ "Content-Type" ][0] )
assert.Equal( t, int64( statePath2BodySize ), contentLength )
assert.IsType( t, res.Body, http.NoBody )
req = ht.NewRequest( "GET", statePath2, nil )
res, _ = router.Test( req, -1 )
bodyBytes, err := io.ReadAll( res.Body )
......
......@@ -20,3 +20,14 @@ type indexHtmlData struct {
Version string
Color string
}
const metricsText = `
# HELP state_entries_quantity The current number of state entries being stored
# TYPE state_entries_quantity gauge
state_entries_quantity {{ .Count }}
`
type metricsTextData struct {
Count int
}