Skip to content
Snippets Groups Projects
Commit fc8b29fc authored by Antoine Kryus's avatar Antoine Kryus
Browse files

add ballotAgent server and functions

parent cad94107
No related branches found
No related tags found
No related merge requests found
......@@ -4,11 +4,17 @@ import (
"ia04/comsoc"
"net/http"
"sync"
"encoding/json"
"bytes"
"fmt"
"time"
"log"
)
type Request struct {
Operator string `json:"op"`
Args [2]int `json:"args"`
Vote []comsoc.Alternative `json:"vote"` // je comprends pas le json:""
ID int `json:"id"`
Meth string
}
type Response struct {
......@@ -21,6 +27,7 @@ type RestBallotAgent struct {
sync.Mutex
ID BallotID
addr string
pfl comsoc.Profile
}
type Alternative comsoc.Alternative
......@@ -28,4 +35,115 @@ type Alternative comsoc.Alternative
type RestBallotI interface {
checkMethod(method string, w http.ResponseWriter, r *http.Request) bool
decodeRequest(r *http.Request) (req Request, err error)
} // je ne sais pas trop comment utiliser l'interface je te laisse si tu préfères
func NewRestBallotAgent(addr string, emptyProfile comsoc.Profile) *RestBallotAgent {
return &RestBallotAgent{ID: BallotID(1), addr: addr, pfl: emptyProfile}
}
// Test de la méthode
func (rsa *RestBallotAgent) checkMethod(method string, w http.ResponseWriter, r *http.Request) bool {
if r.Method != method {
w.WriteHeader(http.StatusMethodNotAllowed)
fmt.Fprintf(w, "method %q not allowed", r.Method)
return false
}
return true
}
func (*RestBallotAgent) decodeRequest(r *http.Request) (req Request, err error) {
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
err = json.Unmarshal(buf.Bytes(), &req)
return
}
func (rba *RestBallotAgent) doVote(w http.ResponseWriter, r *http.Request) {
// mise à jour du nombre de requêtes
rba.Lock()
defer rba.Unlock()
// rba.reqCount++
// vérification de la méthode de la requête
if !rba.checkMethod("POST", w, r) {
return
}
// décodage de la requête
req, err := rba.decodeRequest(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, err.Error())
return
}
// traitement de la requête
var resp Response
rba.pfl = append(rba.pfl, req.Vote) // req should have vote (list of int) and ID (int)
if comsoc.CheckProfileAlternative(rba.pfl, req.Vote) != nil {
w.WriteHeader(http.StatusNotImplemented)
msg := fmt.Sprintf("Vote of voter '%s' is not correct", req.ID)
r.Write([]byte(msg))
return
}
w.WriteHeader(http.StatusOK)
serial, _ := json.Marshal(resp)
w.Write(serial)
}
func (rba *RestBallotAgent) doClose_vote(w http.ResponseWriter, r *http.Request) {
// mise à jour du nombre de requêtes
rba.Lock()
defer rba.Unlock()
// rba.reqCount++
// vérification de la méthode de la requête
if !rba.checkMethod("POST", w, r) {
return
}
// décodage de la requête
req, err := rba.decodeRequest(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, err.Error())
return
}
// traitement de la requête
var resp Response
switch rba.Meth {
case "borda":
//call borda SCF and SWF and store results
}
// another way to do this would be to call method directly from router (mux)
w.WriteHeader(http.StatusOK)
serial, _ := json.Marshal(resp)
w.Write(serial)
}
func (rba *RestBallotAgent) Start() {
// création du routeur
mux := http.NewServeMux()
mux.HandleFunc("/vote")
mux.HandleFunc("/close_vote")
mux.HandleFunc("/get_results")
// création du serveur http
s := &http.Server{
Addr: rba.addr,
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20}
// lancement du serveur
log.Println("Listening on", rba.addr)
go log.Fatal(s.ListenAndServe())
}
......@@ -8,7 +8,8 @@ import (
"gitlab.utc.fr/lagruesy/ia04/demos/restagentdemo/restclientagent"
"gitlab.utc.fr/lagruesy/ia04/demos/restagentdemo/restserveragent"
"comsoc"
// "ia04/comsoc"
// "ia04/agt"
)
func main() {
......@@ -24,6 +25,7 @@ func main() {
go servAgt.Start()
log.Println("démarrage des clients...")
//sample agents
for i := 0; i < n; i++ {
id := fmt.Sprintf("id%02d", i)
op := ops[rand.Intn(3)]
......@@ -33,6 +35,7 @@ func main() {
clAgts = append(clAgts, *agt)
}
for _, agt := range clAgts {
// attention, obligation de passer par cette lambda pour faire capturer la valeur de l'itération par la goroutine
func(agt restclientagent.RestClientAgent) {
......
......@@ -44,7 +44,7 @@ func maxCount(count Count) (bestAlts []Alternative) {
// vérifier que tout le monde a les mêmes alternatives, qu'il n'est pas vide
// vérifie le profil donné, par ex. qu'ils sont tous complets et que chaque alternative de alts apparaît exactement une fois par préférences
func checkProfile(prefs Profile) error {
func CheckProfile(prefs Profile) error {
norm := len(prefs[0]) // Si un des profiles n'a pas la même taille: erreur
for _, voter := range prefs {
if len(voter) != norm {
......@@ -61,7 +61,7 @@ func checkProfile(prefs Profile) error {
return nil
}
func checkProfileAlternative(prefs Profile, alts []Alternative) error {
func CheckProfileAlternative(prefs Profile, alts []Alternative) error {
present := func(alt Alternative, pref []Alternative) bool {
for _, alt2 := range pref {
if alt == alt2 {
......@@ -70,7 +70,7 @@ func checkProfileAlternative(prefs Profile, alts []Alternative) error {
}
return false
}
err := checkProfile(prefs)
err := CheckProfile(prefs)
if err != nil {
return err
}
......
......@@ -2,4 +2,6 @@ module ia04
go 1.19
require gitlab.utc.fr/lagruesy/ia04 v0.2.0
require (
gitlab.utc.fr/lagruesy/ia04 v0.2.0
)
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment