package main import ( "context" "log" "net" "net/http" "os" "time" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/rs/cors" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/reflection" "gorm.io/gorm" pb "peach/gen/go" // the following line is used for the local database "gorm.io/driver/sqlite" // uncomment the following lines to switch to a production ready remote database //libsqldb "github.com/payne8/go-libsql-dual-driver" //sqlite "github.com/ytsruh/gorm-libsql" ) func main() { logger := log.New(os.Stdout, "peach ", log.LstdFlags) // instantiate the grom ORM /* uncomment the following code to switch to a production ready remote database you will need to set the environment variables */ // --------------------- start of remote database code --------------------- //primaryUrl := os.Getenv("LIBSQL_DATABASE_URL") //authToken := os.Getenv("LIBSQL_AUTH_TOKEN") //tdb, err := libsqldb.NewLibSqlDB( // primaryUrl, // //libsqldb.WithMigrationFiles(migrationFiles), // libsqldb.WithAuthToken(authToken), // libsqldb.WithLocalDBName("local.db"), // will not be used for remote-only //) //if err != nil { // logger.Printf("failed to open db %s: %s", primaryUrl, err) // log.Fatalln(err) // return //} //gormDB, err := gorm.Open(sqlite.New(sqlite.Config{Conn: tdb.DB}), &gorm.Config{}) //if err != nil { // logger.Printf("failed to open gorm db %s: %s", primaryUrl, err) // log.Fatalln(err) // return //} // --------------------- end of remote database code --------------------- // -- start of local database code -- gormDB, err := gorm.Open(sqlite.Open("local.db"), &gorm.Config{}) if err != nil { logger.Printf("failed to open gorm db: %s", err) log.Fatalln(err) return } // -- end of local database code -- err = gormDB.AutoMigrate(&pb.UserORM{}) // TODO: figure out how to automate this part if err != nil { logger.Printf("failed to migrate user: %s", err) log.Fatalln(err) return } err = gormDB.AutoMigrate(&pb.ProductORM{}) // TODO: figure out how to automate this part if err != nil { logger.Printf("failed to migrate product: %s", err) log.Fatalln(err) return } handlers := pb.PeachDefaultServer{ DB: gormDB, } grpcServer := grpc.NewServer(grpc.ChainUnaryInterceptor( func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) { // TODO: this is an example of a middleware - we will use this for authentication // we will have a function that checks the token and a switch statement that checks if the method is public or not logger.Printf("request: %s", info.FullMethod) return handler(ctx, req) }, )) pb.RegisterPeachServer(grpcServer, &handlers) reflection.Register(grpcServer) // Start the gRPC server on port 9000 grpcAddr := ":9000" lis, err := net.Listen("tcp", grpcAddr) if err != nil { logger.Fatalf("failed to listen on %s: %v", grpcAddr, err) } go func() { logger.Printf("gRPC server listening on %s", grpcAddr) if err := grpcServer.Serve(lis); err != nil { logger.Fatalf("failed to serve gRPC: %v", err) } }() // Set up the grpc-gateway mux ctx, cancel := context.WithCancel(context.Background()) defer cancel() gwmux := runtime.NewServeMux() opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} grpcEndpoint := "localhost" + grpcAddr err = pb.RegisterPeachHandlerFromEndpoint(ctx, gwmux, grpcEndpoint, opts) if err != nil { logger.Fatalf("failed to register gateway: %v", err) } withCors := cors.New(cors.Options{ AllowedOrigins: []string{"http://localhost:*"}, // TODO: change this to the actual domain AllowedMethods: []string{"GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"}, AllowedHeaders: []string{"ACCEPT", "Authorization", "Content-Type", "X-CSRF-Token"}, ExposedHeaders: []string{"Link"}, AllowCredentials: true, MaxAge: 300, }).Handler(gwmux) // Start the HTTP gateway on port 8080 httpAddr := ":8080" logger.Printf("HTTP gateway listening on %s", httpAddr) server := &http.Server{ Addr: httpAddr, Handler: withCors, ReadTimeout: 5 * time.Second, WriteTimeout: 10 * time.Second, } if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Fatalf("failed to serve HTTP gateway: %v", err) } }