Commit 9b4531c9 authored by Janoš Guljaš's avatar Janoš Guljaš Committed by GitHub

move tags endpoints to debug api (#291)

parent 1f29b19b
......@@ -6,5 +6,4 @@ package api
type (
BytesPostResponse = bytesPostResponse
TagResponse = tagResponse
)
......@@ -56,14 +56,6 @@ func (s *server) setupRouting() {
"POST": http.HandlerFunc(s.chunkUploadHandler),
})
router.Handle("/bzz-tag/name/{name}", jsonhttp.MethodHandler{
"POST": http.HandlerFunc(s.CreateTag),
})
router.Handle("/bzz-tag/uuid/{uuid}", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.getTagInfoUsingUUid),
})
s.Handler = web.ChainHandlers(
logging.NewHTTPAccessLogHandler(s.Logger, logrus.InfoLevel, "api access"),
handlers.CompressHandler,
......
......@@ -12,4 +12,5 @@ type (
AddressesResponse = addressesResponse
PinnedChunk = pinnedChunk
ListPinnedChunksResponse = listPinnedChunksResponse
TagResponse = tagResponse
)
......@@ -77,6 +77,12 @@ func (s *server) setupRouting() {
router.Handle("/chunks-pin", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.listPinnedChunks),
})
router.Handle("/tags", jsonhttp.MethodHandler{
"POST": http.HandlerFunc(s.createTag),
})
router.Handle("/tags/{uid}", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.getTag),
})
router.Handle("/topology", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.topologyHandler),
})
......
......@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package api
package debugapi
import (
crand "crypto/rand"
"errors"
"fmt"
"net/http"
"strconv"
"time"
......@@ -45,13 +48,25 @@ func newTagResponse(tag *tags.Tag) tagResponse {
StartedAt: tag.StartedAt,
}
}
func (s *server) CreateTag(w http.ResponseWriter, r *http.Request) {
tagName := mux.Vars(r)["name"]
tag, err := s.Tags.Create(tagName, 0, false)
func (s *server) createTag(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
if name == "" {
b := make([]byte, 4)
_, err := crand.Read(b)
if err != nil {
s.Logger.Debugf("create tag: read random bytes %v", err)
s.Logger.Errorf("create tag: read random bytes error")
jsonhttp.InternalServerError(w, nil)
return
}
name = fmt.Sprintf("tag-%v-%x", time.Now().UnixNano(), b)
}
tag, err := s.Tags.Create(name, 0, false)
if err != nil {
s.Logger.Debugf("bzz-chunk: tag create error: %v", err)
s.Logger.Error("bzz-chunk: tag create error")
s.Logger.Debugf("create tag: %s %v", name, err)
s.Logger.Errorf("create tag: %s error", name)
jsonhttp.InternalServerError(w, "cannot create tag")
return
}
......@@ -60,22 +75,28 @@ func (s *server) CreateTag(w http.ResponseWriter, r *http.Request) {
}
func (s *server) getTagInfoUsingUUid(w http.ResponseWriter, r *http.Request) {
uidStr := mux.Vars(r)["uuid"]
func (s *server) getTag(w http.ResponseWriter, r *http.Request) {
uidStr := mux.Vars(r)["uid"]
uuid, err := strconv.ParseUint(uidStr, 10, 32)
uid, err := strconv.ParseUint(uidStr, 10, 32)
if err != nil {
s.Logger.Debugf("bzz-tag: parse uid %s: %v", uidStr, err)
s.Logger.Error("bzz-tag: parse uid")
s.Logger.Debugf("get tag: parse uid %s: %v", uidStr, err)
s.Logger.Error("get tag: parse uid")
jsonhttp.BadRequest(w, "invalid uid")
return
}
tag, err := s.Tags.Get(uint32(uuid))
tag, err := s.Tags.Get(uint32(uid))
if err != nil {
s.Logger.Debugf("bzz-tag: tag not present : %v, uuid %s", err, uidStr)
s.Logger.Error("bzz-tag: tag not present")
jsonhttp.InternalServerError(w, "tag not present")
if errors.Is(err, tags.ErrNotFound) {
s.Logger.Debugf("get tag: tag %v not present: %v", uid, err)
s.Logger.Warningf("get tag: tag %v not present", uid)
jsonhttp.NotFound(w, "tag not present")
return
}
s.Logger.Debugf("get tag: tag %v: %v", uid, err)
s.Logger.Errorf("get tag: %v", uid)
jsonhttp.InternalServerError(w, nil)
return
}
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package api_test
package debugapi_test
import (
"bytes"
......@@ -11,6 +11,7 @@ import (
"testing"
"github.com/ethersphere/bee/pkg/api"
"github.com/ethersphere/bee/pkg/debugapi"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/jsonhttp/jsonhttptest"
mp "github.com/ethersphere/bee/pkg/pusher/mock"
......@@ -23,15 +24,20 @@ import (
func TestTags(t *testing.T) {
var (
resource = func(addr swarm.Address) string { return "/chunks/" + addr.String() }
tagResourceUidCreate = func(name string) string { return "/bzz-tag/name/" + name }
tagResourceUUid = func(uuid uint64) string { return "/bzz-tag/uuid/" + strconv.FormatUint(uuid, 10) }
tagResourceUidCreate = func(name string) string { return "/tags?name=" + name }
tagResourceUUid = func(uuid uint64) string { return "/tags/" + strconv.FormatUint(uuid, 10) }
validHash = swarm.MustParseHexAddress("aabbcc")
validContent = []byte("bbaatt")
mockValidator = validator.NewMockValidator(validHash, validContent)
tag = tags.NewTags()
mockValidatingStorer = mock.NewValidatingStorer(mockValidator, tag)
mockPusher = mp.NewMockPusher(tag)
client = newTestServer(t, testServerOptions{
ts = newTestServer(t, testServerOptions{
Storer: mockValidatingStorer,
Tags: tag,
})
// This server is used to store chunks
apiClient = newBZZTestServer(t, testServerOptions{
Storer: mockValidatingStorer,
Tags: tag,
})
......@@ -40,14 +46,14 @@ func TestTags(t *testing.T) {
t.Run("send-invalid-tag-id", func(t *testing.T) {
sentHheaders := make(http.Header)
sentHheaders.Set(api.TagHeaderUid, "file.jpg") // the value should be uint32
_ = jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusBadRequest, jsonhttp.StatusResponse{
_ = jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusBadRequest, jsonhttp.StatusResponse{
Message: "invalid taguid",
Code: http.StatusBadRequest,
}, sentHheaders)
})
t.Run("uid-header-in-return-for-empty-tag", func(t *testing.T) {
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, nil)
......@@ -57,8 +63,8 @@ func TestTags(t *testing.T) {
t.Run("get-tag-and-use-it-to-upload-chunk", func(t *testing.T) {
// Get a tag using API
ta := api.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, client, http.MethodPost, tagResourceUidCreate("file.jpg"), nil, http.StatusOK, &ta)
ta := debugapi.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, ts.Client, http.MethodPost, tagResourceUidCreate("file.jpg"), nil, http.StatusOK, &ta)
if ta.Name != "file.jpg" {
t.Fatalf("tagname is not the same that we sent")
......@@ -67,7 +73,7 @@ func TestTags(t *testing.T) {
// Now upload a chunk and see if we receive a tag with the same uid
sentHheaders := make(http.Header)
sentHheaders.Set(api.TagHeaderUid, strconv.FormatUint(uint64(ta.Uid), 10))
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, sentHheaders)
......@@ -77,8 +83,8 @@ func TestTags(t *testing.T) {
t.Run("get-tag-and-use-it-to-upload-multiple-chunk", func(t *testing.T) {
// Get a tag using API
ta := api.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, client, http.MethodPost, tagResourceUidCreate("file.jpg"), nil, http.StatusOK, &ta)
ta := debugapi.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, ts.Client, http.MethodPost, tagResourceUidCreate("file.jpg"), nil, http.StatusOK, &ta)
if ta.Name != "file.jpg" {
t.Fatalf("tagname is not the same that we sent")
......@@ -87,7 +93,7 @@ func TestTags(t *testing.T) {
// Now upload a chunk and see if we receive a tag with the same uid
sentHheaders := make(http.Header)
sentHheaders.Set(api.TagHeaderUid, strconv.FormatUint(uint64(ta.Uid), 10))
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, sentHheaders)
......@@ -101,7 +107,7 @@ func TestTags(t *testing.T) {
sentHheaders = make(http.Header)
sentHheaders.Set(api.TagHeaderUid, strconv.FormatUint(uint64(ta.Uid), 10))
rcvdHeaders = jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(secondValidHash), bytes.NewReader(secondValidContent), http.StatusOK, jsonhttp.StatusResponse{
rcvdHeaders = jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(secondValidHash), bytes.NewReader(secondValidContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, sentHheaders)
......@@ -111,7 +117,7 @@ func TestTags(t *testing.T) {
t.Run("get-tag-indirectly-and-use-it-to-upload-chunk", func(t *testing.T) {
//Upload anew chunk and we give aUID in response and apps can use that too
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, nil)
......@@ -119,20 +125,20 @@ func TestTags(t *testing.T) {
uuid := isTagFoundInResponse(t, rcvdHeaders, nil)
// see if the tagid is present and has valid values
ta := api.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, client, http.MethodGet, tagResourceUUid(uuid), nil, http.StatusOK, &ta)
ta := debugapi.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, ts.Client, http.MethodGet, tagResourceUUid(uuid), nil, http.StatusOK, &ta)
// Now upload another chunk using the same tag id
sentHheaders := make(http.Header)
sentHheaders.Set(api.TagHeaderUid, strconv.FormatUint(uuid, 10))
_ = jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
_ = jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, sentHheaders)
// see if the tagid is present and has valid values
ta = api.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, client, http.MethodGet, tagResourceUUid(uuid), nil, http.StatusOK, &ta)
ta = debugapi.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, ts.Client, http.MethodGet, tagResourceUUid(uuid), nil, http.StatusOK, &ta)
if uuid != uint64(ta.Uid) {
t.Fatalf("Invalid uuid response")
......@@ -143,22 +149,22 @@ func TestTags(t *testing.T) {
})
t.Run("get-tag-using-uuid", func(t *testing.T) {
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, nil)
uuid := isTagFoundInResponse(t, rcvdHeaders, nil)
// Request the tag and see if the UUID is the same
ta := api.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, client, http.MethodGet, tagResourceUUid(uuid), nil, http.StatusOK, &ta)
ta := debugapi.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, ts.Client, http.MethodGet, tagResourceUUid(uuid), nil, http.StatusOK, &ta)
if uuid != uint64(ta.Uid) {
t.Fatalf("Invalid uuid response")
}
})
t.Run("tag-counters", func(t *testing.T) {
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, client, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
rcvdHeaders := jsonhttptest.ResponseDirectSendHeadersAndReceiveHeaders(t, apiClient, http.MethodPost, resource(validHash), bytes.NewReader(validContent), http.StatusOK, jsonhttp.StatusResponse{
Message: http.StatusText(http.StatusOK),
Code: http.StatusOK,
}, nil)
......@@ -177,8 +183,8 @@ func TestTags(t *testing.T) {
t.Fatal(err)
}
finalTag := api.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, client, http.MethodGet, tagResourceUUid(uuid1), nil, http.StatusOK, &finalTag)
finalTag := debugapi.TagResponse{}
jsonhttptest.ResponseUnmarshal(t, ts.Client, http.MethodGet, tagResourceUUid(uuid1), nil, http.StatusOK, &finalTag)
if tagToVerify.Total != finalTag.Total {
t.Errorf("tag total count mismatch. got %d want %d", tagToVerify.Total, finalTag.Total)
......@@ -198,7 +204,7 @@ func TestTags(t *testing.T) {
})
}
func isTagFoundInResponse(t *testing.T, headers http.Header, tag *api.TagResponse) uint64 {
func isTagFoundInResponse(t *testing.T, headers http.Header, tag *debugapi.TagResponse) uint64 {
uidStr := headers.Get(api.TagHeaderUid)
if uidStr == "" {
t.Fatalf("could not find tagid header in chunk upload response")
......
......@@ -30,10 +30,9 @@ import (
)
var (
errExists = errors.New("already exists")
errNA = errors.New("not available yet")
errNoETA = errors.New("unable to calculate ETA")
errTagNotFound = errors.New("tag not found")
errExists = errors.New("already exists")
errNA = errors.New("not available yet")
errNoETA = errors.New("unable to calculate ETA")
)
// State is the enum type for chunk states
......
......@@ -31,8 +31,8 @@ import (
)
var (
TagUidFunc = rand.Uint32
TagNotFoundErr = errors.New("tag not found")
TagUidFunc = rand.Uint32
ErrNotFound = errors.New("tag not found")
)
// Tags hold tag information indexed by a unique random uint32
......@@ -75,7 +75,7 @@ func (ts *Tags) All() (t []*Tag) {
func (ts *Tags) Get(uid uint32) (*Tag, error) {
t, ok := ts.tags.Load(uid)
if !ok {
return nil, TagNotFoundErr
return nil, ErrNotFound
}
return t.(*Tag), nil
}
......@@ -94,7 +94,7 @@ func (ts *Tags) GetByAddress(address swarm.Address) (*Tag, error) {
})
if t == nil {
return nil, errTagNotFound
return nil, ErrNotFound
}
return t, nil
}
......@@ -104,7 +104,7 @@ func (ts *Tags) GetFromContext(ctx context.Context) (*Tag, error) {
uid := sctx.GetTag(ctx)
t, ok := ts.tags.Load(uid)
if !ok {
return nil, errTagNotFound
return nil, ErrNotFound
}
return t.(*Tag), nil
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment