forked from ambrosus/airdao-wallet-api
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d7abe02
Showing
28 changed files
with
2,046 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
vendor/ | ||
|
||
# IDEs and editors | ||
/.idea | ||
.idea | ||
|
||
# IDE - VSCode | ||
.vscode/* | ||
|
||
#System Files | ||
.DS_Store | ||
Thumbs.db | ||
|
||
.env | ||
app.env | ||
cred.json | ||
|
||
#Docker data | ||
data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
FROM golang:1.19-alpine as base_build | ||
ENV CGO_ENABLED=0 | ||
|
||
RUN mkdir /app | ||
WORKDIR /app | ||
|
||
COPY go.mod . | ||
COPY go.sum . | ||
RUN go mod download | ||
|
||
COPY .. . | ||
|
||
RUN go build -o ./cmd/main ./cmd/main.go | ||
|
||
CMD ["/app/cmd/main"] | ||
|
||
# FROM scratch | ||
# COPY --from=base_build ./app . | ||
# CMD ["./compiled"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
.SILENT: deps lint clean gen-mock test build run run-docker | ||
|
||
CYAN=\033[0;36m | ||
RESET=\033[0m | ||
|
||
pprint = echo -e "${CYAN}::>${RESET} ${1}" | ||
completed = $(call pprint,Completed!) | ||
|
||
deps: | ||
$(call pprint, Downloading go libraries...) | ||
go mod download | ||
$(call completed) | ||
|
||
lint: | ||
$(call pprint, Runnning linter...) | ||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.52.2 | ||
./bin/golangci-lint --version | ||
./bin/golangci-lint run ./... | ||
$(call completed) | ||
|
||
clean: | ||
$(call pprint,Cleaning up...) | ||
rm -rf ./bin | ||
find . -name "mocks" | xargs rm -rf {} | ||
find . -name ".cover.out" | xargs rm -rf {} | ||
$(call completed) | ||
|
||
gen-mock: clean deps | ||
$(call pprint, Generating mocks for tests...) | ||
go get github.com/golang/mock/mockgen | ||
go generate ./... | ||
$(call completed) | ||
|
||
test: | ||
$(call pprint, Runnning tests...) | ||
go test ./... -coverprofile .cover.out | ||
$(call completed) | ||
|
||
build: clean deps | ||
$(call pprint, Building app...) | ||
GOOS=linux GOARCH=amd64 go build -o airdao-mobile-api ./cmd/main.go | ||
$(call completed) | ||
|
||
run: | ||
$(call pprint, Running app...) | ||
go run ./cmd/main.go | ||
$(call completed) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package main | ||
|
||
import ( | ||
"airdao-mobile-api/config" | ||
"airdao-mobile-api/pkg/firebase" | ||
cloudmessaging "airdao-mobile-api/pkg/firebase/cloud-messaging" | ||
"airdao-mobile-api/pkg/logger" | ||
"airdao-mobile-api/pkg/mongodb" | ||
"airdao-mobile-api/services/health" | ||
"airdao-mobile-api/services/watcher" | ||
"context" | ||
"errors" | ||
"log" | ||
"os/signal" | ||
"syscall" | ||
|
||
"github.com/gofiber/fiber/v2" | ||
"github.com/gofiber/fiber/v2/middleware/cors" | ||
"go.uber.org/zap" | ||
) | ||
|
||
func main() { | ||
cfg, err := config.GetConfig() | ||
if err != nil { | ||
log.Fatalf("failed to load config: %v", err) | ||
} | ||
|
||
// Init logger | ||
newLogger, err := logger.NewLogger(cfg.Environment) | ||
if err != nil { | ||
log.Fatalf("can't create logger: %v", err) | ||
} | ||
|
||
zapLogger, err := newLogger.SetupZapLogger() | ||
if err != nil { | ||
log.Fatalf("can't setup zap logger: %v", err) | ||
} | ||
defer func(zapLogger *zap.SugaredLogger) { | ||
err := zapLogger.Sync() | ||
if err != nil && !errors.Is(err, syscall.ENOTTY) { | ||
log.Fatalf("can't setup zap logger: %v", err) | ||
} | ||
}(zapLogger) | ||
|
||
// Connect to database | ||
db, ctx, cancel, err := mongodb.NewConnection(cfg) | ||
if err != nil { | ||
zapLogger.Fatalf("failed to connect to mongodb: %s", err) | ||
} | ||
defer mongodb.Close(db, ctx, cancel) | ||
|
||
// Ping db | ||
err = mongodb.Ping(db, ctx) | ||
if err != nil { | ||
zapLogger.Fatal(err) | ||
} | ||
zapLogger.Info("DB connected successfully") | ||
|
||
// Firebase | ||
firebaseClient, err := firebase.NewClient(cfg.Firebase.CredPath) | ||
if err != nil { | ||
zapLogger.Fatalf("failed to create firebase messaging client - %v", err) | ||
} | ||
|
||
cloudMessagingClient, err := firebaseClient.CreateCloudMessagingClient() | ||
if err != nil { | ||
zapLogger.Fatalf("failed to create firebase cloud messaging client - %v", err) | ||
} | ||
|
||
// Firebase message | ||
cloudMessagingService, err := cloudmessaging.NewCloudMessagingService(cloudMessagingClient, cfg.Firebase.AndroidChannelName) | ||
if err != nil { | ||
zapLogger.Fatalf("failed to create firebase message service - %v", err) | ||
} | ||
|
||
// Repository | ||
watcherRepository, err := watcher.NewRepository(db, cfg.MongoDb.MongoDbName, zapLogger) | ||
if err != nil { | ||
zapLogger.Fatalf("failed to create watcher repository - %v", err) | ||
} | ||
|
||
// Services | ||
watcherService, err := watcher.NewService(watcherRepository, cloudMessagingService, zapLogger) | ||
if err != nil { | ||
zapLogger.Fatalf("failed to create watcher service - %v", err) | ||
} | ||
|
||
if err := watcherService.Init(context.Background()); err != nil { | ||
zapLogger.Fatalf("failed to init watchers - %v", err) | ||
} | ||
|
||
// Handlers | ||
healthHandler := health.NewHandler() | ||
|
||
watcherHandler, err := watcher.NewHandler(watcherService) | ||
if err != nil { | ||
zapLogger.Fatalf("failed to create watcher handler - %v", err) | ||
} | ||
|
||
// Create config variable | ||
config := fiber.Config{ | ||
ServerHeader: "AIRDAO-Mobile-Api", // add custom server header | ||
} | ||
|
||
// Create fiber app | ||
app := fiber.New(config) | ||
|
||
// Init cors | ||
app.Use(cors.New(cors.Config{ | ||
AllowOrigins: "*", | ||
AllowHeaders: "Origin, Content-Type, Accept, Content-Length, Accept-Encoding, Authorization", | ||
AllowMethods: "GET, POST, PUT, DELETE, OPTIONS", | ||
AllowCredentials: true, | ||
})) | ||
|
||
// Set-up Route | ||
app.Route("/api/v1", func(router fiber.Router) { | ||
healthHandler.SetupRoutes(router) | ||
watcherHandler.SetupRoutes(router) | ||
}) | ||
|
||
// Handle 404 page | ||
app.Use(func(c *fiber.Ctx) error { | ||
return c.Status(fiber.StatusNotFound).JSON(map[string]string{"error": "page not found"}) | ||
}) | ||
|
||
// Start the server | ||
go func() { | ||
if err := app.Listen(":" + cfg.Port); err != nil { | ||
zapLogger.Fatal(err) | ||
} | ||
}() | ||
|
||
zapLogger.Infof("Server started on port %v\n", cfg.Port) | ||
|
||
// Create a context that will be used to gracefully shut down the server | ||
ctx, cancel = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) | ||
defer cancel() | ||
|
||
// Wait for the termination signal | ||
<-ctx.Done() | ||
|
||
// Perform the graceful shutdown by closing the server | ||
if err := app.Shutdown(); err != nil { | ||
zapLogger.Fatal(err) | ||
} | ||
|
||
zapLogger.Info("Server gracefully stopped") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package config | ||
|
||
import ( | ||
"sync" | ||
|
||
"github.com/joho/godotenv" | ||
"github.com/kelseyhightower/envconfig" | ||
) | ||
|
||
type Config struct { | ||
Environment string `required:"true" envconfig:"APP_ENV"` | ||
Port string `required:"true" envconfig:"PORT"` | ||
|
||
MongoDb | ||
Firebase | ||
} | ||
|
||
type MongoDb struct { | ||
MongoDbName string `required:"true" envconfig:"MONGO_DB_NAME"` | ||
MongoDbUrl string `required:"true" envconfig:"MONGO_DB_URL"` | ||
} | ||
|
||
type Firebase struct { | ||
CredPath string `required:"true" envconfig:"FIREBASE_CRED_PATH"` | ||
AndroidChannelName string `required:"true" envconfig:"ANDROID_CHANNEL_NAME"` | ||
} | ||
|
||
var ( | ||
once sync.Once | ||
config *Config | ||
) | ||
|
||
func GetConfig() (*Config, error) { | ||
var err error | ||
once.Do(func() { | ||
var cfg Config | ||
_ = godotenv.Load(".env") | ||
|
||
if err = envconfig.Process("", &cfg); err != nil { | ||
return | ||
} | ||
|
||
config = &cfg | ||
}) | ||
|
||
return config, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package config_test | ||
|
||
import ( | ||
"os" | ||
"reflect" | ||
"testing" | ||
|
||
"airdao-mobile-api/config" | ||
) | ||
|
||
func TestInit(t *testing.T) { | ||
type env struct { | ||
environment string | ||
port string | ||
mongoDbName string | ||
mongoDbUrl string | ||
firebaseCredPath string | ||
androidChannel string | ||
} | ||
|
||
type args struct { | ||
env env | ||
} | ||
|
||
setEnv := func(env env) { | ||
os.Setenv("APP_ENV", env.environment) | ||
os.Setenv("PORT", env.port) | ||
os.Setenv("MONGO_DB_NAME", env.mongoDbName) | ||
os.Setenv("MONGO_DB_URL", env.mongoDbUrl) | ||
os.Setenv("FIREBASE_CRED_PATH", env.firebaseCredPath) | ||
os.Setenv("ANDROID_CHANNEL_NAME", env.androidChannel) | ||
} | ||
|
||
tests := []struct { | ||
name string | ||
args args | ||
want *config.Config | ||
wantError bool | ||
}{ | ||
{ | ||
name: "Test config file!", | ||
args: args{ | ||
env: env{ | ||
environment: "development", | ||
port: "5000", | ||
mongoDbName: "example", | ||
mongoDbUrl: "http://127.0.0.1", | ||
firebaseCredPath: "./example.json", | ||
androidChannel: "example", | ||
}, | ||
}, | ||
want: &config.Config{ | ||
Environment: "development", | ||
Port: "5000", | ||
MongoDb: config.MongoDb{ | ||
MongoDbName: "example", | ||
MongoDbUrl: "http://127.0.0.1", | ||
}, | ||
Firebase: config.Firebase{ | ||
CredPath: "./example.json", | ||
AndroidChannelName: "example", | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run(test.name, func(t *testing.T) { | ||
setEnv(test.args.env) | ||
|
||
got, err := config.GetConfig() | ||
if (err != nil) != test.wantError { | ||
t.Errorf("Init() error = %s, wantErr %v", err, test.wantError) | ||
|
||
return | ||
} | ||
|
||
if !reflect.DeepEqual(got, test.want) { | ||
t.Errorf("Init() got = %v, want %v", got, test.want) | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.