Use way instead of mux
This commit is contained in:
parent
5b5852e900
commit
c47cf6ec24
19 changed files with 82 additions and 233 deletions
22
Gopkg.lock
generated
22
Gopkg.lock
generated
|
@ -19,24 +19,18 @@
|
||||||
revision = "06f5f3d67269ccec1fe5fe4134ba6e982984f7f5"
|
revision = "06f5f3d67269ccec1fe5fe4134ba6e982984f7f5"
|
||||||
version = "v1.37.0"
|
version = "v1.37.0"
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/gorilla/context"
|
|
||||||
packages = ["."]
|
|
||||||
revision = "08b5f424b9271eedf6f9f0ce86cb9396ed337a42"
|
|
||||||
version = "v1.1.1"
|
|
||||||
|
|
||||||
[[projects]]
|
|
||||||
name = "github.com/gorilla/mux"
|
|
||||||
packages = ["."]
|
|
||||||
revision = "e3702bed27f0d39777b0b37b664b6280e8ef8fbf"
|
|
||||||
version = "v1.6.2"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/mastertinner/adapters"
|
name = "github.com/mastertinner/adapters"
|
||||||
packages = ["logging"]
|
packages = ["logging"]
|
||||||
revision = "368acae73d1569f0495b00991aaa85ec27d6ee8e"
|
revision = "368acae73d1569f0495b00991aaa85ec27d6ee8e"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
name = "github.com/matryer/way"
|
||||||
|
packages = ["."]
|
||||||
|
revision = "9632d0c407b008073d19d0c4da1e0fc3e9477508"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/minio/minio-go"
|
name = "github.com/minio/minio-go"
|
||||||
packages = [
|
packages = [
|
||||||
|
@ -97,7 +91,7 @@
|
||||||
"http/httpguts",
|
"http/httpguts",
|
||||||
"idna"
|
"idna"
|
||||||
]
|
]
|
||||||
revision = "75944861c7512f64725d687546cfbc757626151f"
|
revision = "1e491301e022f8f977054da4c2d852decd59571f"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
@ -133,6 +127,6 @@
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "6db25b97d13bf45e956ff0f573b637705d594109858fb3424eeadf7233fdf517"
|
inputs-digest = "9f288d84be4931be1d2e9529f7e3350bbfaa9f6cb0968db278c6efddb54e9f64"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|
|
@ -26,12 +26,12 @@
|
||||||
|
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/gorilla/mux"
|
branch = "master"
|
||||||
version = "1.6.2"
|
name = "github.com/mastertinner/adapters"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/mastertinner/adapters"
|
name = "github.com/matryer/way"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
name = "github.com/minio/minio-go"
|
name = "github.com/minio/minio-go"
|
||||||
|
|
|
@ -7,9 +7,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/mastertinner/adapters/logging"
|
"github.com/mastertinner/adapters/logging"
|
||||||
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
||||||
|
"github.com/matryer/way"
|
||||||
minio "github.com/minio/minio-go"
|
minio "github.com/minio/minio-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
@ -29,6 +29,8 @@ func main() {
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmplDir := filepath.Join("web", "template")
|
||||||
|
|
||||||
// Set up S3 client
|
// Set up S3 client
|
||||||
var s3 *minio.Client
|
var s3 *minio.Client
|
||||||
var err error
|
var err error
|
||||||
|
@ -41,50 +43,17 @@ func main() {
|
||||||
log.Fatalln(errors.Wrap(err, "error creating s3 client"))
|
log.Fatalln(errors.Wrap(err, "error creating s3 client"))
|
||||||
}
|
}
|
||||||
|
|
||||||
tmplDir := filepath.Join("web", "template")
|
|
||||||
|
|
||||||
// Set up router
|
// Set up router
|
||||||
r := mux.NewRouter().StrictSlash(true)
|
r := way.NewRouter()
|
||||||
r.Use(logging.Handler(os.Stdout))
|
r.Handle(http.MethodGet, "/", http.RedirectHandler("/buckets", http.StatusPermanentRedirect))
|
||||||
|
r.Handle(http.MethodGet, "/buckets", s3manager.HandleBucketsView(s3, tmplDir))
|
||||||
|
r.Handle(http.MethodGet, "/buckets/:bucketName", s3manager.HandleBucketView(s3, tmplDir))
|
||||||
|
r.Handle(http.MethodPost, "/api/buckets", s3manager.HandleCreateBucket(s3))
|
||||||
|
r.Handle(http.MethodDelete, "/api/buckets/:bucketName", s3manager.HandleDeleteBucket(s3))
|
||||||
|
r.Handle(http.MethodPost, "/api/buckets/:bucketName/objects", s3manager.HandleCreateObject(s3))
|
||||||
|
r.Handle(http.MethodGet, "/api/buckets/:bucketName/objects/:objectName", s3manager.HandleGetObject(s3))
|
||||||
|
r.Handle(http.MethodDelete, "/api/buckets/:bucketName/objects/:objectName", s3manager.HandleDeleteObject(s3))
|
||||||
|
|
||||||
r.
|
lr := logging.Handler(os.Stdout)(r)
|
||||||
Methods(http.MethodGet).
|
log.Fatal(http.ListenAndServe(":"+*port, lr))
|
||||||
Path("/").
|
|
||||||
Handler(http.RedirectHandler("/buckets", http.StatusPermanentRedirect))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodGet).
|
|
||||||
Path("/buckets").
|
|
||||||
Handler(s3manager.BucketsViewHandler(s3, tmplDir))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodGet).
|
|
||||||
Path("/buckets/{bucketName}").
|
|
||||||
Handler(s3manager.BucketViewHandler(s3, tmplDir))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodPost).
|
|
||||||
Path("/api/buckets").
|
|
||||||
Handler(s3manager.CreateBucketHandler(s3))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodDelete).
|
|
||||||
Path("/api/buckets/{bucketName}").
|
|
||||||
Handler(s3manager.DeleteBucketHandler(s3))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodPost).
|
|
||||||
Headers("Content-Type", "application/json; charset=utf-8").
|
|
||||||
Path("/api/buckets/{bucketName}/objects").
|
|
||||||
Handler(s3manager.CopyObjectHandler(s3))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodPost).
|
|
||||||
HeadersRegexp("Content-Type", "multipart/form-data").
|
|
||||||
Path("/api/buckets/{bucketName}/objects").
|
|
||||||
Handler(s3manager.CreateObjectHandler(s3))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodGet).
|
|
||||||
Path("/api/buckets/{bucketName}/objects/{objectName}").
|
|
||||||
Handler(s3manager.GetObjectHandler(s3))
|
|
||||||
r.
|
|
||||||
Methods(http.MethodDelete).
|
|
||||||
Path("/api/buckets/{bucketName}/objects/{objectName}").
|
|
||||||
Handler(s3manager.DeleteObjectHandler(s3))
|
|
||||||
|
|
||||||
log.Fatal(http.ListenAndServe(":"+*port, r))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/matryer/way"
|
||||||
minio "github.com/minio/minio-go"
|
minio "github.com/minio/minio-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BucketViewHandler shows the details page of a bucket.
|
// HandleBucketView shows the details page of a bucket.
|
||||||
func BucketViewHandler(s3 S3, tmplDir string) http.Handler {
|
func HandleBucketView(s3 S3, tmplDir string) http.HandlerFunc {
|
||||||
type objectWithIcon struct {
|
type objectWithIcon struct {
|
||||||
minio.ObjectInfo
|
minio.ObjectInfo
|
||||||
Icon string
|
Icon string
|
||||||
|
@ -22,9 +22,8 @@ func BucketViewHandler(s3 S3, tmplDir string) http.Handler {
|
||||||
BucketName string
|
BucketName string
|
||||||
Objects []objectWithIcon
|
Objects []objectWithIcon
|
||||||
}
|
}
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
bucketName := way.Param(r.Context(), "bucketName")
|
||||||
bucketName := mux.Vars(r)["bucketName"]
|
|
||||||
|
|
||||||
var objs []objectWithIcon
|
var objs []objectWithIcon
|
||||||
doneCh := make(chan struct{})
|
doneCh := make(chan struct{})
|
||||||
|
@ -55,7 +54,7 @@ func BucketViewHandler(s3 S3, tmplDir string) http.Handler {
|
||||||
handleHTTPError(w, errors.Wrap(err, "error executing template"))
|
handleHTTPError(w, errors.Wrap(err, "error executing template"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// icon returns an icon for a file type.
|
// icon returns an icon for a file type.
|
||||||
|
|
|
@ -9,13 +9,13 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
||||||
|
"github.com/matryer/way"
|
||||||
minio "github.com/minio/minio-go"
|
minio "github.com/minio/minio-go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBucketViewHandler(t *testing.T) {
|
func TestHandleBucketView(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
listObjectsV2Func func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo
|
listObjectsV2Func func(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo
|
||||||
bucketName string
|
bucketName string
|
||||||
|
@ -121,11 +121,8 @@ func TestBucketViewHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tmplDir := filepath.Join("..", "..", "..", "web", "template")
|
tmplDir := filepath.Join("..", "..", "..", "web", "template")
|
||||||
r := mux.NewRouter()
|
r := way.NewRouter()
|
||||||
r.
|
r.Handle(http.MethodGet, "/buckets/:bucketName", s3manager.HandleBucketView(s3, tmplDir))
|
||||||
Methods(http.MethodGet).
|
|
||||||
Path("/buckets/{bucketName}").
|
|
||||||
Handler(s3manager.BucketViewHandler(s3, tmplDir))
|
|
||||||
|
|
||||||
ts := httptest.NewServer(r)
|
ts := httptest.NewServer(r)
|
||||||
defer ts.Close()
|
defer ts.Close()
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BucketsViewHandler renders all buckets on an HTML page.
|
// HandleBucketsView renders all buckets on an HTML page.
|
||||||
func BucketsViewHandler(s3 S3, tmplDir string) http.Handler {
|
func HandleBucketsView(s3 S3, tmplDir string) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
buckets, err := s3.ListBuckets()
|
buckets, err := s3.ListBuckets()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleHTTPError(w, errors.Wrap(err, "error listing buckets"))
|
handleHTTPError(w, errors.Wrap(err, "error listing buckets"))
|
||||||
|
@ -29,5 +29,5 @@ func BucketsViewHandler(s3 S3, tmplDir string) http.Handler {
|
||||||
handleHTTPError(w, errors.Wrap(err, "error executing template"))
|
handleHTTPError(w, errors.Wrap(err, "error executing template"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,12 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
||||||
minio "github.com/minio/minio-go"
|
minio "github.com/minio/minio-go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBucketsViewHandler(t *testing.T) {
|
func TestHandleBucketsView(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
listBucketsFunc func() ([]minio.BucketInfo, error)
|
listBucketsFunc func() ([]minio.BucketInfo, error)
|
||||||
expectedStatusCode int
|
expectedStatusCode int
|
||||||
|
@ -51,17 +50,12 @@ func TestBucketsViewHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tmplDir := filepath.Join("..", "..", "..", "web", "template")
|
tmplDir := filepath.Join("..", "..", "..", "web", "template")
|
||||||
r := mux.NewRouter()
|
|
||||||
r.
|
|
||||||
Methods(http.MethodGet).
|
|
||||||
Path("/buckets/{bucketName}").
|
|
||||||
Handler(s3manager.BucketViewHandler(s3, tmplDir))
|
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, "/buckets", nil)
|
req, err := http.NewRequest(http.MethodGet, "/buckets", nil)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
handler := s3manager.BucketsViewHandler(s3, tmplDir)
|
handler := s3manager.HandleBucketsView(s3, tmplDir)
|
||||||
|
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
resp := rr.Result()
|
resp := rr.Result()
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
package s3manager
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
minio "github.com/minio/minio-go"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CopyObjectHandler copies an existing object under a new name.
|
|
||||||
func CopyObjectHandler(s3 S3) http.Handler {
|
|
||||||
// request is the information about an object to copy.
|
|
||||||
type request struct {
|
|
||||||
BucketName string `json:"bucketName"`
|
|
||||||
ObjectName string `json:"objectName"`
|
|
||||||
SourceBucketName string `json:"sourceBucketName"`
|
|
||||||
SourceObjectName string `json:"sourceObjectName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
var req request
|
|
||||||
err := json.NewDecoder(r.Body).Decode(&req)
|
|
||||||
if err != nil {
|
|
||||||
handleHTTPError(w, errors.Wrap(err, "error decoding body JSON"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
src := minio.NewSourceInfo(req.SourceBucketName, req.SourceObjectName, nil)
|
|
||||||
dst, err := minio.NewDestinationInfo(req.BucketName, req.ObjectName, nil, nil)
|
|
||||||
if err != nil {
|
|
||||||
handleHTTPError(w, errors.Wrap(err, "error creating destination for copying"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = s3.CopyObject(dst, src)
|
|
||||||
if err != nil {
|
|
||||||
handleHTTPError(w, errors.Wrap(err, "error copying object"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
|
||||||
err = json.NewEncoder(w).Encode(req)
|
|
||||||
if err != nil {
|
|
||||||
handleHTTPError(w, errors.Wrap(err, "error encoding JSON"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateBucketHandler creates a new bucket.
|
// HandleCreateBucket creates a new bucket.
|
||||||
func CreateBucketHandler(s3 S3) http.Handler {
|
func HandleCreateBucket(s3 S3) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var bucket minio.BucketInfo
|
var bucket minio.BucketInfo
|
||||||
err := json.NewDecoder(r.Body).Decode(&bucket)
|
err := json.NewDecoder(r.Body).Decode(&bucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -31,5 +31,5 @@ func CreateBucketHandler(s3 S3) http.Handler {
|
||||||
handleHTTPError(w, errors.Wrap(err, "error encoding JSON"))
|
handleHTTPError(w, errors.Wrap(err, "error encoding JSON"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateBucketHandler(t *testing.T) {
|
func TestHandleCreateBucket(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
makeBucketFunc func(string, string) error
|
makeBucketFunc func(string, string) error
|
||||||
body string
|
body string
|
||||||
|
@ -64,7 +64,7 @@ func TestCreateBucketHandler(t *testing.T) {
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
handler := s3manager.CreateBucketHandler(s3)
|
handler := s3manager.HandleCreateBucket(s3)
|
||||||
|
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
resp := rr.Result()
|
resp := rr.Result()
|
||||||
|
|
|
@ -4,15 +4,16 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/matryer/way"
|
||||||
minio "github.com/minio/minio-go"
|
minio "github.com/minio/minio-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CreateObjectHandler uploads a new object.
|
// HandleCreateObject uploads a new object.
|
||||||
func CreateObjectHandler(s3 S3) http.Handler {
|
func HandleCreateObject(s3 S3) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
bucketName := mux.Vars(r)["bucketName"]
|
bucketName := way.Param(r.Context(), "bucketName")
|
||||||
|
|
||||||
err := r.ParseMultipartForm(32 << 20)
|
err := r.ParseMultipartForm(32 << 20)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleHTTPError(w, errors.Wrap(err, "error parsing multipart form"))
|
handleHTTPError(w, errors.Wrap(err, "error parsing multipart form"))
|
||||||
|
@ -37,5 +38,5 @@ func CreateObjectHandler(s3 S3) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,14 @@ package s3manager
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/matryer/way"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeleteBucketHandler deletes a bucket.
|
// HandleDeleteBucket deletes a bucket.
|
||||||
func DeleteBucketHandler(s3 S3) http.Handler {
|
func HandleDeleteBucket(s3 S3) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
bucketName := mux.Vars(r)["bucketName"]
|
bucketName := way.Param(r.Context(), "bucketName")
|
||||||
|
|
||||||
err := s3.RemoveBucket(bucketName)
|
err := s3.RemoveBucket(bucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,5 +19,5 @@ func DeleteBucketHandler(s3 S3) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDeleteBucketHandler(t *testing.T) {
|
func TestHandleDeleteBucket(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
removeBucketFunc func(string) error
|
removeBucketFunc func(string) error
|
||||||
expectedStatusCode int
|
expectedStatusCode int
|
||||||
|
@ -44,7 +44,7 @@ func TestDeleteBucketHandler(t *testing.T) {
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
handler := s3manager.DeleteBucketHandler(s3)
|
handler := s3manager.HandleDeleteBucket(s3)
|
||||||
|
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
resp := rr.Result()
|
resp := rr.Result()
|
||||||
|
|
|
@ -3,16 +3,15 @@ package s3manager
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/matryer/way"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeleteObjectHandler deletes an object.
|
// HandleDeleteObject deletes an object.
|
||||||
func DeleteObjectHandler(s3 S3) http.Handler {
|
func HandleDeleteObject(s3 S3) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
bucketName := way.Param(r.Context(), "bucketName")
|
||||||
bucketName := vars["bucketName"]
|
objectName := way.Param(r.Context(), "objectName")
|
||||||
objectName := vars["objectName"]
|
|
||||||
|
|
||||||
err := s3.RemoveObject(bucketName, objectName)
|
err := s3.RemoveObject(bucketName, objectName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -21,5 +20,5 @@ func DeleteObjectHandler(s3 S3) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDeleteObjectHandler(t *testing.T) {
|
func TestHandleDeleteObject(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
removeObjectFunc func(string, string) error
|
removeObjectFunc func(string, string) error
|
||||||
expectedStatusCode int
|
expectedStatusCode int
|
||||||
|
@ -44,7 +44,7 @@ func TestDeleteObjectHandler(t *testing.T) {
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
rr := httptest.NewRecorder()
|
||||||
handler := s3manager.DeleteObjectHandler(s3)
|
handler := s3manager.HandleDeleteObject(s3)
|
||||||
|
|
||||||
handler.ServeHTTP(rr, req)
|
handler.ServeHTTP(rr, req)
|
||||||
|
|
||||||
|
|
|
@ -5,17 +5,16 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/matryer/way"
|
||||||
minio "github.com/minio/minio-go"
|
minio "github.com/minio/minio-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetObjectHandler downloads an object to the client.
|
// HandleGetObject downloads an object to the client.
|
||||||
func GetObjectHandler(s3 S3) http.Handler {
|
func HandleGetObject(s3 S3) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := mux.Vars(r)
|
bucketName := way.Param(r.Context(), "bucketName")
|
||||||
bucketName := vars["bucketName"]
|
objectName := way.Param(r.Context(), "objectName")
|
||||||
objectName := vars["objectName"]
|
|
||||||
|
|
||||||
object, err := s3.GetObject(bucketName, objectName, minio.GetObjectOptions{})
|
object, err := s3.GetObject(bucketName, objectName, minio.GetObjectOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -30,5 +29,5 @@ func GetObjectHandler(s3 S3) http.Handler {
|
||||||
handleHTTPError(w, errors.Wrap(err, "error copying object to response writer"))
|
handleHTTPError(w, errors.Wrap(err, "error copying object to response writer"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,13 @@ import (
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
"github.com/mastertinner/s3manager/internal/app/s3manager"
|
||||||
|
"github.com/matryer/way"
|
||||||
minio "github.com/minio/minio-go"
|
minio "github.com/minio/minio-go"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetObjectHandler(t *testing.T) {
|
func TestHandleGetObject(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
getObjectFunc func(string, string, minio.GetObjectOptions) (*minio.Object, error)
|
getObjectFunc func(string, string, minio.GetObjectOptions) (*minio.Object, error)
|
||||||
bucketName string
|
bucketName string
|
||||||
|
@ -41,11 +41,8 @@ func TestGetObjectHandler(t *testing.T) {
|
||||||
GetObjectFunc: tc.getObjectFunc,
|
GetObjectFunc: tc.getObjectFunc,
|
||||||
}
|
}
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := way.NewRouter()
|
||||||
r.
|
r.Handle(http.MethodGet, "/buckets/:bucketName/objects/:objectName", s3manager.HandleGetObject(s3))
|
||||||
Methods(http.MethodGet).
|
|
||||||
Path("/buckets/{bucketName}/objects/{objectName}").
|
|
||||||
Handler(s3manager.GetObjectHandler(s3))
|
|
||||||
|
|
||||||
ts := httptest.NewServer(r)
|
ts := httptest.NewServer(r)
|
||||||
defer ts.Close()
|
defer ts.Close()
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
|
|
||||||
// S3 is a client to interact with S3 storage.
|
// S3 is a client to interact with S3 storage.
|
||||||
type S3 interface {
|
type S3 interface {
|
||||||
CopyObject(minio.DestinationInfo, minio.SourceInfo) error
|
|
||||||
GetObject(string, string, minio.GetObjectOptions) (*minio.Object, error)
|
GetObject(string, string, minio.GetObjectOptions) (*minio.Object, error)
|
||||||
ListBuckets() ([]minio.BucketInfo, error)
|
ListBuckets() ([]minio.BucketInfo, error)
|
||||||
ListObjectsV2(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo
|
ListObjectsV2(string, string, bool, <-chan struct{}) <-chan minio.ObjectInfo
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
lockS3MockCopyObject sync.RWMutex
|
|
||||||
lockS3MockGetObject sync.RWMutex
|
lockS3MockGetObject sync.RWMutex
|
||||||
lockS3MockListBuckets sync.RWMutex
|
lockS3MockListBuckets sync.RWMutex
|
||||||
lockS3MockListObjectsV2 sync.RWMutex
|
lockS3MockListObjectsV2 sync.RWMutex
|
||||||
|
@ -26,9 +25,6 @@ var (
|
||||||
//
|
//
|
||||||
// // make and configure a mocked S3
|
// // make and configure a mocked S3
|
||||||
// mockedS3 := &S3Mock{
|
// mockedS3 := &S3Mock{
|
||||||
// CopyObjectFunc: func(in1 minio.DestinationInfo, in2 minio.SourceInfo) error {
|
|
||||||
// panic("TODO: mock out the CopyObject method")
|
|
||||||
// },
|
|
||||||
// GetObjectFunc: func(in1 string, in2 string, in3 minio.GetObjectOptions) (*minio.Object, error) {
|
// GetObjectFunc: func(in1 string, in2 string, in3 minio.GetObjectOptions) (*minio.Object, error) {
|
||||||
// panic("TODO: mock out the GetObject method")
|
// panic("TODO: mock out the GetObject method")
|
||||||
// },
|
// },
|
||||||
|
@ -57,9 +53,6 @@ var (
|
||||||
//
|
//
|
||||||
// }
|
// }
|
||||||
type S3Mock struct {
|
type S3Mock struct {
|
||||||
// CopyObjectFunc mocks the CopyObject method.
|
|
||||||
CopyObjectFunc func(in1 minio.DestinationInfo, in2 minio.SourceInfo) error
|
|
||||||
|
|
||||||
// GetObjectFunc mocks the GetObject method.
|
// GetObjectFunc mocks the GetObject method.
|
||||||
GetObjectFunc func(in1 string, in2 string, in3 minio.GetObjectOptions) (*minio.Object, error)
|
GetObjectFunc func(in1 string, in2 string, in3 minio.GetObjectOptions) (*minio.Object, error)
|
||||||
|
|
||||||
|
@ -83,13 +76,6 @@ type S3Mock struct {
|
||||||
|
|
||||||
// calls tracks calls to the methods.
|
// calls tracks calls to the methods.
|
||||||
calls struct {
|
calls struct {
|
||||||
// CopyObject holds details about calls to the CopyObject method.
|
|
||||||
CopyObject []struct {
|
|
||||||
// In1 is the in1 argument value.
|
|
||||||
In1 minio.DestinationInfo
|
|
||||||
// In2 is the in2 argument value.
|
|
||||||
In2 minio.SourceInfo
|
|
||||||
}
|
|
||||||
// GetObject holds details about calls to the GetObject method.
|
// GetObject holds details about calls to the GetObject method.
|
||||||
GetObject []struct {
|
GetObject []struct {
|
||||||
// In1 is the in1 argument value.
|
// In1 is the in1 argument value.
|
||||||
|
@ -148,41 +134,6 @@ type S3Mock struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyObject calls CopyObjectFunc.
|
|
||||||
func (mock *S3Mock) CopyObject(in1 minio.DestinationInfo, in2 minio.SourceInfo) error {
|
|
||||||
if mock.CopyObjectFunc == nil {
|
|
||||||
panic("moq: S3Mock.CopyObjectFunc is nil but S3.CopyObject was just called")
|
|
||||||
}
|
|
||||||
callInfo := struct {
|
|
||||||
In1 minio.DestinationInfo
|
|
||||||
In2 minio.SourceInfo
|
|
||||||
}{
|
|
||||||
In1: in1,
|
|
||||||
In2: in2,
|
|
||||||
}
|
|
||||||
lockS3MockCopyObject.Lock()
|
|
||||||
mock.calls.CopyObject = append(mock.calls.CopyObject, callInfo)
|
|
||||||
lockS3MockCopyObject.Unlock()
|
|
||||||
return mock.CopyObjectFunc(in1, in2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyObjectCalls gets all the calls that were made to CopyObject.
|
|
||||||
// Check the length with:
|
|
||||||
// len(mockedS3.CopyObjectCalls())
|
|
||||||
func (mock *S3Mock) CopyObjectCalls() []struct {
|
|
||||||
In1 minio.DestinationInfo
|
|
||||||
In2 minio.SourceInfo
|
|
||||||
} {
|
|
||||||
var calls []struct {
|
|
||||||
In1 minio.DestinationInfo
|
|
||||||
In2 minio.SourceInfo
|
|
||||||
}
|
|
||||||
lockS3MockCopyObject.RLock()
|
|
||||||
calls = mock.calls.CopyObject
|
|
||||||
lockS3MockCopyObject.RUnlock()
|
|
||||||
return calls
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetObject calls GetObjectFunc.
|
// GetObject calls GetObjectFunc.
|
||||||
func (mock *S3Mock) GetObject(in1 string, in2 string, in3 minio.GetObjectOptions) (*minio.Object, error) {
|
func (mock *S3Mock) GetObject(in1 string, in2 string, in3 minio.GetObjectOptions) (*minio.Object, error) {
|
||||||
if mock.GetObjectFunc == nil {
|
if mock.GetObjectFunc == nil {
|
||||||
|
|
Loading…
Reference in a new issue