diff --git a/api/main.go b/api/main.go index edfc8a8..06cbfcd 100644 --- a/api/main.go +++ b/api/main.go @@ -80,7 +80,6 @@ func New() *WebAPI { ctx.SetStatusCode(404) _, _ = fmt.Fprintf(ctx, "Not found") } - } return api diff --git a/api/task.go b/api/task.go index b31f201..d7fefab 100644 --- a/api/task.go +++ b/api/task.go @@ -8,7 +8,6 @@ import ( "errors" "github.com/Sirupsen/logrus" "github.com/dchest/siphash" - "github.com/google/uuid" "src/task_tracker/storage" "strconv" ) @@ -114,9 +113,9 @@ func (api *WebAPI) TaskGetFromProject(r *Request) { return } - project, err := strconv.Atoi(r.Ctx.UserValue("project").(string)) + project, err := strconv.ParseInt(r.Ctx.UserValue("project").(string), 10, 64) handleErr(err, r) - task := api.Database.GetTaskFromProject(worker, int64(project)) + task := api.Database.GetTaskFromProject(worker, project) if task == nil { @@ -159,7 +158,7 @@ func (api WebAPI) validateSignature(r *Request) (*storage.Worker, error) { widStr := string(r.Ctx.Request.Header.Peek("X-Worker-Id")) signature := r.Ctx.Request.Header.Peek("X-Signature") - wid, err := uuid.Parse(widStr) + wid, err := strconv.ParseInt(widStr, 10, 64) if err != nil { logrus.WithError(err).WithFields(logrus.Fields{ "wid": widStr, @@ -219,7 +218,7 @@ func (api *WebAPI) TaskRelease(r *Request) { var req ReleaseTaskRequest if r.GetJson(&req) { - res := api.Database.ReleaseTask(req.TaskId, &worker.Id, req.Success) + res := api.Database.ReleaseTask(req.TaskId, worker.Id, req.Success) response := ReleaseTaskResponse{ Ok: res, diff --git a/api/worker.go b/api/worker.go index 8c5712f..90b10c0 100644 --- a/api/worker.go +++ b/api/worker.go @@ -2,9 +2,9 @@ package api import ( "github.com/Sirupsen/logrus" - "github.com/google/uuid" "math/rand" "src/task_tracker/storage" + "strconv" "time" ) @@ -34,8 +34,8 @@ type GetWorkerResponse struct { } type WorkerAccessRequest struct { - WorkerId *uuid.UUID `json:"worker_id"` - ProjectId int64 `json:"project_id"` + WorkerId int64 `json:"worker_id"` + ProjectId int64 `json:"project_id"` } type WorkerAccessResponse struct { @@ -79,17 +79,27 @@ func (api *WebAPI) WorkerCreate(r *Request) { func (api *WebAPI) WorkerGet(r *Request) { - id, err := uuid.Parse(r.Ctx.UserValue("id").(string)) + id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64) if err != nil { - logrus.WithFields(logrus.Fields{ + logrus.WithError(err).WithFields(logrus.Fields{ "id": id, - }).Warn("Invalid UUID") + }).Warn("Invalid worker id") r.Json(GetWorkerResponse{ Ok: false, Message: err.Error(), }, 400) return + } else if id <= 0 { + logrus.WithFields(logrus.Fields{ + "id": id, + }).Warn("Invalid worker id") + + r.Json(GetWorkerResponse{ + Ok: false, + Message: "Invalid worker id", + }, 400) + return } worker := api.Database.GetWorker(id) @@ -188,7 +198,6 @@ func (api *WebAPI) workerCreate(request *CreateWorkerRequest, identity *storage. } worker := storage.Worker{ - Id: uuid.New(), Created: time.Now().Unix(), Identity: identity, Secret: makeSecret(), diff --git a/schema.sql b/schema.sql index ff200ef..8770170 100755 --- a/schema.sql +++ b/schema.sql @@ -25,7 +25,7 @@ CREATE TABLE worker_identity CREATE TABLE worker ( - id TEXT PRIMARY KEY, + id SERIAL PRIMARY KEY, alias TEXT, created INTEGER, identity INTEGER REFERENCES worker_identity (id), @@ -46,7 +46,7 @@ CREATE TABLE project CREATE TABLE worker_has_access_to_project ( - worker TEXT REFERENCES worker (id), + worker INTEGER REFERENCES worker (id), project INTEGER REFERENCES project (id), primary key (worker, project) ); @@ -56,7 +56,7 @@ CREATE TABLE task id SERIAL PRIMARY KEY, priority INTEGER DEFAULT 0, project INTEGER REFERENCES project (id), - assignee TEXT REFERENCES worker (id), + assignee INTEGER REFERENCES worker (id), retries INTEGER DEFAULT 0, max_retries INTEGER, status Status DEFAULT 'new', diff --git a/storage/task.go b/storage/task.go index 785bcde..2851b3f 100644 --- a/storage/task.go +++ b/storage/task.go @@ -4,20 +4,19 @@ import ( "database/sql" "fmt" "github.com/Sirupsen/logrus" - "github.com/google/uuid" ) type Task struct { - Id int64 `json:"id"` - Priority int64 `json:"priority"` - Project *Project `json:"project"` - Assignee uuid.UUID `json:"assignee"` - Retries int64 `json:"retries"` - MaxRetries int64 `json:"max_retries"` - Status string `json:"status"` - Recipe string `json:"recipe"` - MaxAssignTime int64 `json:"max_assign_time"` - AssignTime int64 `json:"assign_time"` + Id int64 `json:"id"` + Priority int64 `json:"priority"` + Project *Project `json:"project"` + Assignee int64 `json:"assignee"` + Retries int64 `json:"retries"` + MaxRetries int64 `json:"max_retries"` + Status string `json:"status"` + Recipe string `json:"recipe"` + MaxAssignTime int64 `json:"max_assign_time"` + AssignTime int64 `json:"assign_time"` } func (database *Database) SaveTask(task *Task, project int64, hash64 int64) error { @@ -53,7 +52,7 @@ func (database *Database) GetTask(worker *Worker) *Task { row := db.QueryRow(` UPDATE task - SET assignee=$1 + SET assignee=$1, assign_time=extract(epoch from now() at time zone 'utc') WHERE id IN ( SELECT task.id @@ -71,7 +70,7 @@ func (database *Database) GetTask(worker *Worker) *Task { err := row.Scan(&id) if err != nil { - logrus.WithFields(logrus.Fields{ + logrus.WithError(err).WithFields(logrus.Fields{ "worker": worker, }).Trace("No task available") return nil @@ -104,7 +103,7 @@ func getTaskById(id int64, db *sql.DB) *Task { return task } -func (database Database) ReleaseTask(id int64, workerId *uuid.UUID, success bool) bool { +func (database Database) ReleaseTask(id int64, workerId int64, success bool) bool { db := database.getDB() diff --git a/storage/worker.go b/storage/worker.go index 155f551..f089297 100644 --- a/storage/worker.go +++ b/storage/worker.go @@ -4,7 +4,6 @@ import ( "database/sql" "errors" "github.com/Sirupsen/logrus" - "github.com/google/uuid" ) type Identity struct { @@ -13,7 +12,7 @@ type Identity struct { } type Worker struct { - Id uuid.UUID `json:"id"` + Id int64 `json:"id"` Created int64 `json:"created"` Identity *Identity `json:"identity"` Alias string `json:"alias,omitempty"` @@ -26,17 +25,18 @@ func (database *Database) SaveWorker(worker *Worker) { identityId := getOrCreateIdentity(worker.Identity, db) - res, err := db.Exec("INSERT INTO worker (id, created, identity, secret, alias) VALUES ($1,$2,$3,$4,$5)", - worker.Id, worker.Created, identityId, worker.Secret, worker.Alias) + row := db.QueryRow("INSERT INTO worker (created, identity, secret, alias) VALUES ($1,$2,$3,$4) RETURNING id", + worker.Created, identityId, worker.Secret, worker.Alias) + + err := row.Scan(&worker.Id) handleErr(err) - var rowsAffected, _ = res.RowsAffected() logrus.WithFields(logrus.Fields{ - "rowsAffected": rowsAffected, + "newId": worker.Id, }).Trace("Database.saveWorker INSERT worker") } -func (database *Database) GetWorker(id uuid.UUID) *Worker { +func (database *Database) GetWorker(id int64) *Worker { db := database.getDB() @@ -104,7 +104,7 @@ func getOrCreateIdentity(identity *Identity, db *sql.DB) int64 { return rowId } -func (database *Database) GrantAccess(workerId *uuid.UUID, projectId int64) bool { +func (database *Database) GrantAccess(workerId int64, projectId int64) bool { db := database.getDB() res, err := db.Exec(`INSERT INTO worker_has_access_to_project (worker, project) VALUES ($1,$2) @@ -129,7 +129,7 @@ func (database *Database) GrantAccess(workerId *uuid.UUID, projectId int64) bool return rowsAffected == 1 } -func (database *Database) RemoveAccess(workerId *uuid.UUID, projectId int64) bool { +func (database *Database) RemoveAccess(workerId int64, projectId int64) bool { db := database.getDB() res, err := db.Exec(`DELETE FROM worker_has_access_to_project WHERE worker=$1 AND project=$2`, diff --git a/test/api_task_test.go b/test/api_task_test.go index 14e3361..309f40a 100644 --- a/test/api_task_test.go +++ b/test/api_task_test.go @@ -3,7 +3,6 @@ package test import ( "encoding/json" "fmt" - "github.com/google/uuid" "io/ioutil" "src/task_tracker/api" "src/task_tracker/storage" @@ -66,9 +65,8 @@ func TestGetTaskInvalidWid(t *testing.T) { func TestGetTaskInvalidWorker(t *testing.T) { - id := uuid.New() resp := getTask(&storage.Worker{ - Id: id, + Id: -1, }) if resp.Ok != false { @@ -82,9 +80,8 @@ func TestGetTaskInvalidWorker(t *testing.T) { func TestGetTaskFromProjectInvalidWorker(t *testing.T) { - id := uuid.New() resp := getTaskFromProject(1, &storage.Worker{ - Id: id, + Id: 99999999, }) if resp.Ok != false { @@ -154,7 +151,7 @@ func TestCreateGetTask(t *testing.T) { Priority: 9999, }, worker) - taskResp := getTaskFromProject(resp.Id, genWid()) + taskResp := getTaskFromProject(resp.Id, worker) if taskResp.Ok != true { t.Error() @@ -314,8 +311,8 @@ func TestTaskNoAccess(t *testing.T) { t.Error() } - grantAccess(&worker.Id, pid) - removeAccess(&worker.Id, pid) + grantAccess(worker.Id, pid) + removeAccess(worker.Id, pid) tResp := getTaskFromProject(pid, worker) @@ -356,7 +353,7 @@ func TestTaskHasAccess(t *testing.T) { t.Error() } - grantAccess(&worker.Id, pid) + grantAccess(worker.Id, pid) tResp := getTaskFromProject(pid, worker) diff --git a/test/api_worker_test.go b/test/api_worker_test.go index 9d1f2b4..781eea0 100644 --- a/test/api_worker_test.go +++ b/test/api_worker_test.go @@ -3,7 +3,6 @@ package test import ( "encoding/json" "fmt" - "github.com/google/uuid" "io/ioutil" "net/http" "src/task_tracker/api" @@ -25,7 +24,7 @@ func TestCreateGetWorker(t *testing.T) { t.Error() } - getResp, r := getWorker(resp.Worker.Id.String()) + getResp, r := getWorker(resp.Worker.Id) if r.StatusCode != 200 { t.Error() @@ -47,7 +46,7 @@ func TestCreateGetWorker(t *testing.T) { func TestGetWorkerNotFound(t *testing.T) { - resp, r := getWorker("8bfc0ccd-d5ce-4dc5-a235-3a7ae760d9c6") + resp, r := getWorker(99999999) if r.StatusCode != 404 { t.Error() @@ -59,7 +58,7 @@ func TestGetWorkerNotFound(t *testing.T) { func TestGetWorkerInvalid(t *testing.T) { - resp, r := getWorker("invalid-uuid") + resp, r := getWorker(-1) if r.StatusCode != 400 { t.Error() @@ -76,7 +75,7 @@ func TestGrantAccessFailedProjectConstraint(t *testing.T) { wid := genWid() - resp := grantAccess(&wid.Id, 38274593) + resp := grantAccess(wid.Id, 38274593) if resp.Ok != false { t.Error() @@ -90,7 +89,7 @@ func TestRemoveAccessFailedProjectConstraint(t *testing.T) { worker := genWid() - resp := removeAccess(&worker.Id, 38274593) + resp := removeAccess(worker.Id, 38274593) if resp.Ok != false { t.Error() @@ -112,7 +111,7 @@ func TestRemoveAccessFailedWorkerConstraint(t *testing.T) { Public: true, }).Id - resp := removeAccess(&uuid.Nil, pid) + resp := removeAccess(0, pid) if resp.Ok != false { t.Error() @@ -134,7 +133,7 @@ func TestGrantAccessFailedWorkerConstraint(t *testing.T) { Public: true, }).Id - resp := removeAccess(&uuid.Nil, pid) + resp := removeAccess(0, pid) if resp.Ok != false { t.Error() @@ -156,7 +155,7 @@ func TestUpdateAliasValid(t *testing.T) { t.Error() } - w, _ := getWorker(wid.Id.String()) + w, _ := getWorker(wid.Id) if w.Worker.Alias != "new alias" { t.Error() @@ -190,9 +189,9 @@ func createWorker(req api.CreateWorkerRequest) (*api.CreateWorkerResponse, *http return resp, r } -func getWorker(id string) (*api.GetWorkerResponse, *http.Response) { +func getWorker(id int64) (*api.GetWorkerResponse, *http.Response) { - r := Get(fmt.Sprintf("/worker/get/%s", id), nil) + r := Get(fmt.Sprintf("/worker/get/%d", id), nil) var resp *api.GetWorkerResponse data, _ := ioutil.ReadAll(r.Body) @@ -208,7 +207,7 @@ func genWid() *storage.Worker { return resp.Worker } -func grantAccess(wid *uuid.UUID, project int64) *api.WorkerAccessResponse { +func grantAccess(wid int64, project int64) *api.WorkerAccessResponse { r := Post("/access/grant", api.WorkerAccessRequest{ WorkerId: wid, @@ -223,7 +222,7 @@ func grantAccess(wid *uuid.UUID, project int64) *api.WorkerAccessResponse { return resp } -func removeAccess(wid *uuid.UUID, project int64) *api.WorkerAccessResponse { +func removeAccess(wid int64, project int64) *api.WorkerAccessResponse { r := Post("/access/remove", api.WorkerAccessRequest{ WorkerId: wid, diff --git a/test/common.go b/test/common.go index d3f5f5e..bd26d30 100644 --- a/test/common.go +++ b/test/common.go @@ -12,6 +12,7 @@ import ( "net/http" "src/task_tracker/config" "src/task_tracker/storage" + "strconv" ) func Post(path string, x interface{}, worker *storage.Worker) *http.Response { @@ -27,7 +28,7 @@ func Post(path string, x interface{}, worker *storage.Worker) *http.Response { mac.Write(body) sig := hex.EncodeToString(mac.Sum(nil)) - req.Header.Add("X-Worker-Id", worker.Id.String()) + req.Header.Add("X-Worker-Id", strconv.FormatInt(worker.Id, 10)) req.Header.Add("X-Signature", sig) } @@ -51,7 +52,8 @@ func Get(path string, worker *storage.Worker) *http.Response { mac.Write([]byte(path)) sig := hex.EncodeToString(mac.Sum(nil)) - req.Header.Add("X-Worker-Id", worker.Id.String()) + fmt.Println(strconv.FormatInt(worker.Id, 10)) + req.Header.Add("X-Worker-Id", strconv.FormatInt(worker.Id, 10)) req.Header.Add("X-Signature", sig) } diff --git a/test/schema.sql b/test/schema.sql index d108236..8770170 100755 --- a/test/schema.sql +++ b/test/schema.sql @@ -25,7 +25,7 @@ CREATE TABLE worker_identity CREATE TABLE worker ( - id TEXT PRIMARY KEY, + id SERIAL PRIMARY KEY, alias TEXT, created INTEGER, identity INTEGER REFERENCES worker_identity (id), @@ -46,7 +46,7 @@ CREATE TABLE project CREATE TABLE worker_has_access_to_project ( - worker TEXT REFERENCES worker (id), + worker INTEGER REFERENCES worker (id), project INTEGER REFERENCES project (id), primary key (worker, project) ); @@ -56,14 +56,14 @@ CREATE TABLE task id SERIAL PRIMARY KEY, priority INTEGER DEFAULT 0, project INTEGER REFERENCES project (id), - assignee TEXT REFERENCES worker (id), + assignee INTEGER REFERENCES worker (id), retries INTEGER DEFAULT 0, max_retries INTEGER, status Status DEFAULT 'new', recipe TEXT, max_assign_time INTEGER DEFAULT 0, assign_time INTEGER DEFAULT 0, - hash64 BIGINT UNIQUE + hash64 BIGINT DEFAULT NULL UNIQUE ); CREATE TABLE log_entry