add handlers, storage(Postgres, sqlite) (#3)

Reviewed-on: #3
Co-authored-by: Evstigneev Denis <danteevstigneev@yandex.ru>
Co-committed-by: Evstigneev Denis <danteevstigneev@yandex.ru>
This commit is contained in:
2023-08-11 20:12:15 +03:00
committed by Vasiliy Tolstov
parent b0f76d9bac
commit 8886dcba9c
35 changed files with 2751 additions and 936 deletions

View File

@@ -2,14 +2,19 @@ package handler
import (
"context"
"encoding/json"
cmsstorage "go.unistack.org/cms-service/storage"
"go.unistack.org/micro/v3"
"go.unistack.org/micro/v3/errors"
"go.unistack.org/unistack-org/pkgdash/config"
"go.unistack.org/unistack-org/pkgdash/models"
pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate"
cligit "go.unistack.org/unistack-org/pkgdash/service/client_git"
"go.unistack.org/unistack-org/pkgdash/storage"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"io"
"net/http"
"net/url"
)
type Handler struct {
@@ -17,6 +22,11 @@ type Handler struct {
store storage.Storage
writer writer
protojson.MarshalOptions
protojson.UnmarshalOptions
git cligit.Client
chanUrl chan *pb.AddPackageReq
}
func (h *Handler) ListPackage(w http.ResponseWriter, r *http.Request) {
@@ -24,7 +34,7 @@ func (h *Handler) ListPackage(w http.ResponseWriter, r *http.Request) {
logger := h.svc.Logger()
logger.Debug(ctx, "Start getListPackage")
dbRsp, err := h.store.List(ctx)
dbRsp, err := h.store.ListPackage(ctx)
if err != nil {
logger.Errorf(ctx, "error db response: %v", err)
h.writer.Response(ctx, w, err)
@@ -32,18 +42,45 @@ func (h *Handler) ListPackage(w http.ResponseWriter, r *http.Request) {
}
rsp := new(pb.ListPackageRsp)
rsp.Packages = models.ListPackage(dbRsp).Mapping()
rsp.Packages = dbRsp.Decode()
logger.Debug(ctx, "Success finish getListPackage")
h.writer.Response(ctx, w, rsp)
}
func (h *Handler) UpdateInfo(w http.ResponseWriter, r *http.Request) {
func (h *Handler) UpdatePackage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := h.svc.Logger()
logger.Debug(ctx, "Start UpdateInfo")
logger.Debug(ctx, "Start UpdatePackage")
// TODO
defer r.Body.Close()
all, err := io.ReadAll(r.Body)
if err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
}
req := new(pb.UpdatePackageReq)
if err = h.Unmarshal(all, req); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewUnmarshalError(err))
return
}
if err = req.Validate(); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewValidationError(err))
return
}
if err = h.store.UpdatePackage(ctx, req); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
}
logger.Debug(ctx, "Success finish UpdatePackage")
}
func (h *Handler) AddComment(w http.ResponseWriter, r *http.Request) {
@@ -51,11 +88,129 @@ func (h *Handler) AddComment(w http.ResponseWriter, r *http.Request) {
logger := h.svc.Logger()
logger.Debug(ctx, "Start AddComment")
// TODO
defer r.Body.Close()
all, err := io.ReadAll(r.Body)
if err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
}
req := new(pb.AddCommentReq)
if err = h.Unmarshal(all, req); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewUnmarshalError(err))
return
}
if err = req.Validate(); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewValidationError(err))
return
}
if err = h.store.AddComment(ctx, req); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
}
logger.Debug(ctx, "Success finish addComment")
}
func NewHandler(svc micro.Service, w writer) *Handler {
return &Handler{svc: svc, writer: w}
func (h *Handler) AddPackage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := h.svc.Logger()
logger.Debug(ctx, "Start AddPackage")
defer r.Body.Close()
all, err := io.ReadAll(r.Body)
if err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
}
req := new(pb.AddPackageReq)
if err = h.Unmarshal(all, req); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewUnmarshalError(err))
return
}
if err = req.Validate(); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewValidationError(err))
return
}
if h.git.IsClose() {
logger.Error(ctx, "chan is closed")
} else {
h.chanUrl <- req
}
logger.Debug(ctx, "Success finish addPackage")
}
func (h *Handler) GetModule(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
logger := h.svc.Logger()
logger.Debug(ctx, "Start GetModule")
req := new(pb.GetModuleReq)
if err := URLValuesToProto(r.URL.Query(), req); err != nil {
logger.Errorf(ctx, "Required parameter missing: %v", err)
h.writer.Response(ctx, w, err)
return
}
modules, err := h.store.GetModule(ctx, req)
if err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
}
rsp := &pb.GetModuleRsp{Modules: modules.Decode()}
h.writer.Response(ctx, w, rsp)
logger.Debug(ctx, "Success finish getModule")
}
func URLValuesToProto(vals url.Values, msg proto.Message) error {
params := make(map[string]interface{})
var err error
for k, v := range vals {
if len(v) == 0 {
continue
}
switch k {
case "id[]":
params[k] = v
default:
params[k] = v[0]
}
}
b, err := json.Marshal(params)
if err != nil {
return NewUnmarshalError(err)
}
if err = protojson.Unmarshal(b, msg); err != nil {
return NewUnmarshalError(err)
}
return nil
}
func NewHandler(svc micro.Service, w writer, client cligit.Client) *Handler {
h := &Handler{
svc: svc,
writer: w,
git: client,
}
h.EmitUnpopulated = true
h.UseProtoNames = false
return h
}
func (h *Handler) Init(ctx context.Context) error {
@@ -68,6 +223,8 @@ func (h *Handler) Init(ctx context.Context) error {
return errors.New(config.ServiceName, "error init storage", 1)
}
h.chanUrl = h.git.Run(ctx, st)
h.store = st
return nil

21
handler/middleware.go Normal file
View File

@@ -0,0 +1,21 @@
package handler
import "net/http"
func Methods(m string, next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
if req.Method != m {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
switch req.Method {
case http.MethodPost:
w.WriteHeader(http.StatusCreated)
case http.MethodPut:
w.WriteHeader(http.StatusNoContent)
}
next.ServeHTTP(w, req)
}
}

View File

@@ -2,7 +2,7 @@ package handler
import (
"context"
"go.unistack.org/micro/v4/logger"
"go.unistack.org/micro/v3/logger"
pb "go.unistack.org/unistack-org/pkgdash/proto/go_generate"
"net/http"
@@ -18,6 +18,7 @@ type writer interface {
Response(ctx context.Context, rw http.ResponseWriter, value interface{})
}
// nolint
type stackTracer interface {
StackTrace() errors.StackTrace
}