From 967be9e750221ab2ab783f95df79bb26d290a45e Mon Sep 17 00:00:00 2001
From: Martial Simon
Date: Mon, 15 Sep 2025 01:07:58 +0200
Subject: add: added projects
---
idvoc-2025/CommentsInteractor/main.go | 147 ++++++++++++++++++++++++++++++++++
1 file changed, 147 insertions(+)
create mode 100644 idvoc-2025/CommentsInteractor/main.go
(limited to 'idvoc-2025/CommentsInteractor/main.go')
diff --git a/idvoc-2025/CommentsInteractor/main.go b/idvoc-2025/CommentsInteractor/main.go
new file mode 100644
index 0000000..9a19243
--- /dev/null
+++ b/idvoc-2025/CommentsInteractor/main.go
@@ -0,0 +1,147 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/gorilla/handlers"
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+ "io"
+ "log"
+ "net/http"
+ "os"
+ "strconv"
+)
+
+func getenv(key, fallback string) string {
+ value := os.Getenv(key)
+ if len(value) == 0 {
+ return fallback
+ }
+ return value
+}
+
+type Comment struct {
+ Comment string `json:"comment"`
+}
+
+type EngineError struct {
+ Message string `json:"message"`
+ AdditionalInfo string `json:"additionalInfo"`
+}
+
+var comments_engine_endpoint string
+var (
+ httpHits = promauto.NewCounterVec(prometheus.CounterOpts{
+ Name: "comments_interactor_http_hits_total",
+ Help: "The total number of hits on a given route",
+ }, []string{"route", "method"})
+ commentsReceived = promauto.NewCounter(prometheus.CounterOpts{
+ Name: "comments_interactor_comments_received_total",
+ Help: "The total number of comments received (successfully posted or not)",
+ })
+ commentsPosted = promauto.NewCounter(prometheus.CounterOpts{
+ Name: "comments_interactor_comments_posted_total",
+ Help: "The total number of comments posted (successfully posted)",
+ })
+)
+
+func sendComment(w http.ResponseWriter, r *http.Request) {
+ commentsReceived.Inc()
+ if err := r.ParseForm(); err != nil {
+ fmt.Fprintf(w, "error
ParseForm() err: %v
", err)
+ return
+ }
+ var comment Comment
+ comment.Comment = r.FormValue("comment")
+ if comment.Comment == "" {
+ fmt.Fprintf(w, "error
Empty comment or malformed
")
+ return
+ }
+ obj, err := json.Marshal(comment)
+ if err != nil {
+ fmt.Fprintf(w, "error
Empty comment or malformed
")
+ return
+ }
+ _, err = http.Post("http://"+comments_engine_endpoint+"/comment", "application/json", bytes.NewReader(obj))
+ if err == nil {
+ fmt.Fprintf(w, "Success !
Comment posted
")
+ commentsPosted.Inc()
+ } else {
+ fmt.Fprintf(w, "Error
Error while trying to send a comment: %s", err)
+ }
+}
+
+func showDashboard(w http.ResponseWriter, r *http.Request) {
+ io.WriteString(w, "
Latest comments
")
+ io.WriteString(w, "")
+ resp, err := http.Get("http://" + comments_engine_endpoint + "/latest")
+ if err != nil {
+ log.Printf("Could not HTTP get on CommentsEngine: %s", err)
+ io.WriteString(w, fmt.Sprintf("Error contacting the backend, %s", err))
+ } else {
+ defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+ var comments []string
+ err = json.Unmarshal(body, &comments)
+ if err != nil {
+ var engineError EngineError
+ err = json.Unmarshal(body, &engineError)
+ if err != nil {
+ log.Printf("CommentsEngine returned unexpected value: %s", err)
+ io.WriteString(w, fmt.Sprintf("CommentsEngine returned badly formated values, %s", err))
+ } else {
+ io.WriteString(w, fmt.Sprintf("CommentsEngine returned an error: %s
Additional info: %s", engineError.Message, engineError.AdditionalInfo))
+ }
+ } else {
+ for i, comment := range comments {
+ io.WriteString(w, "
comment "+strconv.Itoa(i)+"
"+comment+"
")
+ }
+ }
+ }
+ io.WriteString(w, "
")
+ io.WriteString(w, "Send comment
")
+ io.WriteString(w, "")
+}
+
+func getRoot(w http.ResponseWriter, r *http.Request) {
+ httpHits.With(prometheus.Labels{"route": "/", "method": r.Method}).Inc()
+ io.WriteString(w, "CommentsInteractor")
+ if r.Method == http.MethodPost {
+ sendComment(w, r)
+ }
+ showDashboard(w, r)
+ io.WriteString(w, "")
+}
+
+func sendError(w http.ResponseWriter, err error, additionalInfo string) {
+ w.WriteHeader(http.StatusInternalServerError)
+ resp := make(map[string]string)
+ resp["message"] = fmt.Sprint(err)
+ resp["additionalInfo"] = additionalInfo
+ jsonResp, err := json.Marshal(resp)
+ if err != nil {
+ log.Fatalf("Error happened in JSON marshal. Err: %s", err)
+ }
+ w.Write(jsonResp)
+}
+
+func main() {
+ http.HandleFunc("/", getRoot)
+ prometheus.Unregister(prometheus.NewGoCollector())
+ http.Handle("/metrics", promhttp.Handler())
+
+ listeningHostPort := getenv("HOST", "127.0.0.1") + ":" + getenv("PORT", "9000")
+ comments_engine_endpoint = getenv("COMMENTS_ENGINE_ENDPOINT", "127.0.0.1:8000")
+ fmt.Printf("Starting the server on %s\n", listeningHostPort)
+ err := http.ListenAndServe(listeningHostPort, handlers.LoggingHandler(os.Stdout, http.DefaultServeMux))
+ if errors.Is(err, http.ErrServerClosed) {
+ fmt.Printf("server closed\n")
+ } else if err != nil {
+ fmt.Printf("error starting server: %s\n", err)
+ os.Exit(1)
+ }
+}
--
cgit v1.2.3