Skip to content

Commit 6fcc36d

Browse files
committed
feat: Use standard server setup
1 parent 7d06707 commit 6fcc36d

10 files changed

Lines changed: 78 additions & 141 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ settings.yaml
2929
__debug_bin*
3030
*.code-workspace
3131
.history/
32+
.env
3233

3334

cmd/fetch-api/main.go

Lines changed: 21 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@ package main
22

33
import (
44
"context"
5+
"errors"
56
"flag"
6-
"fmt"
7-
"net"
87
"os"
98
"os/signal"
109
"strconv"
1110

1211
_ "github.com/DIMO-Network/fetch-api/docs"
1312
"github.com/DIMO-Network/fetch-api/internal/app"
1413
"github.com/DIMO-Network/fetch-api/internal/config"
15-
"github.com/DIMO-Network/shared/pkg/settings"
16-
"github.com/gofiber/fiber/v2"
17-
"github.com/gofiber/fiber/v2/middleware/adaptor"
18-
"github.com/prometheus/client_golang/prometheus/promhttp"
19-
"github.com/rs/zerolog"
14+
"github.com/DIMO-Network/server-garage/pkg/env"
15+
"github.com/DIMO-Network/server-garage/pkg/logging"
16+
"github.com/DIMO-Network/server-garage/pkg/monserver"
17+
"github.com/DIMO-Network/server-garage/pkg/runner"
2018
"golang.org/x/sync/errgroup"
21-
"google.golang.org/grpc"
2219
)
2320

2421
// @title DIMO Fetch API
@@ -27,81 +24,38 @@ import (
2724
// @in header
2825
// @name Authorization
2926
func main() {
30-
logger := zerolog.New(os.Stdout).With().Timestamp().Str("app", "fetch-api").Logger()
31-
// create a flag for the settings file
32-
settingsFile := flag.String("settings", "settings.yaml", "settings file")
27+
settingsFile := flag.String("env", ".env", "env file")
3328
flag.Parse()
34-
settings, err := settings.LoadConfig[config.Settings](*settingsFile)
29+
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
30+
defer cancel()
31+
logger := logging.GetAndSetDefaultLogger("fetch-api")
32+
settings, err := env.LoadSettings[config.Settings](*settingsFile)
3533
if err != nil {
3634
logger.Fatal().Err(err).Msg("Couldn't load settings.")
3735
}
38-
webServer, err := app.CreateWebServer(&logger, &settings)
36+
webServer, err := app.CreateWebServer(&settings)
3937
if err != nil {
4038
logger.Fatal().Err(err).Msg("Failed to create web server.")
4139
}
4240
rpcServer, err := app.CreateGRPCServer(&logger, &settings)
4341
if err != nil {
4442
logger.Fatal().Err(err).Msg("Failed to create RPC server.")
4543
}
46-
47-
monApp := CreateMonitoringServer(strconv.Itoa(settings.MonPort), &logger)
48-
49-
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
50-
defer cancel()
51-
5244
group, gCtx := errgroup.WithContext(ctx)
5345

54-
logger.Info().Str("port", strconv.Itoa(settings.GRPCPort)).Msgf("Starting gRPC server")
55-
runGRPC(gCtx, rpcServer, ":"+strconv.Itoa(settings.GRPCPort), group)
46+
monApp := monserver.NewMonitoringServer(&logger, settings.EnablePprof)
5647
logger.Info().Str("port", strconv.Itoa(settings.MonPort)).Msgf("Starting monitoring server")
57-
runFiber(gCtx, monApp, ":"+strconv.Itoa(settings.MonPort), group)
48+
runner.RunHandler(gCtx, group, monApp, ":"+strconv.Itoa(settings.MonPort))
49+
5850
logger.Info().Str("port", strconv.Itoa(settings.Port)).Msgf("Starting web server")
59-
runFiber(gCtx, webServer, ":"+strconv.Itoa(settings.Port), group)
51+
runner.RunFiber(gCtx, group, webServer, ":"+strconv.Itoa(settings.Port))
52+
53+
logger.Info().Str("port", strconv.Itoa(settings.GRPCPort)).Msgf("Starting gRPC server")
54+
runner.RunGRPC(gCtx, group, rpcServer, ":"+strconv.Itoa(settings.GRPCPort))
6055

6156
err = group.Wait()
62-
if err != nil {
63-
logger.Fatal().Err(err).Msg("Failed to run servers.")
57+
if err != nil && !errors.Is(err, context.Canceled) {
58+
logger.Fatal().Err(err).Msg("Server shut down due to an error.")
6459
}
65-
}
66-
67-
func runFiber(ctx context.Context, fiberApp *fiber.App, addr string, group *errgroup.Group) {
68-
group.Go(func() error {
69-
if err := fiberApp.Listen(addr); err != nil {
70-
return fmt.Errorf("failed to start server: %w", err)
71-
}
72-
return nil
73-
})
74-
group.Go(func() error {
75-
<-ctx.Done()
76-
if err := fiberApp.Shutdown(); err != nil {
77-
return fmt.Errorf("failed to shutdown server: %w", err)
78-
}
79-
return nil
80-
})
81-
}
82-
83-
func runGRPC(ctx context.Context, grpcServer *grpc.Server, addr string, group *errgroup.Group) {
84-
group.Go(func() error {
85-
lis, err := net.Listen("tcp", addr)
86-
if err != nil {
87-
return fmt.Errorf("failed to listen on gRPC port %s: %w", addr, err)
88-
}
89-
if err := grpcServer.Serve(lis); err != nil {
90-
return fmt.Errorf("gRPC server failed to serve: %w", err)
91-
}
92-
return nil
93-
})
94-
group.Go(func() error {
95-
<-ctx.Done()
96-
grpcServer.GracefulStop()
97-
return nil
98-
})
99-
}
100-
101-
func CreateMonitoringServer(port string, logger *zerolog.Logger) *fiber.App {
102-
monApp := fiber.New(fiber.Config{DisableStartupMessage: true})
103-
monApp.Get("/", func(c *fiber.Ctx) error { return nil })
104-
monApp.Get("/metrics", adaptor.HTTPHandler(promhttp.Handler()))
105-
106-
return monApp
60+
logger.Info().Msg("Server shut down.")
10761
}

go.mod

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ require (
66
github.com/ClickHouse/clickhouse-go/v2 v2.40.1
77
github.com/DIMO-Network/clickhouse-infra v0.0.5
88
github.com/DIMO-Network/cloudevent v0.1.3
9+
github.com/DIMO-Network/server-garage v0.0.4
910
github.com/DIMO-Network/shared v1.0.7
1011
github.com/aws/aws-sdk-go-v2 v1.38.0
1112
github.com/aws/aws-sdk-go-v2/credentials v1.18.2
@@ -29,7 +30,6 @@ require (
2930

3031
require (
3132
github.com/ClickHouse/ch-go v0.67.0 // indirect
32-
github.com/DIMO-Network/yaml v0.1.0 // indirect
3333
github.com/KyleBanks/depth v1.2.1 // indirect
3434
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
3535
github.com/PuerkitoBio/purell v1.1.1 // indirect
@@ -45,6 +45,7 @@ require (
4545
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.3 // indirect
4646
github.com/aws/smithy-go v1.22.5 // indirect
4747
github.com/beorn7/perks v1.0.1 // indirect
48+
github.com/caarlos0/env/v11 v11.3.1 // indirect
4849
github.com/cespare/xxhash/v2 v2.3.0 // indirect
4950
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
5051
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
@@ -58,16 +59,16 @@ require (
5859
github.com/go-openapi/swag v0.19.15 // indirect
5960
github.com/google/uuid v1.6.0 // indirect
6061
github.com/holiman/uint256 v1.3.2 // indirect
62+
github.com/joho/godotenv v1.5.1 // indirect
6163
github.com/josharian/intern v1.0.0 // indirect
6264
github.com/klauspost/compress v1.18.0 // indirect
6365
github.com/mailru/easyjson v0.7.6 // indirect
64-
github.com/mattn/go-colorable v0.1.13 // indirect
66+
github.com/mattn/go-colorable v0.1.14 // indirect
6567
github.com/mattn/go-isatty v0.0.20 // indirect
6668
github.com/mattn/go-runewidth v0.0.16 // indirect
6769
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
6870
github.com/paulmach/orb v0.11.1 // indirect
6971
github.com/pierrec/lz4/v4 v4.1.22 // indirect
70-
github.com/pkg/errors v0.9.1 // indirect
7172
github.com/pmezard/go-difflib v1.0.0 // indirect
7273
github.com/prometheus/client_model v0.6.2 // indirect
7374
github.com/prometheus/common v0.65.0 // indirect

go.sum

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ github.com/DIMO-Network/clickhouse-infra v0.0.5 h1:zY1STwb9+vovpYXdjaeakE29pgZPI
1414
github.com/DIMO-Network/clickhouse-infra v0.0.5/go.mod h1:XS80lhSJNWBWGgZ+m4j7++zFj1wAXfmtV2gJfhGlabQ=
1515
github.com/DIMO-Network/cloudevent v0.1.3 h1:jsQCcVdZuARCobgalrsrV99mjtGlN7igh8f24xqzeDA=
1616
github.com/DIMO-Network/cloudevent v0.1.3/go.mod h1:Aaqfcg9FQod0CbsbPIz+8Ykr0udL0jNpO8AABPqEMaQ=
17+
github.com/DIMO-Network/server-garage v0.0.4 h1:K0wnQ2vJAtyK8lbINxKneVyqELORAu4Ut1ePZ3yb8cI=
18+
github.com/DIMO-Network/server-garage v0.0.4/go.mod h1:bdj0wKTjozjjD2w7Htk/rnzOv+jH+iBrhCuXOP/H00s=
1719
github.com/DIMO-Network/shared v1.0.7 h1:LfSgsqJ6R7EUyfo2GTfuhrCpoDcweJqe7eVOa4j7Xbo=
1820
github.com/DIMO-Network/shared v1.0.7/go.mod h1:lDHUKwwT2LW6Zvd42Nb33dXklRNTmfyOlbUNx2dQfGY=
19-
github.com/DIMO-Network/yaml v0.1.0 h1:KQ3oKHUZETchR6Pxbmmol3e4ewrPv/q8cEwqxfwyZbU=
20-
github.com/DIMO-Network/yaml v0.1.0/go.mod h1:KkiehcbkVzH8Pf8f9dja8B2aW81gYYZSqfwzSj9yN68=
2121
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
2222
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
2323
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
@@ -57,6 +57,8 @@ github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp
5757
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
5858
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
5959
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
60+
github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA=
61+
github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U=
6062
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
6163
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
6264
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -166,6 +168,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy
166168
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
167169
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
168170
github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
171+
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
172+
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
169173
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
170174
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
171175
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -191,8 +195,9 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
191195
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
192196
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
193197
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
194-
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
195198
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
199+
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
200+
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
196201
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
197202
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
198203
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=

internal/app/app.go

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package app
22

33
import (
4-
"errors"
54
"fmt"
65
"net/http"
76
"strconv"
8-
"strings"
97

108
"github.com/DIMO-Network/fetch-api/internal/config"
119
"github.com/DIMO-Network/fetch-api/internal/fetch/httphandler"
1210
"github.com/DIMO-Network/fetch-api/internal/fetch/rpc"
1311
"github.com/DIMO-Network/fetch-api/pkg/auth"
1412
fetchgrpc "github.com/DIMO-Network/fetch-api/pkg/grpc"
13+
"github.com/DIMO-Network/server-garage/pkg/fibercommon"
1514
"github.com/DIMO-Network/shared/pkg/middleware/metrics"
1615
"github.com/DIMO-Network/shared/pkg/middleware/privilegetoken"
1716
"github.com/DIMO-Network/shared/pkg/privileges"
@@ -30,18 +29,17 @@ import (
3029
)
3130

3231
// CreateWebServer creates a new web server with the given logger and settings.
33-
func CreateWebServer(logger *zerolog.Logger, settings *config.Settings) (*fiber.App, error) {
32+
func CreateWebServer(settings *config.Settings) (*fiber.App, error) {
3433
chainId, err := strconv.ParseUint(settings.ChainID, 10, 64)
3534
if err != nil {
3635
return nil, fmt.Errorf("failed to parse chain ID: %w", err)
3736
}
3837

3938
app := fiber.New(fiber.Config{
40-
ErrorHandler: func(c *fiber.Ctx, err error) error {
41-
return ErrorHandler(c, err, logger)
42-
},
39+
ErrorHandler: fibercommon.ErrorHandler,
4340
DisableStartupMessage: true,
4441
})
42+
app.Use(fibercommon.ContextLoggerMiddleware)
4543

4644
jwtAuth := jwtware.New(jwtware.Config{
4745
JWKSetURLs: []string{settings.TokenExchangeJWTKeySetURL},
@@ -76,7 +74,7 @@ func CreateWebServer(logger *zerolog.Logger, settings *config.Settings) (*fiber.
7674
}
7775

7876
s3Client := s3ClientFromSettings(settings)
79-
vehHandler := httphandler.NewHandler(logger, chConn, s3Client,
77+
vehHandler := httphandler.NewHandler(chConn, s3Client,
8078
[]string{settings.CloudEventBucket, settings.EphemeralBucket, settings.VCBucket}, settings.VehicleNFTAddress, chainId)
8179
// File endpoints
8280
vehicleGroup.Post("/latest-index-key/:tokenId", vehiclePriv, jwtAuth, vehHandler.GetLatestIndexKey)
@@ -113,33 +111,6 @@ func CreateGRPCServer(logger *zerolog.Logger, settings *config.Settings) (*grpc.
113111
return server, nil
114112
}
115113

116-
// ErrorHandler custom handler to log recovered errors using our logger and return json instead of string
117-
func ErrorHandler(ctx *fiber.Ctx, err error, logger *zerolog.Logger) error {
118-
code := fiber.StatusInternalServerError // Default 500 statuscode
119-
message := "Internal error."
120-
121-
var e *fiber.Error
122-
if errors.As(err, &e) {
123-
code = e.Code
124-
message = e.Message
125-
}
126-
127-
// don't log not found errors
128-
if code != fiber.StatusNotFound {
129-
logger.Err(err).Int("httpStatusCode", code).
130-
Str("httpPath", strings.TrimPrefix(ctx.Path(), "/")).
131-
Str("httpMethod", ctx.Method()).
132-
Msg("caught an error from http request")
133-
}
134-
135-
return ctx.Status(code).JSON(codeResp{Code: code, Message: message})
136-
}
137-
138-
type codeResp struct {
139-
Message string `json:"message"`
140-
Code int `json:"code"`
141-
}
142-
143114
// HealthCheck godoc
144115
// @Summary Show the status of server.
145116
// @Description get the status of server.

internal/config/settings.go

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ import (
88

99
// Settings contains the application config.
1010
type Settings struct {
11-
Port int `yaml:"PORT"`
12-
MonPort int `yaml:"MON_PORT"`
13-
GRPCPort int `yaml:"GRPC_PORT"`
14-
TokenExchangeJWTKeySetURL string `yaml:"TOKEN_EXCHANGE_JWK_KEY_SET_URL"`
15-
TokenExchangeIssuer string `yaml:"TOKEN_EXCHANGE_ISSUER_URL"`
16-
VehicleNFTAddress common.Address `yaml:"VEHICLE_NFT_ADDRESS"`
17-
ChainID string `yaml:"CHAIN_ID"`
18-
CloudEventBucket string `yaml:"CLOUDEVENT_BUCKET"`
19-
EphemeralBucket string `yaml:"EPHEMERAL_BUCKET"`
20-
VCBucket string `yaml:"VC_BUCKET"`
21-
S3AWSRegion string `yaml:"S3_AWS_REGION"`
22-
S3AWSAccessKeyID string `yaml:"S3_AWS_ACCESS_KEY_ID"`
23-
S3AWSSecretAccessKey string `yaml:"S3_AWS_SECRET_ACCESS_KEY"`
24-
Clickhouse config.Settings `yaml:",inline"`
11+
Port int `env:"PORT"`
12+
MonPort int `env:"MON_PORT"`
13+
GRPCPort int `env:"GRPC_PORT"`
14+
EnablePprof bool `env:"ENABLE_PPROF"`
15+
TokenExchangeJWTKeySetURL string `env:"TOKEN_EXCHANGE_JWK_KEY_SET_URL"`
16+
TokenExchangeIssuer string `env:"TOKEN_EXCHANGE_ISSUER_URL"`
17+
VehicleNFTAddress common.Address `env:"VEHICLE_NFT_ADDRESS"`
18+
ChainID string `env:"CHAIN_ID"`
19+
CloudEventBucket string `env:"CLOUDEVENT_BUCKET"`
20+
EphemeralBucket string `env:"EPHEMERAL_BUCKET"`
21+
VCBucket string `env:"VC_BUCKET"`
22+
S3AWSRegion string `env:"S3_AWS_REGION"`
23+
S3AWSAccessKeyID string `env:"S3_AWS_ACCESS_KEY_ID"`
24+
S3AWSSecretAccessKey string `env:"S3_AWS_SECRET_ACCESS_KEY"`
25+
Clickhouse config.Settings `env:",inline"`
2526
}

0 commit comments

Comments
 (0)