Commit: Bulk unfinished work
This commit is contained in:
32
fx/echo.go
Normal file
32
fx/echo.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
// EchoHandler is an http.Handler that copies its request body
|
||||
// back to the response.
|
||||
type EchoHandler struct{}
|
||||
|
||||
// NewEchoHandler builds a new EchoHandler.
|
||||
func NewEchoHandler() *EchoHandler {
|
||||
return &EchoHandler{}
|
||||
}
|
||||
|
||||
// ServeHTTP handles an HTTP request to the /echo endpoint.
|
||||
func (*EchoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if _, err := io.Copy(w, r.Body); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Failed to handle request:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EchoHandler) Handler() http.Handler {
|
||||
return e
|
||||
}
|
||||
|
||||
func (*EchoHandler) Path() string {
|
||||
return "/echo"
|
||||
}
|
||||
9
fx/interfaces/integration.go
Normal file
9
fx/interfaces/integration.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package interfaces
|
||||
|
||||
import "context"
|
||||
|
||||
type BasicIntegration interface {
|
||||
OnStart(context.Context) error
|
||||
OnStop(context.Context) error
|
||||
Invoke()
|
||||
}
|
||||
1
fx/interfaces/stores/mandantstore.go
Normal file
1
fx/interfaces/stores/mandantstore.go
Normal file
@@ -0,0 +1 @@
|
||||
package stores
|
||||
17
fx/interfaces/stores/messagestore.go
Normal file
17
fx/interfaces/stores/messagestore.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package stores
|
||||
|
||||
import "context"
|
||||
|
||||
type Message struct {
|
||||
Id int
|
||||
From string
|
||||
Subject string
|
||||
Body string
|
||||
}
|
||||
|
||||
type MessageStore interface {
|
||||
AddMessage(ctx context.Context, m *Message) error
|
||||
GetMessage(ctx context.Context, id int) (*Message, error)
|
||||
ListMessages(ctx context.Context) ([]*Message, error)
|
||||
RemoveMessage(ctx context.Context, id int) error
|
||||
}
|
||||
1
fx/interfaces/stores/projectstore.go
Normal file
1
fx/interfaces/stores/projectstore.go
Normal file
@@ -0,0 +1 @@
|
||||
package stores
|
||||
44
fx/interfaces/stores/sessionstore.go
Normal file
44
fx/interfaces/stores/sessionstore.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package stores
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Session struct {
|
||||
Token string
|
||||
UserID uint
|
||||
MandantId uint
|
||||
}
|
||||
|
||||
func (s *Session) Deserialize(t string, m map[string]string) (*Session, error) {
|
||||
userid, err := strconv.Atoi(m["userid"])
|
||||
if err != nil {
|
||||
return nil, errors.New("Userid from cache not an int")
|
||||
}
|
||||
|
||||
mandantid, err := strconv.Atoi(m["mandantid"])
|
||||
if err != nil {
|
||||
return nil, errors.New("Mandantid from cache not an int")
|
||||
}
|
||||
|
||||
s.Token = t
|
||||
s.UserID = uint(userid)
|
||||
s.MandantId = uint(mandantid)
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Session) Serialize() map[string]string {
|
||||
m := make(map[string]string)
|
||||
m["userid"] = strconv.Itoa(int(s.UserID))
|
||||
m["mandantid"] = strconv.Itoa(int(s.MandantId))
|
||||
return m
|
||||
}
|
||||
|
||||
type SessionStore interface {
|
||||
AddSession(s *Session)
|
||||
GetSessionFromToken(token string) (*Session, error)
|
||||
RemoveSession(token string)
|
||||
SetMandantInSession(token string, mandantId uint) error
|
||||
}
|
||||
1
fx/interfaces/stores/todostore.go
Normal file
1
fx/interfaces/stores/todostore.go
Normal file
@@ -0,0 +1 @@
|
||||
package stores
|
||||
137
fx/logger.go
Normal file
137
fx/logger.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"go.uber.org/fx"
|
||||
|
||||
"go.opentelemetry.io/contrib/bridges/otelslog"
|
||||
"go.opentelemetry.io/otel"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
|
||||
"go.opentelemetry.io/otel/log/global"
|
||||
"go.opentelemetry.io/otel/propagation"
|
||||
olog "go.opentelemetry.io/otel/sdk/log"
|
||||
"go.opentelemetry.io/otel/sdk/metric"
|
||||
"go.opentelemetry.io/otel/sdk/trace"
|
||||
)
|
||||
|
||||
func NewOtelTracerProvider(lc fx.Lifecycle) *trace.TracerProvider {
|
||||
tp, err := newTracerProvider()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return tp.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return tp
|
||||
}
|
||||
|
||||
func NewOtelMeterProvider(lc fx.Lifecycle) *metric.MeterProvider {
|
||||
mp, err := newMeterProvider()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return mp.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return mp
|
||||
}
|
||||
|
||||
func NewOtelLoggerProvider(lc fx.Lifecycle) *olog.LoggerProvider {
|
||||
lp, err := newLoggerProvider()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return lp.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return lp
|
||||
}
|
||||
|
||||
func NewLogger(loggerProvider *olog.LoggerProvider) *slog.Logger {
|
||||
logger := otelslog.NewLogger("Application", otelslog.WithLoggerProvider(loggerProvider))
|
||||
return logger
|
||||
}
|
||||
|
||||
// setupOTelSDK bootstraps the OpenTelemetry pipeline.
|
||||
// If it does not return an error, make sure to call shutdown for proper cleanup.
|
||||
func SetupOTelSDK(tracerProvider *trace.TracerProvider, meterProvider *metric.MeterProvider, loggerProvider *olog.LoggerProvider) {
|
||||
// Set up propagator.
|
||||
prop := newPropagator()
|
||||
otel.SetTextMapPropagator(prop)
|
||||
|
||||
// Set up trace provider.
|
||||
otel.SetTracerProvider(tracerProvider)
|
||||
otel.SetMeterProvider(meterProvider)
|
||||
|
||||
// Set up logger provider.
|
||||
global.SetLoggerProvider(loggerProvider)
|
||||
}
|
||||
|
||||
func newPropagator() propagation.TextMapPropagator {
|
||||
return propagation.NewCompositeTextMapPropagator(
|
||||
propagation.TraceContext{},
|
||||
propagation.Baggage{},
|
||||
)
|
||||
}
|
||||
|
||||
func newTracerProvider() (*trace.TracerProvider, error) {
|
||||
|
||||
traceExporter, err := otlptracehttp.New(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tracerProvider := trace.NewTracerProvider(
|
||||
trace.WithBatcher(traceExporter,
|
||||
// Default is 5s. Set to 1s for demonstrative purposes.
|
||||
trace.WithBatchTimeout(time.Second)),
|
||||
)
|
||||
return tracerProvider, nil
|
||||
}
|
||||
|
||||
func newMeterProvider() (*metric.MeterProvider, error) {
|
||||
metricExporter, err := otlpmetrichttp.New(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
meterProvider := metric.NewMeterProvider(
|
||||
metric.WithReader(metric.NewPeriodicReader(metricExporter,
|
||||
// Default is 1m. Set to 3s for demonstrative purposes.
|
||||
metric.WithInterval(3*time.Second))),
|
||||
)
|
||||
return meterProvider, nil
|
||||
}
|
||||
|
||||
func newLoggerProvider() (*olog.LoggerProvider, error) {
|
||||
logExporter, err := otlploghttp.New(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
loggerProvider := olog.NewLoggerProvider(
|
||||
olog.WithProcessor(olog.NewBatchProcessor(logExporter)),
|
||||
)
|
||||
|
||||
logger := otelslog.NewLogger("sloger", otelslog.WithLoggerProvider(loggerProvider))
|
||||
logger.Info("Hello")
|
||||
|
||||
return loggerProvider, nil
|
||||
}
|
||||
56
fx/routes.go
Normal file
56
fx/routes.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
connectcors "connectrpc.com/cors"
|
||||
"github.com/rs/cors"
|
||||
)
|
||||
|
||||
type Handler interface {
|
||||
Handler() http.Handler
|
||||
Path() string
|
||||
}
|
||||
|
||||
type route struct {
|
||||
path string
|
||||
handler http.Handler
|
||||
}
|
||||
|
||||
func NewRoute(path string, handler http.Handler) Handler {
|
||||
return &route{
|
||||
path: path,
|
||||
handler: handler,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *route) Handler() http.Handler {
|
||||
return r.handler
|
||||
}
|
||||
|
||||
func (r *route) Path() string {
|
||||
return r.path
|
||||
}
|
||||
|
||||
// NewServeMux builds a ServeMux that will route requests
|
||||
// to the given EchoHandler.
|
||||
func NewServeMux(handlers []Handler, logger *slog.Logger) http.Handler {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
for _, h := range handlers {
|
||||
logger.Debug("Registering route", "path", h.Path())
|
||||
mux.Handle(h.Path(), h.Handler())
|
||||
}
|
||||
|
||||
handler := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"http://10.8.0.3:3001", "http://10.8.0.3:3001/", os.Getenv("FRONTEND_URI")}, // replace with your domain
|
||||
AllowedMethods: connectcors.AllowedMethods(),
|
||||
AllowedHeaders: append(connectcors.AllowedHeaders(), "authentication", "Authentication"),
|
||||
ExposedHeaders: connectcors.ExposedHeaders(),
|
||||
AllowCredentials: true,
|
||||
}).Handler(mux)
|
||||
|
||||
return handler
|
||||
}
|
||||
40
fx/server.go
Normal file
40
fx/server.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package fx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
func NewHTTPServer(lc fx.Lifecycle, handler http.Handler) *http.Server {
|
||||
p := new(http.Protocols)
|
||||
p.SetHTTP1(true)
|
||||
// Use h2c so we can serve HTTP/2 without TLS.
|
||||
p.SetUnencryptedHTTP2(true)
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: ":3002",
|
||||
Protocols: p,
|
||||
Handler: handler,
|
||||
}
|
||||
|
||||
lc.Append(fx.Hook{
|
||||
OnStart: func(ctx context.Context) error {
|
||||
go func() {
|
||||
fmt.Println("Listening on :3002")
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
},
|
||||
OnStop: func(ctx context.Context) error {
|
||||
return srv.Shutdown(ctx)
|
||||
},
|
||||
})
|
||||
|
||||
return srv
|
||||
}
|
||||
Reference in New Issue
Block a user