Commit 0053aa87 authored by christophe.devienne's avatar christophe.devienne

storage: Use ErrNoSuchID in EnvelopeStorage

parent f206287d5bc2
......@@ -32,7 +32,7 @@ require (
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.6.1
github.com/stretchr/testify v1.7.0
github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59
gopkg.in/yaml.v2 v2.3.0
......
......@@ -530,6 +530,7 @@ github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
......@@ -538,6 +539,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae h1:vgGSvdW5Lqg+I1aZOlG32uyE6xHpLdKhZzcTEktz5wM=
github.com/termie/go-shutil v0.0.0-20140729215957-bcacb06fecae/go.mod h1:quDq6Se6jlGwiIKia/itDZxqC5rj6/8OdFyMMAwTxCs=
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
......
......@@ -74,8 +74,10 @@ type EnvelopeStorage interface {
GetEventTypes(id api.UUID) (types []string, exists bool)
// ReceptionStatus returns the envelope reception status
// Must returns a (possibly nested) ErrNoSuchID if the envelope does not exist
ReceptionStatus(id api.UUID) (EnvelopeStorageReceptionStatus, error)
// Must returns a (possibly nested) ErrNoSuchID if the envelope does not exist
ReadEnvelope(id api.UUID, position EnvelopeReadPos, maxsize int) (api.Envelope, EnvelopeReadPos, error)
Purge(EnvelopeFilter)
......
......@@ -410,7 +410,7 @@ func (es EnvelopeStorage) ReceptionStatus(id api.UUID) (storage.EnvelopeStorageR
defer tx.BlindRollback()
err := tx.Query(es.model.Envelope).Get(&dbEnvelope, uuid.UUID(id))
if err == yago.ErrRecordNotFound {
return storage.EnvelopeStorageReceptionUnknown, fmt.Errorf("No such envelope: %s", id)
return storage.EnvelopeStorageReceptionUnknown, storage.NewNoSuchIDError(storage.DatatypeEnvelope, id)
}
if err != nil {
return storage.EnvelopeStorageReceptionUnknown, err
......@@ -432,7 +432,7 @@ func (es EnvelopeStorage) ReadEnvelope(id api.UUID, position storage.EnvelopeRea
// Load the envelope
err := tx.Query(es.model.Envelope).Get(&dbEnvelope, uuid.UUID(id))
if err == yago.ErrRecordNotFound {
return api.Envelope{}, storage.EnvelopeReadPos{}, fmt.Errorf("No such envelope: %s", id)
return api.Envelope{}, storage.EnvelopeReadPos{}, storage.NewNoSuchIDError(storage.DatatypeEnvelope, id)
}
must(err)
......
......@@ -6,6 +6,7 @@ import (
"crypto/sha256"
"database/sql"
"encoding/hex"
"errors"
"time"
jsoniter "github.com/json-iterator/go"
......@@ -408,6 +409,9 @@ func (es EnvelopeStorageNG) ReceptionStatus(id api.UUID) (storage.EnvelopeStorag
row := tx.QueryRow(
"SELECT status FROM envelope_storage WHERE envelope_id = $1", uuid.UUID(id))
if err := row.Scan(&s); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return 0, storage.NewNoSuchIDError(storage.DatatypeEnvelope, id)
}
return 0, err
}
......@@ -492,6 +496,21 @@ func (es EnvelopeStorageNG) ReadEnvelope(id api.UUID, position storage.EnvelopeR
return mergedFragment, sorterPosition, nil
}
// no fragment found, checking if the envelope actually exists
var exists bool
row := tx.QueryRow(
"SELECT EXISTS(SELECT 1 FROM envelope_storage_data WHERE envelope_id = $1 LIMIT 1)",
uuid.UUID(id),
)
if err := row.Scan(&exists); err != nil {
return api.Envelope{}, position, err
}
if !exists {
return api.Envelope{}, position, storage.NewNoSuchIDError(
storage.DatatypeEnvelope, id)
}
return api.Envelope{}, position, nil
}
......
......@@ -2,9 +2,41 @@ package storage
import (
"errors"
"xbus.io/go-xbus/v3/api"
)
var (
// ErrNoSuchID is returned when a non-existing id is passed to some function
ErrNoSuchID = errors.New("No such ID")
)
type Datatype string
func (d Datatype) String() string {
return string(d)
}
const (
DatatypeEnvelope Datatype = "envelope"
)
type NoSuchIDError struct {
datatype Datatype
id api.UUID
}
func (err NoSuchIDError) Unwrap() error {
return ErrNoSuchID
}
func (err NoSuchIDError) Error() string {
return "No such " + err.datatype.String() + ": " + err.id.String()
}
func NewNoSuchIDError(datatype Datatype, id api.UUID) *NoSuchIDError {
return &NoSuchIDError{
datatype: datatype,
id: id,
}
}
......@@ -192,7 +192,7 @@ func (s *EnvelopeStorage) ReceptionStatus(id api.UUID) (storage.EnvelopeStorageR
r, ok := s.receivers[id]
if !ok {
return storage.EnvelopeStorageReceptionUnknown, fmt.Errorf("Unknown envelope")
return storage.EnvelopeStorageReceptionUnknown, storage.NewNoSuchIDError("envelope", id)
}
switch r.Status() {
case api.EnvelopeAck_RECEIVING:
......@@ -215,7 +215,7 @@ func (s *EnvelopeStorage) ReadEnvelope(id api.UUID, position storage.EnvelopeRea
envelope, ok := s.envelopes[id]
if !ok {
return api.Envelope{}, position, fmt.Errorf("No such envelope: %s", id)
return api.Envelope{}, position, storage.NewNoSuchIDError("envelope", id)
}
if position.Start {
......
......@@ -3,6 +3,7 @@
package storage
import (
"errors"
"sync"
"testing"
"time"
......@@ -39,6 +40,19 @@ func EnvelopeStorageTests(t *testing.T, factory EnvelopeStorageFactory, supportU
handlerCalled = false
}
t.Run("Store/NoSuchID", func(t *testing.T) {
envelopeStorage, clean := factory(t)
defer clean()
id := api.MustUUIDFromString("b74415ee-83c1-11e6-8f04-133b336287df")
_, err := envelopeStorage.ReceptionStatus(id)
assert.ErrorIs(t, err, storage.ErrNoSuchID)
_, _, err = envelopeStorage.ReadEnvelope(id, storage.EnvelopeStartPos(), 0)
assert.ErrorIs(t, err, storage.ErrNoSuchID)
})
t.Run("Store/TypesUnknown", func(t *testing.T) {
envelopeStorage, clean := factory(t)
defer clean()
......@@ -547,6 +561,10 @@ func EnvelopeStorageTests(t *testing.T, factory EnvelopeStorageFactory, supportU
consecutiveWaits := 0
for !pos.Complete {
out, newPos, err := envelopeStorage.ReadEnvelope(envID, pos, 500)
if errors.Is(err, storage.ErrNoSuchID) {
time.Sleep(1 * time.Millisecond)
continue
}
if err != nil {
t.Fatal(err)
}
......
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