chanched handlers

This commit is contained in:
2023-08-12 19:26:50 +03:00
parent 85f4b92fa7
commit 17a09f7fb3
28 changed files with 503 additions and 1001 deletions

View File

@@ -1,26 +0,0 @@
package encoders
import (
"encoding/json"
"net/http"
pb "go.unistack.org/unistack-org/pkgdash/proto"
"github.com/pkg/errors"
)
type JSON struct{}
func (*JSON) Success(rw http.ResponseWriter, response interface{}) error {
rw.Header().Set("Content-Type", "application/json; charset=utf-8")
rw.WriteHeader(http.StatusOK)
return errors.WithStack(json.NewEncoder(rw).Encode(response))
}
func (*JSON) Error(rw http.ResponseWriter, err *pb.Error, status int) error {
rw.Header().Set("Content-Type", "application/problem+json; charset=utf-8")
rw.WriteHeader(status)
return errors.WithStack(json.NewEncoder(rw).Encode(&pb.ErrorRsp{Error: err}))
}

View File

@@ -1,51 +0,0 @@
package encoders
import (
"github.com/pkg/errors"
pb "go.unistack.org/unistack-org/pkgdash/proto"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
"io"
"net/http"
)
var ErrWrongResponseType = errors.New("JSONProto: wrong response message type")
type JSONProto struct {
m protojson.MarshalOptions
}
func NewJSONProto() *JSONProto {
return &JSONProto{m: protojson.MarshalOptions{
EmitUnpopulated: true,
UseProtoNames: false,
}}
}
func (e *JSONProto) Success(rw http.ResponseWriter, response interface{}) error {
rw.Header().Set("Content-Type", "application/json; charset=utf-8")
rw.WriteHeader(http.StatusOK)
if v, ok := response.(proto.Message); ok {
return errors.WithStack(e.Fmarshal(rw, v))
}
return ErrWrongResponseType
}
func (e *JSONProto) Error(rw http.ResponseWriter, err *pb.Error, status int) error {
rw.Header().Set("Content-Type", "application/problem+json; charset=utf-8")
rw.WriteHeader(status)
return errors.WithStack(e.Fmarshal(rw, &pb.ErrorRsp{Error: err}))
}
func (e *JSONProto) Fmarshal(w io.Writer, m proto.Message) error {
b, err := e.m.Marshal(m)
if len(b) > 0 {
if _, err = w.Write(b); err != nil {
return err
}
}
return err
}

View File

@@ -1,6 +1,16 @@
package handler
import "github.com/pkg/errors"
import (
"github.com/google/uuid"
"github.com/pkg/errors"
pb "go.unistack.org/unistack-org/pkgdash/proto"
)
const (
badRequest = `Bad Requet`
internalError = `Internal Error`
notFound = `Source Not Found`
)
type UnmarshalError struct {
err error
@@ -18,16 +28,15 @@ func NewUnmarshalError(err error) error {
return errors.WithStack(&UnmarshalError{err: err})
}
type InternalError struct {
Err error
}
func (e *InternalError) Error() string {
return e.Err.Error()
}
func NewInternalError(err error) error {
return errors.WithStack(&InternalError{Err: err})
func NewInternalError(err error) *pb.ErrorRsp {
return &pb.ErrorRsp{
Error: &pb.Error{
Code: internalErrorCode,
Title: internalError,
Uuid: uuid.New().String(),
Details: err.Error(),
},
}
}
type ParametersMissingError struct {
@@ -42,26 +51,24 @@ func NewParametersMissingError(err error) error {
return errors.WithStack(&ParametersMissingError{Err: err})
}
type NotFoundError struct {
Err error
func NewNotFoundError(err error) *pb.ErrorRsp {
return &pb.ErrorRsp{
Error: &pb.Error{
Code: notFoundErrorCode,
Title: notFound,
Uuid: uuid.New().String(),
Details: err.Error(),
},
}
}
func (e *NotFoundError) Error() string {
return e.Err.Error()
}
func NewNotFoundError(err error) error {
return errors.WithStack(&NotFoundError{Err: err})
}
type ValidationError struct {
Err error
}
func (e *ValidationError) Error() string {
return e.Err.Error()
}
func NewValidationError(err error) error {
return errors.WithStack(&ValidationError{Err: err})
func NewValidationError(err error) *pb.ErrorRsp {
return &pb.ErrorRsp{
Error: &pb.Error{
Code: badRequestCode,
Title: badRequest,
Uuid: uuid.New().String(),
Details: err.Error(),
},
}
}

View File

@@ -2,20 +2,18 @@ package handler
import (
"context"
"encoding/json"
"io"
"net/http"
"net/url"
"database/sql"
"errors"
cmsstorage "go.unistack.org/cms-service/storage"
httpsrv "go.unistack.org/micro-server-http/v4"
"go.unistack.org/micro/v4"
"go.unistack.org/micro/v4/errors"
"go.unistack.org/unistack-org/pkgdash/config"
pb "go.unistack.org/unistack-org/pkgdash/proto"
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"
"google.golang.org/protobuf/types/known/emptypb"
"net/http"
)
type Handler struct {
@@ -30,119 +28,80 @@ type Handler struct {
chanUrl chan *pb.AddPackageReq
}
func (h *Handler) ListPackage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
func (h *Handler) ListPackage(ctx context.Context, _ *emptypb.Empty, rsp *pb.ListPackageRsp) error {
logger := h.svc.Logger()
logger.Debug(ctx, "Start getListPackage")
dbRsp, err := h.store.ListPackage(ctx)
if err != nil {
logger.Errorf(ctx, "error db response: %v", err)
h.writer.Response(ctx, w, err)
return
httpsrv.SetRspCode(ctx, http.StatusInternalServerError)
return httpsrv.SetError(NewInternalError(err))
}
rsp := new(pb.ListPackageRsp)
//rsp = new(pb.ListPackageRsp)
rsp.Packages = dbRsp.Decode()
logger.Debug(ctx, "Success finish getListPackage")
h.writer.Response(ctx, w, rsp)
return nil
}
func (h *Handler) UpdatePackage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
func (h *Handler) UpdatePackage(ctx context.Context, req *pb.UpdatePackageReq, rsp *pb.UpdatePackageRsp) error {
logger := h.svc.Logger()
logger.Debug(ctx, "Start UpdatePackage")
defer r.Body.Close()
all, err := io.ReadAll(r.Body)
if err != nil {
if err := req.Validate(); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
httpsrv.SetRspCode(ctx, http.StatusBadRequest)
return httpsrv.SetError(NewValidationError(err))
}
req := new(pb.UpdatePackageReq)
if err = h.Unmarshal(all, req); err != nil {
if err := h.store.UpdatePackage(ctx, req); err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewUnmarshalError(err))
return
httpsrv.SetRspCode(ctx, http.StatusInternalServerError)
return httpsrv.SetError(NewInternalError(err))
}
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
}
rsp.Id = req.Id
logger.Debug(ctx, "Success finish UpdatePackage")
return nil
}
func (h *Handler) AddComment(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
func (h *Handler) AddComment(ctx context.Context, req *pb.AddCommentReq, rsp *pb.AddCommentRsp) error {
logger := h.svc.Logger()
logger.Debug(ctx, "Start AddComment")
defer r.Body.Close()
all, err := io.ReadAll(r.Body)
err := req.Validate()
if err != nil {
logger.Error(ctx, err)
h.writer.Response(ctx, w, NewInternalError(err))
return
httpsrv.SetRspCode(ctx, http.StatusBadRequest)
return httpsrv.SetError(NewValidationError(err))
}
req := new(pb.AddCommentReq)
if err = h.Unmarshal(all, req); err != nil {
if rsp.Id, err = h.store.AddComment(ctx, 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
if errors.Is(err, sql.ErrNoRows) {
httpsrv.SetRspCode(ctx, http.StatusNotFound)
return httpsrv.SetError(NewNotFoundError(err))
}
httpsrv.SetRspCode(ctx, http.StatusInternalServerError)
return httpsrv.SetError(NewInternalError(err))
}
logger.Debug(ctx, "Success finish addComment")
return nil
}
func (h *Handler) AddPackage(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
func (h *Handler) AddPackage(ctx context.Context, req *pb.AddPackageReq, rsp *pb.AddPackageRsp) error {
logger := h.svc.Logger()
logger.Debug(ctx, "Start AddPackage")
defer r.Body.Close()
all, err := io.ReadAll(r.Body)
err := req.Validate()
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
httpsrv.SetRspCode(ctx, http.StatusBadRequest)
return httpsrv.SetError(NewValidationError(err))
}
if h.git.IsClose() {
@@ -151,69 +110,40 @@ func (h *Handler) AddPackage(w http.ResponseWriter, r *http.Request) {
h.chanUrl <- req
}
rsp.Status = "Sent"
logger.Debug(ctx, "Success finish addPackage")
return nil
}
func (h *Handler) GetModule(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
func (h *Handler) GetModule(ctx context.Context, req *pb.GetModuleReq, rsp *pb.GetModuleRsp) error {
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
httpsrv.SetRspCode(ctx, http.StatusInternalServerError)
return httpsrv.SetError(NewInternalError(err))
}
rsp := &pb.GetModuleRsp{Modules: modules.Decode()}
h.writer.Response(ctx, w, rsp)
rsp.Modules = modules.Decode()
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 {
func NewHandler(svc micro.Service, client cligit.Client) *Handler {
h := &Handler{
svc: svc,
writer: w,
git: client,
svc: svc,
git: client,
}
h.EmitUnpopulated = true
h.UseProtoNames = false
return h
}
// TODO add conn db
func (h *Handler) Init(ctx context.Context) error {
store := cmsstorage.InterfaceFromContext(h.svc.Options().Context)
if store == nil {