-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.go
111 lines (85 loc) · 2.9 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"context"
"github.com/schartey/gqlgen-auth-starter/graphql"
"github.com/schartey/gqlgen-auth-starter/graphql/resolvers"
"github.com/spf13/viper"
"io"
"syscall"
"net/http"
"os"
"os/signal"
"time"
"github.com/99designs/gqlgen/handler"
log "github.com/sirupsen/logrus"
h "github.com/schartey/gqlgen-auth-starter/graphql/handler"
nested "github.com/antonfisher/nested-logrus-formatter"
)
const defaultPort = "8080"
func main() {
ctx := context.Background()
config, err := setupConfig()
if err != nil {
log.Panicf("Could not load configs: %s", err)
}
port := os.Getenv("PORT")
if port == "" {
port = defaultPort
}
// Initialize Logging to file and stdout
initializeLogging(config)
// Create channel to handle incoming sigint and sigterm
done := make(chan os.Signal, 1)
signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
// Add repositories to the resolver so we can store data in resolvers
keycloakConfig := config.Sub("keycloak")
resolver := WireRootResolver(ctx, keycloakConfig)
handlerServiceProvider := WireHandlerServiceProvider(ctx, keycloakConfig)
// Setup server
server := setupServer(ctx, port, resolver, handlerServiceProvider)
// When we receive sigint or siterm we continue to stopping the server
<-done
log.Info("Server Stopped")
// The server gets 5 seconds time until shutdown
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer func() {
// extra handling here
cancel()
}()
if err := server.Shutdown(ctx); err != nil {
log.Fatalf("Server Shutdown Failed:%+v", err)
}
log.Debug("Server Exited Properly")
}
func setupConfig() (*viper.Viper, error) {
configFile := os.Getenv("CONFIG_FILE")
configPath := os.Getenv("CONFIG_PATH")
return LoadConfig(configFile, configPath)
}
func initializeLogging(config *viper.Viper) {
logConfig := config.Sub("log")
logFile := logConfig.GetString("log-file")
var file, err = os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Println("Could Not Open Log File : " + err.Error())
}
log.SetOutput(io.MultiWriter(os.Stdout, file))
log.SetFormatter(&nested.Formatter{
HideKeys: true,
FieldsOrder: []string{"component", "category"},
})
}
func setupServer(ctx context.Context, port string, resolver *resolvers.RootResolver, handlerServiceProvider *h.HandlerServiceProvider) *http.Server {
m := http.NewServeMux()
server := http.Server{Addr: ":" + port, Handler: m}
m.Handle("/login", h.AddContext(ctx, h.Login(handlerServiceProvider)))
m.Handle("/query", h.AddContext(ctx, handler.GraphQL(graphql.NewExecutableSchema(graphql.Config{Resolvers: resolver}))))
m.Handle("/", handler.Playground("GraphQL playground", "/query"))
go func() {
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)
return &server
}