This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

1package notella 2 3import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "log" 8 "net/http" 9 10 "firebase.google.com/go/v4/messaging" 11 ll "github.com/gwennlbh/label-logger-go" 12 "github.com/nats-io/nats.go" 13 "github.com/nats-io/nats.go/jetstream" 14) 15 16type HealthResponse struct { 17 Redis bool `json:"redis"` 18 NATS bool `json:"nats"` 19 ChurrosDatabase bool `json:"churros_db"` 20 Firebase bool `json:"firebase"` 21} 22 23func (r HealthResponse) AllGood() bool { 24 return r.Redis && r.NATS && r.ChurrosDatabase && r.Firebase 25} 26 27func healthHandler(w http.ResponseWriter, r *http.Request) { 28 ll.Debug("Checking health due to request from %s", r.RemoteAddr) 29 // Set the content type to JSON 30 w.Header().Set("Content-Type", "application/json") 31 32 // Example response (you can modify this with your own business logic) 33 response := CheckHealth() 34 35 // Marshal the response to JSON and write it to the response writer 36 if err := json.NewEncoder(w).Encode(response); err != nil { 37 http.Error(w, "Unable to encode JSON", http.StatusInternalServerError) 38 return 39 } 40} 41 42func CheckHealth() HealthResponse { 43 response := HealthResponse{} 44 45 if err := CheckRedisHealth(); err != nil { 46 ll.ErrorDisplay("while checking Redis health", err) 47 } else { 48 response.Redis = true 49 } 50 51 if err := CheckNATSHealth(); err != nil { 52 ll.ErrorDisplay("while checking NATS health", err) 53 } else { 54 response.NATS = true 55 } 56 57 if err := CheckChurrosDatabaseHealth(); err != nil { 58 ll.ErrorDisplay("while checking Churros database health", err) 59 } else { 60 response.ChurrosDatabase = true 61 } 62 63 if err := CheckFirebaseHealth(); err != nil { 64 ll.ErrorDisplay("while checking Firebase Cloud Messaging health", err) 65 } else { 66 response.Firebase = true 67 } 68 return response 69} 70 71func StartHealthCheckEndpoint(port int) { 72 // Set up route for the /health endpoint 73 http.HandleFunc("/health", healthHandler) 74 75 // Start the server and log any errors 76 ll.Log("Starting", "cyan", "health check endpoint on :%d/health", port) 77 if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil { 78 log.Fatalf("Server failed to start: %v", err) 79 } 80} 81 82func CheckRedisHealth() error { 83 return redisClient.Ping(context.Background()).Err() 84} 85 86func CheckNATSHealth() error { 87 nc, err := nats.Connect(config.NatsURL) 88 if err != nil { 89 return fmt.Errorf("could not connect to NATS at %s: %w", config.NatsURL, err) 90 } 91 92 defer nc.Close() 93 94 js, err := jetstream.New(nc) 95 if err != nil { 96 return fmt.Errorf("could not connect to Jetstream: %w", err) 97 } 98 99 stream, err := js.CreateStream(context.Background(), jetstream.StreamConfig{ 100 Name: StreamName, 101 Subjects: []string{SubjectName}, 102 }) 103 if err != nil { 104 return fmt.Errorf("could not create stream: %w", err) 105 } 106 107 consumers := stream.ListConsumers(context.Background()) 108 if consumers.Err() != nil { 109 return fmt.Errorf("could not list consumers: %w", consumers.Err()) 110 } 111 112 for info := range consumers.Info() { 113 if consumers.Err() != nil { 114 return fmt.Errorf("could not get consumer info: %w", consumers.Err()) 115 } 116 if info.Name == ConsumerName { 117 return nil 118 } 119 } 120 121 return fmt.Errorf("%s not connected to stream", ConsumerName) 122} 123 124func CheckChurrosDatabaseHealth() error { 125 return prisma.Prisma.QueryRaw("SELECT 1").Exec(context.Background(), nil) 126} 127 128func CheckFirebaseHealth() error { 129 if !config.HasValidFirebaseServiceAccount() { 130 return nil 131 } 132 133 fcm, err := firebaseClient.Messaging(firebaseCtx) 134 if err != nil { 135 return fmt.Errorf("while initializing messaging client: %w", err) 136 } 137 138 _, err = fcm.SendDryRun(firebaseCtx, &messaging.Message{ 139 Notification: &messaging.Notification{ 140 Title: "Health check attempt", 141 Body: "This is a health check attempt to ensure that the FCM service is working properly. The notification is not supposed to be displayed to the user.", 142 }, 143 Token: "invalid", 144 }) 145 if err != nil && err.Error() == "The registration token is not a valid FCM registration token" { 146 return nil 147 } 148 return err 149}