Skip to content

Commit

Permalink
Merge pull request #25 from MowlCoder/iter25
Browse files Browse the repository at this point in the history
Iter25
  • Loading branch information
MowlCoder committed Dec 30, 2023
2 parents c8bbaeb + d34ab10 commit 96a64ef
Show file tree
Hide file tree
Showing 28 changed files with 2,910 additions and 494 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ commit = $(shell git rev-parse HEAD)
ifeq ($(OS), Windows_NT)
build_date = $(shell date /t)
else
build_date = $(shell date)
build_date = $(shell date -I)
endif
ldflags = "-X main.buildCommit=$(commit) -X main.buildDate=$(build_date) -X main.buildVersion=$(build_version)"

Expand Down
72 changes: 60 additions & 12 deletions cmd/shortener/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"log"
"math/rand"
"net"
"net/http"
"os"
"os/signal"
Expand All @@ -15,15 +16,19 @@ import (
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/joho/godotenv"
"google.golang.org/grpc"

_ "github.com/jackc/pgx/v5/stdlib"

"github.com/MowlCoder/go-url-shortener/internal/config"
"github.com/MowlCoder/go-url-shortener/internal/handlers"
grpcHandlers "github.com/MowlCoder/go-url-shortener/internal/handlers/grpc"
httpHandlers "github.com/MowlCoder/go-url-shortener/internal/handlers/http"
"github.com/MowlCoder/go-url-shortener/internal/interceptors"
"github.com/MowlCoder/go-url-shortener/internal/logger"
customMiddlewares "github.com/MowlCoder/go-url-shortener/internal/middlewares"
"github.com/MowlCoder/go-url-shortener/internal/services"
"github.com/MowlCoder/go-url-shortener/internal/storage"
"github.com/MowlCoder/go-url-shortener/proto"
)

var (
Expand Down Expand Up @@ -64,19 +69,31 @@ func main() {
stringGeneratorService := services.NewStringGenerator()
userService := services.NewUserService()
deleteURLQueue := services.NewDeleteURLQueue(urlStorage, customLogger, 3)

shortenerHandler := handlers.NewShortenerHandler(
appConfig,
shortenerService := services.NewShortenerService(
urlStorage,
stringGeneratorService,
deleteURLQueue,
)

router := makeRouter(
shortenerHandler,
httpShortenerHandler := httpHandlers.NewShortenerHandler(
appConfig,
shortenerService,
)
grpcShortenerHandler := grpcHandlers.NewShortenerHandler(
appConfig,
shortenerService,
)

httpRouter := makeRouter(
httpShortenerHandler,
userService,
customLogger,
gzipWriter,
appConfig,
)
grpcServer := makeGRPCServer(
grpcShortenerHandler,
userService,
)

workersCtx, workersStopCtx := context.WithCancel(context.Background())
Expand All @@ -86,25 +103,37 @@ func main() {
log.Println("URL Shortener server is running on", appConfig.BaseHTTPAddr)
log.Println("Config:", appConfig)

server := http.Server{
httpServer := http.Server{
Addr: appConfig.BaseHTTPAddr,
Handler: router,
Handler: httpRouter,
}

go func() {
var err error

if appConfig.EnableHTTPS {
err = server.ListenAndServeTLS(appConfig.SSLPemPath, appConfig.SSLKeyPath)
err = httpServer.ListenAndServeTLS(appConfig.SSLPemPath, appConfig.SSLKeyPath)
} else {
err = server.ListenAndServe()
err = httpServer.ListenAndServe()
}

if err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()

go func() {
listen, err := net.Listen("tcp", appConfig.BaseGRPCAddr)
if err != nil {
log.Fatal(err)
}

log.Println("gRPC server started on", appConfig.BaseGRPCAddr)
if err := grpcServer.Serve(listen); err != nil {
log.Fatal(err)
}
}()

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGINT)
<-sigs
Expand All @@ -121,10 +150,11 @@ func main() {
}
}()

if err := server.Shutdown(shutdownCtx); err != nil {
if err := httpServer.Shutdown(shutdownCtx); err != nil {
log.Fatal(err)
}

grpcServer.Stop()
workersStopCtx()

log.Println("graceful shutdown server successfully")
Expand All @@ -135,10 +165,11 @@ func main() {
// @description URL shortener helps to work with long urls, allow to save your long url and give you a small url, that point to your long url
// @BasePath /
func makeRouter(
shortenerHandler *handlers.ShortenerHandler,
shortenerHandler *httpHandlers.ShortenerHandler,
userService *services.UserService,
customLogger *logger.Logger,
gzipWriter *gzip.Writer,
appConfig *config.AppConfig,
) http.Handler {
mux := chi.NewRouter()

Expand All @@ -152,6 +183,11 @@ func makeRouter(
return customMiddlewares.AuthMiddleware(handler, userService)
})

mux.Group(func(privateRouter chi.Router) {
privateRouter.Use(customMiddlewares.TrustedSubnetsMiddleware(appConfig.TrustedSubnet))
privateRouter.Get("/api/internal/stats", shortenerHandler.GetStats)
})

mux.Post("/api/shorten/batch", shortenerHandler.ShortBatchURL)
mux.Post("/api/shorten", shortenerHandler.ShortURLJSON)
mux.Post("/", shortenerHandler.ShortURL)
Expand All @@ -163,6 +199,18 @@ func makeRouter(
return mux
}

func makeGRPCServer(
shortenerHandler *grpcHandlers.ShortenerHandler,
userService *services.UserService,
) *grpc.Server {
grpcServer := grpc.NewServer(
grpc.UnaryInterceptor(interceptors.CreateAuthInterceptor(userService)),
)
proto.RegisterShortenerServer(grpcServer, shortenerHandler)

return grpcServer
}

func displayBuildInfo() {
if buildVersion == "" {
buildVersion = "N/A"
Expand Down
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ require (
go.uber.org/mock v0.3.0
go.uber.org/zap v1.25.0
golang.org/x/tools v0.15.0
google.golang.org/grpc v1.60.1
google.golang.org/protobuf v1.32.0
honnef.co/go/tools v0.4.6
)

Expand All @@ -37,6 +39,7 @@ require (
github.com/go-toolsmith/astp v1.1.0 // indirect
github.com/go-toolsmith/strparse v1.1.0 // indirect
github.com/go-toolsmith/typep v1.1.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.4.2 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
Expand All @@ -58,6 +61,7 @@ require (
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.14.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUN
github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
Expand Down Expand Up @@ -195,6 +199,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
4 changes: 4 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import (
// and configurable variables for application.
type AppConfig struct {
BaseHTTPAddr string `env:"SERVER_ADDRESS" json:"base_http_addr"`
BaseGRPCAddr string `env:"GRPC_SERVER_ADDRESS" json:"base_grpc_addr"`
BaseShortURLAddr string `env:"BASE_URL" json:"base_url"`
AppEnvironment string `env:"APP_ENV" json:"app_env"`
FileStoragePath string `env:"FILE_STORAGE_PATH" json:"file_storage_path"`
DatabaseDSN string `env:"DATABASE_DSN" json:"database_dsn"`
EnableHTTPS bool `env:"ENABLE_HTTPS" json:"enable_https"`
SSLKeyPath string `env:"SSL_KEY_PATH" json:"ssl_key_path"`
SSLPemPath string `env:"SSL_PEM_PATH" json:"ssl_pem_path"`
TrustedSubnet string `env:"TRUSTED_SUBNET" json:"trusted_subnet"`
}

// Available environments.
Expand All @@ -34,12 +36,14 @@ func (appConfig *AppConfig) ParseFlags() {
var configPath string
flag.StringVar(&configPath, "c", "", "Path to config file")
flag.StringVar(&appConfig.BaseHTTPAddr, "a", "localhost:8080", "Base http address that server running on")
flag.StringVar(&appConfig.BaseGRPCAddr, "ga", ":3200", "Base grpc address that server running on")
flag.StringVar(&appConfig.BaseShortURLAddr, "b", "http://localhost:8080", "Base short url address")
flag.StringVar(&appConfig.FileStoragePath, "f", "/tmp/short-url-db.json", "Storage file path")
flag.StringVar(&appConfig.DatabaseDSN, "d", "", "Database DSN")
flag.BoolVar(&appConfig.EnableHTTPS, "s", false, "Enable HTTPS")
flag.StringVar(&appConfig.SSLKeyPath, "sslk", "./certs/server.key", "Path to ssl key file")
flag.StringVar(&appConfig.SSLPemPath, "sslp", "./certs/server.pem", "Path to ssl pem file")
flag.StringVar(&appConfig.TrustedSubnet, "t", "", "Trusted subnet in CIDR format")
flag.Parse()

if configPathFromEnv, ok := os.LookupEnv("CONFIG"); ok {
Expand Down
21 changes: 21 additions & 0 deletions internal/domain/shortener.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
package domain

// ShortenedURL is model of shortened url. Use model to store data in storages.
type ShortenedURL struct {
ShortURL string `json:"short_url"`
OriginalURL string `json:"original_url"`
UserID string `json:"user_id"`
ID int `json:"id"`
IsDeleted bool `json:"is_deleted"`
}

// SaveShortURLDto contains info about short url saving to pass around layers.
type SaveShortURLDto struct {
OriginalURL string `json:"original_url"`
ShortURL string `json:"short_url"`
UserID string `json:"user_id"`
}

// InternalStats contains internal stats about system state
type InternalStats struct {
URLs int `json:"urls"`
Users int `json:"users"`
}

type ShortBatchURL struct {
CorrelationID string `json:"correlation_id"`
OriginalURL string `json:"original_url"`
ShortURL string `json:"short_url"`
}

0 comments on commit 96a64ef

Please sign in to comment.