This commit is contained in:
Dennis Coyle 2018-04-25 10:55:26 -04:00
parent 074b8bc96b
commit bb8d4f8d22
16 changed files with 42 additions and 251 deletions

11
.travis.yml Normal file
View File

@ -0,0 +1,11 @@
language: go
go:
- 1.10.x
- tip
before_install:
- make build-dev-deps
- go get -u golang.org/x/vgo
- vgo install

View File

@ -1,14 +1,17 @@
.PHONY: test lint
lint: check-copyrights
@echo "Running ${@}"
@gometalinter.v2 \
@gometalinter \
--deadline=60s \
--disable-all \
--enable=golint \
--enable=goimports \
--enable=vet \
--enable=deadcode \
--enable=gosimple \
--enable=goconst \
--exclude=.*\.pb\.go \
--exclude=.*_test.go \
./...
check-copyrights:
@ -23,5 +26,8 @@ proto:
build-dev-deps:
go get -u github.com/golang/protobuf/protoc-gen-go
go get -u gopkg.in/alecthomas/gometalinter.v2
gometalinter.v2 --install
go get -u github.com/alecthomas/gometalinter
gometalinter --install --force
test:
go test -v ./...

View File

@ -1,11 +0,0 @@
# build
FROM golang:alpine AS build-env
ADD . /go/src/research/lang/storj-node-go/
RUN cd /go/src/research/lang/storj-node-go/ && go build -o main
# final stage
FROM alpine
WORKDIR /app
COPY --from=build-env /go/src/research/lang/storj-node-go/main /app/
ENTRYPOINT ./main

View File

@ -1,45 +0,0 @@
package main
import (
"fmt"
"github.com/kataras/iris"
"github.com/storj/storj/routes"
"github.com/storj/storj/storage/boltdb"
)
func main() {
bdb, err := boltdb.New()
if err != nil {
fmt.Println(err)
return
}
defer bdb.DB.Close()
users := routes.Users{DB: bdb}
app := iris.Default()
SetRoutes(app, users)
app.Run(iris.Addr(":8080"))
}
// SetRoutes defines all restful routes on the service
func SetRoutes(app *iris.Application, users routes.Users) {
app.Post("/users/:id", users.CreateUser)
app.Get("/users/:id", users.GetUser)
app.Put("/users/:id/:email", users.UpdateUser)
app.Delete("/users/:id", users.DeleteUser)
// app.Get("/users/confirmations/:token", users.Confirm)
// app.Get("/files?startDate=<timestamp>?tag=<tag>", files.ListFiles)
// app.Get("/file-ids/:name", files.GetFileId)
// app.Get("/files/:file?skip=<number>&limit=<number>&exclude=<node-ids>", files.GetPointers)
// app.Delete("/files/:file", files.DeleteFile)
// app.Post("/files", files.NewFile)
// app.Put("/files/:file/shards/:index", files.AddShardToFile)
// app.Post("/reports", reports.CreateReport)
// app.Get("/contacts?address=<address>&skip=<number>&limit=<number>", contacts.GetContacts)
}

View File

@ -33,6 +33,7 @@ func main() {
}
}
// Main is the exported CLI executable function
func Main() error {
encKey := sha256.Sum256([]byte(*key))
fc, err := infectious.NewFEC(*rsk, *rsn)

View File

@ -27,6 +27,7 @@ func main() {
}
}
// Main is the exported CLI executable function
func Main() error {
pieces, err := ioutil.ReadDir(flag.Arg(0))
if err != nil {

View File

@ -42,6 +42,7 @@ func main() {
}
}
// Main is the exported CLI executable function
func Main() error {
encKey := sha256.Sum256([]byte(*key))
fc, err := infectious.NewFEC(*rsk, *rsn)

View File

@ -36,6 +36,7 @@ func main() {
}
}
// Main is the exported CLI executable function
func Main() error {
err := os.MkdirAll(flag.Arg(0), 0755)
if err != nil {

View File

@ -141,7 +141,7 @@ func ServeContent(w http.ResponseWriter, r *http.Request, name string,
w.WriteHeader(code)
if r.Method != "HEAD" {
if r.Method != http.MethodHead {
r := sendContent()
defer r.Close()
io.CopyN(w, r, sendSize)
@ -178,7 +178,7 @@ func checkPreconditions(w http.ResponseWriter, r *http.Request,
}
switch checkIfNoneMatch(w, r) {
case condFalse:
if r.Method == "GET" || r.Method == "HEAD" {
if r.Method == http.MethodGet || r.Method == http.MethodHead {
writeNotModified(w)
return true, ""
}
@ -284,7 +284,7 @@ func checkIfNoneMatch(w http.ResponseWriter, r *http.Request) condResult {
}
func checkIfModifiedSince(r *http.Request, modtime time.Time) condResult {
if r.Method != "GET" && r.Method != "HEAD" {
if r.Method != http.MethodGet && r.Method != http.MethodHead {
return condNone
}
ims := r.Header.Get("If-Modified-Since")
@ -305,7 +305,7 @@ func checkIfModifiedSince(r *http.Request, modtime time.Time) condResult {
func checkIfRange(w http.ResponseWriter, r *http.Request, modtime time.Time) (
rv condResult) {
if r.Method != "GET" && r.Method != "HEAD" {
if r.Method != http.MethodGet && r.Method != http.MethodHead {
return condNone
}
ir := r.Header.Get("If-Range")
@ -419,6 +419,7 @@ func parseRange(s string, size int64) ([]httpRange, error) {
if !strings.HasPrefix(s, b) {
return nil, errors.New("invalid range")
}
var ranges []httpRange
noOverlap := false
for _, ra := range strings.Split(s[len(b):], ",") {

View File

@ -8,10 +8,10 @@ import (
"os"
)
// FileHandleRanger returns a RangerCloser from a file handle. The
// RangerCloser's Close method will call fh.Close().
// FileHandleRanger returns a Closer from a file handle. The
// Closer's Close method will call fh.Close().
// Footgun: If FileHandleRanger fails, fh.Close will not have been called.
func FileHandleRanger(fh *os.File) (RangerCloser, error) {
func FileHandleRanger(fh *os.File) (Closer, error) {
stat, err := fh.Stat()
if err != nil {
return nil, Error.Wrap(err)
@ -25,8 +25,8 @@ func FileHandleRanger(fh *os.File) (RangerCloser, error) {
}, nil
}
// FileRanger returns a RangerCloser from a path.
func FileRanger(path string) (RangerCloser, error) {
// FileRanger returns a Closer from a path.
func FileRanger(path string) (Closer, error) {
fh, err := os.Open(path)
if err != nil {
return nil, err

View File

@ -19,15 +19,15 @@ type Ranger interface {
Range(offset, length int64) io.ReadCloser
}
// A RangerCloser is a Ranger that must be closed when finished
type RangerCloser interface {
// A Closer is a Ranger that must be closed when finished
type Closer interface {
Ranger
io.Closer
}
// NopCloser makes an existing Ranger function as a RangerCloser
// NopCloser makes an existing Ranger function as a Closer
// with a no-op for Close()
func NopCloser(r Ranger) RangerCloser {
func NopCloser(r Ranger) Closer {
return struct {
Ranger
io.Closer

View File

@ -1,64 +0,0 @@
package routes
import (
"log"
"github.com/google/uuid"
"github.com/kataras/iris"
"github.com/storj/storj/storage/boltdb"
)
// Users contains items needed to process requests to the user namespace
type Users struct {
DB *boltdb.Client
}
func (u *Users) CreateUser(ctx iris.Context) {
user := boltdb.User{
Id: uuid.New(),
Username: ctx.Params().Get("id"),
Email: `dece@trali.zzd`,
}
if err := ctx.ReadJSON(user); err != nil {
ctx.JSON(iris.StatusNotAcceptable)
}
u.DB.CreateUser(user)
}
func (u *Users) GetUser(ctx iris.Context) {
userId := ctx.Params().Get("id")
userInfo, err := u.DB.GetUser([]byte(userId))
if err != nil {
log.Println(err)
}
ctx.Writef("%s's info is: %s", userId, userInfo)
}
// Updates only email for now
// Uses two db queries now, can refactor
func (u *Users) UpdateUser(ctx iris.Context) {
userId := ctx.Params().Get("id")
userInfo, err := u.DB.GetUser([]byte(userId))
if err != nil {
log.Println(err)
}
updated := boltdb.User{
Id: userInfo.Id,
Username: userInfo.Username,
Email: ctx.Params().Get("email"),
}
err1 := u.DB.UpdateUser(updated)
if err1 != nil {
log.Println(err)
}
}
func (u *Users) DeleteUser(ctx iris.Context) {
userId := ctx.Params().Get("id")
u.DB.DeleteUser([]byte(userId))
}

View File

@ -1,40 +0,0 @@
package boltdb
import (
"time"
"github.com/boltdb/bolt"
)
var defaultTimeout = 1 * time.Second
// Client is the storage interface for the Bolt database
type Client struct {
DB *bolt.DB
UsersBucket *bolt.Bucket
}
// New instantiates a new BoltDB client
func New() (*Client, error) {
db, err := bolt.Open("my.db", 0600, &bolt.Options{Timeout: defaultTimeout})
if err != nil {
return nil, err
}
b := &bolt.Bucket{}
err = db.Update(func(tx *bolt.Tx) error {
b, err = tx.CreateBucketIfNotExists([]byte("users"))
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &Client{
DB: db,
}, nil
}

View File

@ -1,5 +0,0 @@
package boltdb
type Contact struct {
Id int64 `json:"id"`
}

View File

@ -1,69 +0,0 @@
package boltdb
import (
"encoding/json"
"log"
"github.com/boltdb/bolt"
"github.com/google/uuid"
)
type User struct {
Id uuid.UUID `json:"id"`
Email string `json:"email"`
Username string `json:"username"`
}
// CreateUser calls bolt database instance to create user
func (bdb *Client) CreateUser(user User) error {
return bdb.DB.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("users"))
usernameKey := []byte(user.Username)
userBytes, err := json.Marshal(user)
if err != nil {
log.Println(err)
}
return b.Put(usernameKey, userBytes)
})
}
func (bdb *Client) GetUser(key []byte) (User, error) {
var userInfo User
err := bdb.DB.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("users"))
v := b.Get(key)
if v == nil {
log.Println("user not found")
return nil
} else {
err1 := json.Unmarshal(v, &userInfo)
return err1
}
})
return userInfo, err
}
func (bdb *Client) UpdateUser(user User) error {
return bdb.DB.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("users"))
usernameKey := []byte(user.Username)
userBytes, err := json.Marshal(user)
if err != nil {
log.Println(err)
}
return b.Put(usernameKey, userBytes)
})
}
func (bdb *Client) DeleteUser(key []byte) {
if err := bdb.DB.Update(func(tx *bolt.Tx) error {
return tx.Bucket([]byte("users")).Delete(key)
}); err != nil {
log.Println(err)
}
}

View File

@ -15,7 +15,10 @@ type mockRedisClient struct {
pingCalled int
}
// ErrMissingKey is the error returned if a key is not in the mock store
var ErrMissingKey = errors.New("missing")
// ErrForced is the error returned when the forced error flag is passed to mock an error
var ErrForced = errors.New("error forced by using 'error' key in mock")
func (m *mockRedisClient) Get(key string) ([]byte, error) {