mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-11 19:04:35 +00:00
162 lines
4.6 KiB
Go
162 lines
4.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/micro/micro/v3/service/errors"
|
|
"github.com/micro/micro/v3/service/logger"
|
|
"github.com/micro/micro/v3/service/store"
|
|
pb "github.com/micro/services/notes/proto"
|
|
)
|
|
|
|
const storePrefix = "notes/"
|
|
|
|
// New returns an initialized notes handler
|
|
func New() pb.NotesHandler {
|
|
return new(handler)
|
|
}
|
|
|
|
type handler struct{}
|
|
|
|
// List all the notes
|
|
func (h *handler) List(ctx context.Context, req *pb.ListRequest, rsp *pb.ListResponse) error {
|
|
// query the store
|
|
recs, err := store.Read(storePrefix, store.ReadPrefix())
|
|
if err != nil {
|
|
logger.Errorf("Error reading notes from the store: %v", err)
|
|
return errors.InternalServerError("notes.List.Unknown", "Error reading from the store")
|
|
}
|
|
|
|
// serialize the response
|
|
rsp.Notes = make([]*pb.Note, len(recs))
|
|
for i, r := range recs {
|
|
var note pb.Note
|
|
if err := json.Unmarshal(r.Value, ¬e); err != nil {
|
|
logger.Errorf("Error unmarshaling note: %v", err)
|
|
return errors.InternalServerError("notes.List.Unknown", "Error unmarshaling note")
|
|
}
|
|
rsp.Notes[i] = ¬e
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Create a note
|
|
func (h *handler) Create(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error {
|
|
// validate the request
|
|
if len(req.Title) == 0 {
|
|
return errors.BadRequest("notes.Create.MissingTitle", "Missing title")
|
|
}
|
|
|
|
// construct the note
|
|
note := &pb.Note{
|
|
Id: uuid.New().String(),
|
|
Created: time.Now().Unix(),
|
|
Title: req.Title,
|
|
Text: req.Text,
|
|
}
|
|
|
|
// marshal the note to bytes
|
|
bytes, err := json.Marshal(note)
|
|
if err != nil {
|
|
logger.Errorf("Error marshaling note: %v", err)
|
|
return errors.InternalServerError("notes.Create.Unknown", "Error marshaling note")
|
|
}
|
|
|
|
// write to the store
|
|
key := storePrefix + note.Id
|
|
if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil {
|
|
logger.Errorf("Error writing to store: %v", err)
|
|
return errors.InternalServerError("notes.Create.Unknown", "Error writing to store")
|
|
}
|
|
|
|
// return the id
|
|
rsp.Id = note.Id
|
|
return nil
|
|
}
|
|
|
|
// Delete a note
|
|
func (h *handler) Delete(ctx context.Context, req *pb.DeleteRequest, rsp *pb.DeleteResponse) error {
|
|
// validate the request
|
|
if len(req.Id) == 0 {
|
|
return errors.BadRequest("notes.Delete.MissingID", "Missing id")
|
|
}
|
|
|
|
// delete the note from the store
|
|
if err := store.Delete(storePrefix + req.Id); err == store.ErrNotFound {
|
|
return errors.NotFound("notes.Delete.InvalidID", "Note not found with this ID")
|
|
} else if err != nil {
|
|
logger.Errorf("Error deleting from the store: %v", err)
|
|
return errors.InternalServerError("notes.Delete.Unknown", "Error deleting from the store")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Update a note
|
|
func (h *handler) Update(ctx context.Context, req *pb.UpdateRequest, rsp *pb.UpdateResponse) error {
|
|
// validate the request
|
|
if len(req.Id) == 0 {
|
|
return errors.BadRequest("notes.Update.MissingID", "Missing id")
|
|
}
|
|
if len(req.Title) == 0 {
|
|
return errors.BadRequest("notes.Update.MissingTitle", "Missing title")
|
|
}
|
|
|
|
// read the note from the store
|
|
recs, err := store.Read(storePrefix + req.Id)
|
|
if err == store.ErrNotFound {
|
|
return errors.NotFound("notes.Update.InvalidID", "Note not found with this ID")
|
|
} else if err != nil {
|
|
logger.Errorf("Error reading from the store: %v", err)
|
|
return errors.InternalServerError("notes.Update.Unknown", "Error reading from the store")
|
|
}
|
|
|
|
// unmarshal the note
|
|
var note pb.Note
|
|
if err := json.Unmarshal(recs[0].Value, ¬e); err != nil {
|
|
logger.Errorf("Error unmarshaling note: %v", err)
|
|
return errors.InternalServerError("notes.Update.Unknown", "Error unmarshaling note")
|
|
}
|
|
|
|
// assign the new title and text
|
|
note.Title = req.Title
|
|
note.Text = req.Text
|
|
|
|
// marshal the note to bytes
|
|
bytes, err := json.Marshal(note)
|
|
if err != nil {
|
|
logger.Errorf("Error marshaling note: %v", err)
|
|
return errors.InternalServerError("notes.Update.Unknown", "Error marshaling note")
|
|
}
|
|
|
|
// write to the store
|
|
key := storePrefix + note.Id
|
|
if err := store.Write(&store.Record{Key: key, Value: bytes}); err != nil {
|
|
logger.Errorf("Error writing to store: %v", err)
|
|
return errors.InternalServerError("notes.Update.Unknown", "Error writing to store")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// UpdateStream updates a note every time an update is sent on the stream
|
|
func (h *handler) UpdateStream(ctx context.Context, stream pb.Notes_UpdateStreamStream) error {
|
|
for {
|
|
uReq, err := stream.Recv()
|
|
if err == io.EOF {
|
|
return nil
|
|
} else if err != nil {
|
|
return errors.InternalServerError("notes.UpdateStream.Unknown", "Error reading from stream")
|
|
}
|
|
|
|
if err := h.Update(ctx, uReq, nil); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|