udemy-go-microservices/broker-service/cmd/api/handlers.go

215 lines
4.6 KiB
Go
Raw Normal View History

2024-08-28 07:28:34 +00:00
package main
import (
"broker/cmd/api/event"
2024-08-28 19:40:50 +00:00
"bytes"
"encoding/json"
"errors"
"log"
2024-08-28 07:28:34 +00:00
"net/http"
)
2024-08-28 19:40:50 +00:00
type RequestPayload struct {
Action string `string:"action"`
2024-08-29 12:28:30 +00:00
Auth AuthPayload `json:"auth,omitempty"`
Log LogPayload `json:"log,omitempty"`
2024-09-02 19:32:59 +00:00
Mail MailPayload `json:"mail,omitempty"`
2024-08-28 19:40:50 +00:00
}
type AuthPayload struct {
Email string `json:"email"`
Password string `json:"password"`
}
2024-08-29 12:28:30 +00:00
type LogPayload struct {
Name string `json:"name"`
Data string `json:"data"`
}
2024-09-02 19:32:59 +00:00
type MailPayload struct {
From string `json:"from"`
To string `json:"to"`
Subject string `json:"subject"`
Content string `json:"content"`
}
2024-08-28 07:28:34 +00:00
func (app *Config) Broker(w http.ResponseWriter, r *http.Request) {
payload := jsonResponse{
Error: false,
Message: "Hit the broker",
}
2024-08-28 08:04:52 +00:00
app.writeJSON(w, http.StatusOK, payload)
2024-08-28 07:28:34 +00:00
}
2024-08-28 19:40:50 +00:00
func (app *Config) HandleSubmission(w http.ResponseWriter, r *http.Request) {
var requestPayload RequestPayload
err := app.readJSON(w, r, &requestPayload)
if err != nil {
app.errorJSON(w, err, http.StatusBadRequest)
return
}
switch requestPayload.Action {
case "auth":
app.authenticate(w, requestPayload.Auth)
2024-08-29 12:28:30 +00:00
case "log":
// app.LogItem(w, requestPayload.Log)
app.logEventViaRabbit(w, requestPayload.Log)
2024-09-02 19:32:59 +00:00
case "mail":
app.SendMail(w, requestPayload.Mail)
2024-08-28 19:40:50 +00:00
default:
app.errorJSON(w, errors.New("unknown action"))
}
}
func (app *Config) authenticate(w http.ResponseWriter, a AuthPayload) {
2024-08-29 12:28:30 +00:00
authService := Microservice{
Input: a,
Addr: "http://authentication-service/authenticate",
ErrCode: statusError{
2024-08-31 20:56:25 +00:00
ExpectedCode: http.StatusAccepted,
ErrCode: http.StatusUnauthorized,
Err: errors.New("invalid credentials"),
2024-08-29 12:28:30 +00:00
},
SuccessMsg: "Authenticated",
}
app.callService(w, authService)
}
func (app *Config) LogItem(w http.ResponseWriter, entry LogPayload) {
2024-08-31 20:56:25 +00:00
log.Println(entry)
2024-08-29 12:28:30 +00:00
loggerService := Microservice{
Input: entry,
Addr: "http://logger-service/log",
ErrCode: statusError{
2024-08-31 20:56:25 +00:00
ExpectedCode: http.StatusAccepted,
ErrCode: http.StatusInternalServerError,
Err: errors.New("internal error"),
2024-08-29 12:28:30 +00:00
},
SuccessMsg: "Logged!",
}
app.callService(w, loggerService)
}
2024-09-02 19:32:59 +00:00
func (app *Config) SendMail(w http.ResponseWriter, entry MailPayload) {
log.Println(entry)
mailService := Microservice{
Input: entry,
Addr: "http://mail-service/send-mail",
ErrCode: statusError{
ExpectedCode: http.StatusAccepted,
ErrCode: http.StatusInternalServerError,
Err: errors.New("internal error"),
},
SuccessMsg: "Mail sent!",
}
app.callService(w, mailService)
}
2024-08-29 12:28:30 +00:00
type statusError struct {
2024-08-31 20:56:25 +00:00
ExpectedCode int
ErrCode int
Err error
2024-08-29 12:28:30 +00:00
}
type Microservice struct {
Input any
Addr string
ErrCode statusError
SuccessMsg string
}
func (app *Config) callService(w http.ResponseWriter, ms Microservice) {
// create some json we'll send to the microservice
inputPayload, err := json.MarshalIndent(ms.Input, "", "\t")
2024-08-28 19:40:50 +00:00
if err != nil {
app.errorJSON(w, err, http.StatusBadRequest)
return
}
2024-08-31 20:56:25 +00:00
log.Println(ms.Input)
2024-08-28 19:40:50 +00:00
// call the service
req, err := http.NewRequest(
"POST",
2024-08-29 12:28:30 +00:00
ms.Addr,
bytes.NewBuffer(inputPayload),
2024-08-28 19:40:50 +00:00
)
if err != nil {
app.errorJSON(w, err, http.StatusBadRequest)
return
}
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
app.errorJSON(w, err, http.StatusInternalServerError)
return
}
defer resp.Body.Close()
log.Println(resp.Body)
// make sure we get back the correct status code
2024-08-31 20:56:25 +00:00
if resp.StatusCode != ms.ErrCode.ExpectedCode {
app.errorJSON(w, ms.ErrCode.Err, ms.ErrCode.ErrCode)
2024-08-28 19:40:50 +00:00
return
}
// create a variable we'll read resp.Body into
var respPayload jsonResponse
err = json.NewDecoder(resp.Body).Decode(&respPayload)
if err != nil {
app.errorJSON(w, err, http.StatusBadRequest)
return
}
if respPayload.Error {
2024-08-29 12:28:30 +00:00
app.errorJSON(w, errors.New(respPayload.Message))
2024-08-28 19:40:50 +00:00
return
}
var payload jsonResponse
payload.Error = false
2024-08-29 12:28:30 +00:00
payload.Message = ms.SuccessMsg
2024-08-28 19:40:50 +00:00
payload.Data = respPayload.Data
app.writeJSON(w, http.StatusOK, payload)
}
func (app *Config) logEventViaRabbit(w http.ResponseWriter, l LogPayload) {
err := app.pushToQueue(l.Name, l.Data)
if err != nil {
app.errorJSON(w, err)
return
}
var payload jsonResponse
payload.Error = false
payload.Message = "logged via RabbitMQ"
app.writeJSON(w, http.StatusOK, payload)
}
func (app *Config) pushToQueue(name, msg string) error {
emitter, err := event.NewEmitter(app.Rabbit)
if err != nil {
return err
}
payload := LogPayload{
Name: name,
Data: msg,
}
j, _ := json.MarshalIndent(&payload, "", "\t")
err = emitter.Push(string(j), "log.INFO")
if err != nil {
return err
}
return nil
}