Skip to content

Commit

Permalink
Merge pull request #10 from PickHD/SRS-06
Browse files Browse the repository at this point in the history
SRS-06
  • Loading branch information
PickHD committed May 8, 2023
2 parents e8e8339 + 47681d0 commit c654c0f
Show file tree
Hide file tree
Showing 16 changed files with 456 additions and 36 deletions.
15 changes: 10 additions & 5 deletions auth/internal/v1/model/user.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package model

import "go.mongodb.org/mongo-driver/bson/primitive"
import (
"time"

"go.mongodb.org/mongo-driver/bson/primitive"
)

type (
// User consist data of users
User struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
FullName string `bson:"fullname,omitempty"`
Email string `bson:"email,omitempty"`
Password string `bson:"password,omitempty"`
ID primitive.ObjectID `bson:"_id,omitempty"`
FullName string `bson:"fullname,omitempty"`
Email string `bson:"email,omitempty"`
Password string `bson:"password,omitempty"`
CreatedAt time.Time `bson:"created_at,omitempty"`
}
)
8 changes: 5 additions & 3 deletions auth/internal/v1/repository/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package repository

import (
"context"
"time"

"github.com/PickHD/singkatin-revamp/auth/internal/v1/config"
"github.com/PickHD/singkatin-revamp/auth/internal/v1/model"
Expand Down Expand Up @@ -44,9 +45,10 @@ func (ar *AuthRepositoryImpl) CreateUser(ctx context.Context, req *model.User) (
// if doc not exists, create new one
if err == mongo.ErrNoDocuments {
res, err := ar.DB.Collection(ar.Config.Database.UsersCollection).InsertOne(ctx, model.User{
FullName: req.FullName,
Email: req.Email,
Password: req.Password,
FullName: req.FullName,
Email: req.Email,
Password: req.Password,
CreatedAt: time.Now(),
})
if err != nil {
ar.Logger.Error("AuthRepositoryImpl.CreateUser InsertOne ERROR, ", err)
Expand Down
11 changes: 10 additions & 1 deletion shortener/cmd/v1/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ func main() {
app.Logger.Error("Error received by channel", err)
}
case consumerMode:
infrastructure.ConsumeMessages(app, app.Config.RabbitMQ.QueueCreateShortener)
// Make a channel to receive messages into infinite loop.
forever := make(chan bool)

queues := []string{app.Config.RabbitMQ.QueueCreateShortener, app.Config.RabbitMQ.QueueUpdateVisitor}

for _, q := range queues {
go infrastructure.ConsumeMessages(app, q)
}

<-forever
}
}
49 changes: 49 additions & 0 deletions shortener/docs/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 49 additions & 0 deletions shortener/docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,55 @@
}
}
}
},
"/{short_url}": {
"get": {
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Shortener"
],
"summary": "Click Shorteners URL",
"parameters": [
{
"type": "string",
"description": "short urls",
"name": "short_url",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/helper.BaseResponse"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/helper.BaseResponse"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/helper.BaseResponse"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/helper.BaseResponse"
}
}
}
}
}
},
"definitions": {
Expand Down
32 changes: 32 additions & 0 deletions shortener/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ info:
title: Singkatin Revamp API
version: "1.0"
paths:
/{short_url}:
get:
consumes:
- application/json
parameters:
- description: short urls
in: path
name: short_url
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/helper.BaseResponse'
"400":
description: Bad Request
schema:
$ref: '#/definitions/helper.BaseResponse'
"404":
description: Not Found
schema:
$ref: '#/definitions/helper.BaseResponse'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/helper.BaseResponse'
summary: Click Shorteners URL
tags:
- Shortener
/health-check:
get:
consumes:
Expand Down
2 changes: 1 addition & 1 deletion shortener/internal/v1/application/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func SetupApplication(ctx context.Context) (*App, error) {
app.Application = echo.New()
app.Application.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, echo.HeaderAuthorization},
}))

app.GRPC = grpc.NewServer()
Expand Down
2 changes: 1 addition & 1 deletion shortener/internal/v1/application/dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Dependency struct {
func SetupDependencyInjection(app *App) *Dependency {
// repository
healthCheckRepoImpl := repository.NewHealthCheckRepository(app.Context, app.Config, app.Logger, app.DB, app.Redis)
shortRepoImpl := repository.NewShortRepository(app.Context, app.Config, app.Logger, app.DB)
shortRepoImpl := repository.NewShortRepository(app.Context, app.Config, app.Logger, app.DB, app.Redis, app.RabbitMQ)

// service
healthCheckSvcImpl := service.NewHealthCheckService(app.Context, app.Config, healthCheckRepoImpl)
Expand Down
2 changes: 1 addition & 1 deletion shortener/internal/v1/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func loadConfiguration() *Configuration {
RabbitMQ: &RabbitMQ{
ConnURL: helper.GetEnvString("AMQP_SERVER_URL"),
QueueCreateShortener: helper.GetEnvString("AMQP_QUEUE_CREATE_SHORTENER"),
QueueUpdateVisitor: helper.GetEnvString("AMQP_QUEUE_UPDATE_VISITOR"),
QueueUpdateVisitor: helper.GetEnvString("AMQP_QUEUE_UPDATE_VISITOR_COUNT"),
},
}
}
Expand Down
48 changes: 48 additions & 0 deletions shortener/internal/v1/controller/short.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package controller

import (
"context"
"net/http"
"strings"

"github.com/PickHD/singkatin-revamp/shortener/internal/v1/config"
"github.com/PickHD/singkatin-revamp/shortener/internal/v1/helper"
"github.com/PickHD/singkatin-revamp/shortener/internal/v1/model"
"github.com/PickHD/singkatin-revamp/shortener/internal/v1/service"
shortenerpb "github.com/PickHD/singkatin-revamp/shortener/pkg/api/v1/proto/shortener"
"github.com/labstack/echo/v4"
"github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand All @@ -15,8 +19,15 @@ import (
type (
// ShortController is an interface that has all the function to be implemented inside short controller
ShortController interface {
// grpc
GetListShortenerByUserID(ctx context.Context, req *shortenerpb.ListShortenerRequest) (*shortenerpb.ListShortenerResponse, error)

// http
ClickShortener(ctx echo.Context) error

// rabbitmq
ProcessCreateShortUser(ctx context.Context, req *model.CreateShortRequest) error
ProcessUpdateVisitorCount(ctx context.Context, req *model.UpdateVisitorRequest) error
}

// ShortControllerImpl is an app short struct that consists of all the dependencies needed for short controller
Expand Down Expand Up @@ -65,6 +76,34 @@ func (sc *ShortControllerImpl) GetListShortenerByUserID(ctx context.Context, req
}, nil
}

// Check godoc
// @Summary Click Shorteners URL
// @Tags Shortener
// @Accept json
// @Produce json
// @Param short_url path string true "short urls"
// @Success 200 {object} helper.BaseResponse
// @Failure 400 {object} helper.BaseResponse
// @Failure 404 {object} helper.BaseResponse
// @Failure 500 {object} helper.BaseResponse
// @Router /{short_url} [get]
func (sc *ShortControllerImpl) ClickShortener(ctx echo.Context) error {
data, err := sc.ShortSvc.ClickShort(ctx.Param("short_url"))
if err != nil {
if strings.Contains(err.Error(), string(model.Validation)) {
return helper.NewResponses[any](ctx, http.StatusBadRequest, err.Error(), ctx.Param("short_url"), err, nil)
}

if strings.Contains(err.Error(), string(model.NotFound)) {
return helper.NewResponses[any](ctx, http.StatusNotFound, err.Error(), ctx.Param("short_url"), err, nil)
}

return helper.NewResponses[any](ctx, http.StatusInternalServerError, "failed click shortener", ctx.Param("short_url"), err, nil)
}

return ctx.Redirect(http.StatusTemporaryRedirect, data.FullURL)
}

func (sc *ShortControllerImpl) ProcessCreateShortUser(ctx context.Context, req *model.CreateShortRequest) error {
err := sc.ShortSvc.CreateShort(ctx, req)
if err != nil {
Expand All @@ -73,3 +112,12 @@ func (sc *ShortControllerImpl) ProcessCreateShortUser(ctx context.Context, req *

return nil
}

func (sc *ShortControllerImpl) ProcessUpdateVisitorCount(ctx context.Context, req *model.UpdateVisitorRequest) error {
err := sc.ShortSvc.UpdateVisitorShort(ctx, req)
if err != nil {
return model.NewError(model.Internal, err.Error())
}

return nil
}
2 changes: 2 additions & 0 deletions shortener/internal/v1/infrastructure/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ func setupRouter(app *application.App) {
v1.GET("/swagger/*any", echoSwagger.WrapHandler)

v1.GET("/health-check", dep.HealthCheckController.Check)

v1.GET("/:short_url", dep.ShortController.ClickShortener)
}

}
27 changes: 20 additions & 7 deletions shortener/internal/v1/infrastructure/rabbitmq.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ package infrastructure

import (
"encoding/json"
"fmt"

"github.com/PickHD/singkatin-revamp/shortener/internal/v1/application"
"github.com/PickHD/singkatin-revamp/shortener/internal/v1/model"
)

// ConsumeMessages generic function to consume message from defined param queues
func ConsumeMessages(app *application.App, queueName string) {
dep := application.SetupDependencyInjection(app)

Expand All @@ -26,9 +28,6 @@ func ConsumeMessages(app *application.App, queueName string) {

app.Logger.Info("Waiting Message in Queues ", queueName, ".....")

// Make a channel to receive messages into infinite loop.
forever := make(chan bool)

go func() {
for msg := range messages {
switch queueName {
Expand All @@ -40,18 +39,32 @@ func ConsumeMessages(app *application.App, queueName string) {
app.Logger.Error("Unmarshal JSON ERROR, ", err)
}

app.Logger.Info("Success Consume Message :", req)
app.Logger.Info(fmt.Sprintf("[%s] Success Consume Message :", queueName), req)

err = dep.ShortController.ProcessCreateShortUser(app.Context, &req)
if err != nil {
app.Logger.Error("ProcessCreateShortUser ERROR, ", err)
}

app.Logger.Info("Success Process Message : ", req)
app.Logger.Info(fmt.Sprintf("[%s] Success Process Message :", queueName), req)
case app.Config.RabbitMQ.QueueUpdateVisitor:
var req model.UpdateVisitorRequest

err := json.Unmarshal(msg.Body, &req)
if err != nil {
app.Logger.Error("Unmarshal JSON ERROR, ", err)
}

app.Logger.Info(fmt.Sprintf("[%s] Success Consume Message :", queueName), req)

err = dep.ShortController.ProcessUpdateVisitorCount(app.Context, &req)
if err != nil {
app.Logger.Error("ProcessUpdateVisitorCount ERROR, ", err)
}

app.Logger.Info(fmt.Sprintf("[%s] Success Process Message :", queueName), req)

}
}
}()

<-forever
}
5 changes: 5 additions & 0 deletions shortener/internal/v1/model/key.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package model

const (
KeyShortURL = "short_url:%s"
)
Loading

0 comments on commit c654c0f

Please sign in to comment.