diff --git a/alexey-cloud/README.md b/alexey-cloud/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3dd7e590268fd3114a6f2549e2eab49482c2bb87 --- /dev/null +++ b/alexey-cloud/README.md @@ -0,0 +1,10 @@ +# BlockChain +To start the project you need golang. +To launch the project you need to launch the 10 servers each in different terminal with the commande: +bash script.sh $SERVERNMB +So for server 1 its "bash script.sh 1", "bash script.sh 5" for server 5 +After that do: +go build +./main +And the programme will ask you to type in what you need. +For cloud version you need my machines images, and the call client back for rate doesnt work. diff --git a/alexey-cloud/client.go b/alexey-cloud/client.go new file mode 100644 index 0000000000000000000000000000000000000000..9ea7d15cbe11fa27afb06fd7a71426bf14c3e10d --- /dev/null +++ b/alexey-cloud/client.go @@ -0,0 +1,105 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strings" +) + +func client() { + println("Create your transaction: ") + println("ID of transaction:") + reader := bufio.NewReader(os.Stdin) + input, _ := reader.ReadString('\n') + input = strings.TrimSuffix(input, "\n") + message := input + println("Sender:") + reader = bufio.NewReader(os.Stdin) + input, _ = reader.ReadString('\n') + input = strings.TrimSuffix(input, "\n") + message = message + " " + input + println("Receiver:") + reader = bufio.NewReader(os.Stdin) + input, _ = reader.ReadString('\n') + input = strings.TrimSuffix(input, "\n") + message = message + " " + input + println("Amount:") + reader = bufio.NewReader(os.Stdin) + input, _ = reader.ReadString('\n') + input = strings.TrimSuffix(input, "\n") + message = message + " " + input + goodInput := false + for !goodInput { + println("Is it fake?(Y/N):") + reader = bufio.NewReader(os.Stdin) + char, _, err := reader.ReadRune() + if err != nil { + fmt.Println(err) + } + switch char { + case 'Y': + message = message + " " + "false" + goodInput = true + case 'N': + message = message + " " + "true" + goodInput = true + default: + println("type Y or N:") + } + } + goodInput = false + for !goodInput { + println("What do you want to do with it? creantTrans or Rate?(C/R):") + reader = bufio.NewReader(os.Stdin) + char, _, err := reader.ReadRune() + if err != nil { + fmt.Println(err) + } + switch char { + case 'C': + create_transaction("M" + message) + goodInput = true + case 'R': + rate("N" + message) + goodInput = true + default: + println("type C or R:") + } + } +} + +func rate(trans string) { + conn, err := net.Dial("tcp", "34.67.47.51:8000") + if err != nil { + fmt.Println(err) + return + } + // what to send + fmt.Fprintf(conn, trans+"\n") + conn.Close() + ln, err := net.Listen("tcp", ":9000") //marche pas en cloud + if err != nil { + fmt.Println(err) + return + } + con, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + message, _ := bufio.NewReader(con).ReadString('\n') + fmt.Print("Message from server: " + message) +} + +func create_transaction(trans string) { + conn, err := net.Dial("tcp", "34.67.47.51:8000") + if err != nil { + fmt.Println(err) + return + } + // what to send + fmt.Fprintf(conn, trans+"\n") + conn.Close() +} diff --git a/alexey-cloud/go.mod b/alexey-cloud/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..201842e855468976f1559fab8fdb5e030d6e4d4f --- /dev/null +++ b/alexey-cloud/go.mod @@ -0,0 +1,5 @@ +module main + +go 1.17 + +require gopkg.in/yaml.v2 v2.4.0 diff --git a/alexey-cloud/go.sum b/alexey-cloud/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..dd0bc19f1fe3e536098c0fd769c96042bf9ebc73 --- /dev/null +++ b/alexey-cloud/go.sum @@ -0,0 +1,4 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/alexey-cloud/main b/alexey-cloud/main new file mode 100755 index 0000000000000000000000000000000000000000..be3ac8ae2ae51e4d43097965fc86e5a1abde77eb Binary files /dev/null and b/alexey-cloud/main differ diff --git a/alexey-cloud/main.go b/alexey-cloud/main.go new file mode 100644 index 0000000000000000000000000000000000000000..a78d6fb588f5d39fefa73b329daececed95cf8df --- /dev/null +++ b/alexey-cloud/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + client() +} diff --git a/alexey-cloud/script.sh b/alexey-cloud/script.sh new file mode 100644 index 0000000000000000000000000000000000000000..7bb76028516cdc5b6cb7c6725e9982419cc152da --- /dev/null +++ b/alexey-cloud/script.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +go run server$1/server.go server$1/parser.go $1 diff --git a/alexey-cloud/server1/data.json b/alexey-cloud/server1/data.json new file mode 100644 index 0000000000000000000000000000000000000000..32bfb661f24bcd33ef8beb9e9fa7d4d198f89772 --- /dev/null +++ b/alexey-cloud/server1/data.json @@ -0,0 +1,93 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 2, + "sender": "2", + "receiver": "2", + "amount": 2, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": true + } +] \ No newline at end of file diff --git a/alexey-cloud/server1/neigh.yaml b/alexey-cloud/server1/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f240af507a161df44521bdb3e211aaa0c4c57b9b --- /dev/null +++ b/alexey-cloud/server1/neigh.yaml @@ -0,0 +1,14 @@ +id: 1 +address: "34.67.47.51" +neighbours: + - id: 2 + address: "34.122.55.203" + edge_weight: 7 + + - id: 3 + address: "34.132.241.177" + edge_weight: 4 + + - id: 10 + address: "35.203.46.17" + edge_weight: 4 diff --git a/alexey-cloud/server1/parser.go b/alexey-cloud/server1/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..4f84575dea3733f43208d494460e76aac5976c14 --- /dev/null +++ b/alexey-cloud/server1/parser.go @@ -0,0 +1,214 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions(filename string) { + // Open our jsonFile + jsonFile, err := os.Open(filename) + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server1/server.go b/alexey-cloud/server1/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server1/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server10/data.json b/alexey-cloud/server10/data.json new file mode 100644 index 0000000000000000000000000000000000000000..86dc1b7bcf730005baad49b5804e5170868921d8 --- /dev/null +++ b/alexey-cloud/server10/data.json @@ -0,0 +1,72 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 2, + "sender": "2", + "receiver": "2", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server10/neigh.yaml b/alexey-cloud/server10/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e32b7e62416efc4cf9b3bb99304982b4399b52f8 --- /dev/null +++ b/alexey-cloud/server10/neigh.yaml @@ -0,0 +1,6 @@ +id: 10 +address: "35.203.46.17" +neighbours: + - id: 1 + address: "34.67.47.51" + edge_weight: 7 diff --git a/alexey-cloud/server10/parser.go b/alexey-cloud/server10/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server10/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server10/server.go b/alexey-cloud/server10/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server10/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server2/data.json b/alexey-cloud/server2/data.json new file mode 100644 index 0000000000000000000000000000000000000000..edc15ac60b5be308c9030e4ef0ae05b9332cc363 --- /dev/null +++ b/alexey-cloud/server2/data.json @@ -0,0 +1,79 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server2/neigh.yaml b/alexey-cloud/server2/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1e7cb90240717110561078343bf21fe526516a16 --- /dev/null +++ b/alexey-cloud/server2/neigh.yaml @@ -0,0 +1,14 @@ +id: 2 +address: "34.122.55.203" +neighbours: + - id: 1 + address: "34.67.47.51" + edge_weight: 7 + + - id: 3 + address: "34.132.241.177" + edge_weight: 4 + + - id: 7 + address: "34.123.88.238" + edge_weight: 4 diff --git a/alexey-cloud/server2/parser.go b/alexey-cloud/server2/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server2/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server2/server.go b/alexey-cloud/server2/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server2/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server3/data.json b/alexey-cloud/server3/data.json new file mode 100644 index 0000000000000000000000000000000000000000..9650f478bcd4fce778fe9e9a0f6078d1dc974047 --- /dev/null +++ b/alexey-cloud/server3/data.json @@ -0,0 +1,93 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 2, + "sender": "2", + "receiver": "2", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server3/neigh.yaml b/alexey-cloud/server3/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b94c33a7dc7639b94c969a99d3cf6137c1fdf83b --- /dev/null +++ b/alexey-cloud/server3/neigh.yaml @@ -0,0 +1,16 @@ +id: 3 +address: "34.132.241.177" +neighbours: + - id: 1 + address: "34.67.47.51" + edge_weight: 7 + + - id: 2 + address: "34.122.55.203" + edge_weight: 4 + + - id: 4 + address: "35.225.130.115" + + - id: 5 + address: "34.71.229.241" diff --git a/alexey-cloud/server3/parser.go b/alexey-cloud/server3/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server3/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server3/server.go b/alexey-cloud/server3/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server3/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server4/data.json b/alexey-cloud/server4/data.json new file mode 100644 index 0000000000000000000000000000000000000000..edc15ac60b5be308c9030e4ef0ae05b9332cc363 --- /dev/null +++ b/alexey-cloud/server4/data.json @@ -0,0 +1,79 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server4/neigh.yaml b/alexey-cloud/server4/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3f67ab4f5d237ed0b38314b317f2780f8d25d87d --- /dev/null +++ b/alexey-cloud/server4/neigh.yaml @@ -0,0 +1,12 @@ +id: 4 +address: "35.225.130.115" +neighbours: + - id: 3 + address: "34.132.241.177" + edge_weight: 7 + - id: 9 + address: "35.193.74.132" + edge_weight: 7 + - id: 6 + address: "35.184.3.3" + edge_weight: 7 diff --git a/alexey-cloud/server4/parser.go b/alexey-cloud/server4/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server4/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server4/server.go b/alexey-cloud/server4/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server4/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server5/data.json b/alexey-cloud/server5/data.json new file mode 100644 index 0000000000000000000000000000000000000000..420a56b09fc4d1988d4d4b80e8de181963fefb35 --- /dev/null +++ b/alexey-cloud/server5/data.json @@ -0,0 +1,72 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server5/neigh.yaml b/alexey-cloud/server5/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0155d54ab2a81e5b8b2773835533e97c8670bf47 --- /dev/null +++ b/alexey-cloud/server5/neigh.yaml @@ -0,0 +1,9 @@ +id: 5 +address: "34.71.229.241" +neighbours: + - id: 3 + address: "34.132.241.177" + edge_weight: 7 + - id: 6 + address: "35.184.3.3" + edge_weight: 6 diff --git a/alexey-cloud/server5/parser.go b/alexey-cloud/server5/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server5/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server5/server.go b/alexey-cloud/server5/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server5/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server6/data.json b/alexey-cloud/server6/data.json new file mode 100644 index 0000000000000000000000000000000000000000..420a56b09fc4d1988d4d4b80e8de181963fefb35 --- /dev/null +++ b/alexey-cloud/server6/data.json @@ -0,0 +1,72 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server6/neigh.yaml b/alexey-cloud/server6/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1677a901b6ca75ddfc00b8f089fe685c79da2504 --- /dev/null +++ b/alexey-cloud/server6/neigh.yaml @@ -0,0 +1,9 @@ +id: 6 +address: "35.184.3.3" +neighbours: + - id: 4 + address: "35.225.130.115" + edge_weight: 7 + - id: 5 + address: "34.71.229.241" + edge_weight: 7 diff --git a/alexey-cloud/server6/parser.go b/alexey-cloud/server6/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server6/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server6/server.go b/alexey-cloud/server6/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server6/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server7/data.json b/alexey-cloud/server7/data.json new file mode 100644 index 0000000000000000000000000000000000000000..edc15ac60b5be308c9030e4ef0ae05b9332cc363 --- /dev/null +++ b/alexey-cloud/server7/data.json @@ -0,0 +1,79 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server7/neigh.yaml b/alexey-cloud/server7/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ebbab3f4f4be8c9dab3371feb4dde5e4e2e702dd --- /dev/null +++ b/alexey-cloud/server7/neigh.yaml @@ -0,0 +1,12 @@ +id: 7 +address: "34.123.88.238" +neighbours: + - id: 9 + address: "35.193.74.132" + edge_weight: 7 + - id: 2 + address: "34.122.55.203" + edge_weight: 7 + - id: 8 + address: "35.203.28.206" + edge_weight: 7 diff --git a/alexey-cloud/server7/parser.go b/alexey-cloud/server7/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server7/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server7/server.go b/alexey-cloud/server7/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server7/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server8/data.json b/alexey-cloud/server8/data.json new file mode 100644 index 0000000000000000000000000000000000000000..72aeefe4402965aed56fae6de39c2365203d5950 --- /dev/null +++ b/alexey-cloud/server8/data.json @@ -0,0 +1,65 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 0, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server8/neigh.yaml b/alexey-cloud/server8/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..20bb053306d1ab6aa6ca33d474e002ae1edbbcc2 --- /dev/null +++ b/alexey-cloud/server8/neigh.yaml @@ -0,0 +1,6 @@ +id: 8 +address: "35.203.28.206" +neighbours: + - id: 7 + address: "34.123.88.238" + edge_weight: 7 diff --git a/alexey-cloud/server8/parser.go b/alexey-cloud/server8/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server8/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server8/server.go b/alexey-cloud/server8/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server8/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/server9/data.json b/alexey-cloud/server9/data.json new file mode 100644 index 0000000000000000000000000000000000000000..ab280cd7b05882a3997b64ce8e5d5f642cc4adeb --- /dev/null +++ b/alexey-cloud/server9/data.json @@ -0,0 +1,79 @@ +[ + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 5, + "sender": "5", + "receiver": "5", + "amount": 5, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 1, + "sender": "Thom", + "receiver": "Keko", + "amount": 69, + "isFake": false + }, + { + "ID": 2, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Yo", + "receiver": "Mama", + "amount": 55, + "isFake": false + }, + { + "ID": 2, + "sender": "Moa", + "receiver": "Toa", + "amount": 99, + "isFake": false + }, + { + "ID": 4, + "sender": "3", + "receiver": "5", + "amount": 1, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "43", + "amount": 2, + "isFake": false + }, + { + "ID": 5, + "sender": "1", + "receiver": "76", + "amount": 8, + "isFake": false + }, + { + "ID": 65, + "sender": "43", + "receiver": "12", + "amount": 76, + "isFake": false + } +] \ No newline at end of file diff --git a/alexey-cloud/server9/neigh.yaml b/alexey-cloud/server9/neigh.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f68d102eabff5a6d7df7e76e302f8f017cbd4894 --- /dev/null +++ b/alexey-cloud/server9/neigh.yaml @@ -0,0 +1,9 @@ +id: 9 +address: "35.193.74.132" +neighbours: + - id: 4 + address: "35.225.130.115" + edge_weight: 7 + - id: 7 + address: "34.123.88.238" + edge_weight: 7 diff --git a/alexey-cloud/server9/parser.go b/alexey-cloud/server9/parser.go new file mode 100644 index 0000000000000000000000000000000000000000..1fd76de17ce64e72d28a9c6f15fd81d9e7e18109 --- /dev/null +++ b/alexey-cloud/server9/parser.go @@ -0,0 +1,215 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Transaction struct { + ID int `json:"ID"` + Sender string `json:"sender"` + Receiver string `json:"receiver"` + Amount int `json:"amount"` + IsFake bool `json:"isFake"` +} + +type Node struct { + ID int `yaml:"id"` + Address string `yaml:"address"` + Neighbours []Neighbours `yaml:"neighbours"` +} + +type Neighbours struct { + ID int `yaml:"id"` + Address string `yaml:"address"` +} + +func ListOfTransactions() { + // Open our jsonFile + jsonFile, err := os.Open("node1.json") + // if we os.Open returns an error then handle it + if err != nil { + fmt.Println(err) + } + fmt.Println("Successfully Opened node1.json") + // read our opened jsonFile as a byte array. + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + // we unmarshal our byteArray which contains our + // jsonFile's content into 'transaction' which we defined above + json.Unmarshal(byteValue, &transactions) + + for i := 0; i < len(transactions); i++ { + fmt.Println("ID:" + strconv.Itoa(transactions[i].ID)) + fmt.Println("Sender: " + transactions[i].Sender) + fmt.Println("Receiver: " + transactions[i].Receiver) + fmt.Println("Amount: " + strconv.Itoa(transactions[i].Amount)) + fmt.Println("isFake: " + strconv.FormatBool(transactions[i].IsFake)) + } + // defer the closing of our jsonFile so that we can parse it later on + defer jsonFile.Close() +} + +func AppendData(newTrans Transaction, filename string) { + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + + file, _ := ioutil.ReadAll(jsonFile) + data := []Transaction{} + json.Unmarshal(file, &data) + + data = append(data, newTrans) + dataBytes, _ := json.MarshalIndent(data, "", " ") + + _ = ioutil.WriteFile(filename, dataBytes, 0666) +} + +func Fake(fakeID int, fakeTrans Transaction) { + jsonFile, err := os.Open("node1.json") + if err != nil { + fmt.Println(err) + } + + byteValue, _ := ioutil.ReadAll(jsonFile) + + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + print(transactions[i].ID) + if transactions[i].ID == fakeID { + transactions[i] = fakeTrans + } + } + dataBytes, _ := json.MarshalIndent(transactions, "", " ") + + _ = ioutil.WriteFile("node1.json", dataBytes, 0666) +} + +func ReadYAML(filename string) Node { + file, err := ioutil.ReadFile(filename) + if err != nil { + panic(err) + } + var yamlData Node + err = yaml.Unmarshal(file, &yamlData) + + if err != nil { + panic(err) + } + + return yamlData +} + +func TrimLeftChar(s string) string { + for i := range s { + if i > 0 { + return s[i:] + } + } + return s[:0] +} + +func TradeFromString(message string, filename string) { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, _ := strconv.ParseBool(tablMessage[4]) + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + print(isFake) + AppendData(*newTrans, filename) +} + +func removePortInString(address string) string { + for i := 0; i < len(address); i++ { + if address[i] == ':' { + address = address[:i] + break + } + } + return address +} + +func checkTrade(message string, filename string) int { + tablMessage := strings.Split(message, " ") + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + id, _ := strconv.ParseInt(tablMessage[0], 10, 32) + amount, _ := strconv.ParseInt(tablMessage[3], 10, 32) + isFake, err := strconv.ParseBool(tablMessage[4]) + if err != nil { + fmt.Println(err) + } + newTrans := &Transaction{ + ID: int(id), + Sender: tablMessage[1], + Receiver: tablMessage[2], + Amount: int(amount), + IsFake: isFake, + } + jsonFile, err := os.Open(filename) + if err != nil { + fmt.Println(err) + } + byteValue, _ := ioutil.ReadAll(jsonFile) + var transactions []Transaction + json.Unmarshal(byteValue, &transactions) + for i := 0; i < len(transactions); i++ { + if transAreEqual(transactions[i], *newTrans) { + return 1 + } + } + return 0 +} + +func getNbrOfTrade(message string) int { + if message[len(message)-1] == '\n' { + message = message[:len(message)-1] + } + tablMessage := strings.Split(message, " ") + if len(tablMessage) == 6 { + nbrTrade, err := strconv.ParseInt(tablMessage[5], 10, 32) + if err != nil { + fmt.Println(err) + } + return int(nbrTrade) + } + return 0 +} + +func transAreEqual(trans1 Transaction, trans2 Transaction) bool { + if trans1.ID != trans2.ID { + return false + } + if trans1.Sender != trans2.Sender { + return false + } + if trans1.Receiver != trans2.Receiver { + return false + } + if trans1.Amount != trans2.Amount { + return false + } + if trans1.IsFake != trans2.IsFake { + return false + } + return true +} diff --git a/alexey-cloud/server9/server.go b/alexey-cloud/server9/server.go new file mode 100644 index 0000000000000000000000000000000000000000..de83d3353abc2f61b60f17bee7f561b3fdc33f91 --- /dev/null +++ b/alexey-cloud/server9/server.go @@ -0,0 +1,179 @@ +package main + +import ( + "bufio" + "fmt" + "net" + "os" + "strconv" + "strings" + "sync" + "time" +) + +var mode = 0 +var parent = "" +var rate = 0 +var client = "" +var root = false + +func start(serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + print("Server " + serverNbr + " Starting on port " + node.Address + ":8000\n") + ln, err := net.Listen("tcp", ":8000") + if err != nil { + fmt.Println(err) + return + } + for { + conn, err := ln.Accept() + if err != nil { + fmt.Println(err) + return + } + go handle(conn, serverNbr) + time.Sleep(50 * time.Millisecond) //besoin d'attendre sinon confli + } +} + +func handle(conn net.Conn, serverNbr string) { + message, _ := bufio.NewReader(conn).ReadString('\n') + println("from" + conn.RemoteAddr().String() + " " + "Message received:" + message) + var mutex = &sync.Mutex{} + if message[0:1] == "M" { + root = true + broadcast(TrimLeftChar(message), serverNbr) + } else if message[0:1] == "S" { // + mutex.Lock() + broadcast(TrimLeftChar(message), serverNbr) + mutex.Unlock() + } + if message[0:1] == "N" { //si message client requete rate + mode = 0 + parent = "root" + rate += checkTrade(TrimLeftChar(message), "server"+serverNbr+"/data.json") + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + } else if message[0:1] == "A" { //message envoye au voisin ACK + mutex.Lock() + mode++ + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } else if message[0:1] == "R" { //message envoye au parent ACK + mutex.Lock() + mode++ + rate += getNbrOfTrade(message) + broadcastWithAck(TrimLeftChar(message), serverNbr, conn) + mutex.Unlock() + } +} + +func broadcast(message string, serverNbr string) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + mode++ + if mode == 1 { + TradeFromString(message, "server"+serverNbr+"/data.json") + sendToNeighbours(node, message) + } + if mode == len(node.Neighbours) && !root { + mode = 0 + } else if mode == len(node.Neighbours)+1 && root { + mode = 0 + root = false + } +} + +func sendToNeighbours(node Node, message string) { + message = "S" + message + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + for i := 0; i < len(node.Neighbours); i++ { + // receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func broadcastWithAck(message string, serverNbr string, conn net.Conn) { + var node Node = ReadYAML("server" + serverNbr + "/neigh.yaml") + if mode == 0 { + client = conn.RemoteAddr().String() + sendToNeighboursACK(node, message) + } else { + if parent == "" { + parent = conn.RemoteAddr().String() + rate += checkTrade(message, "server"+serverNbr+"/data.json") + sendToNeighboursACK(node, message) + } + if mode == len(node.Neighbours) { + if parent == "root" { + sendToClient(node) + } else { + sendToParent(node, message, serverNbr) + } + } + } +} + +func sendToNeighboursACK(node Node, message string) { + //sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + message = "A" + message + for i := 0; i < len(node.Neighbours); i++ { + if removePortInString(parent) == node.Neighbours[i].Address { + continue + } + //receiver, _ := net.ResolveTCPAddr("tcp", node.Neighbours[i].Address+":8000") + conn, err := net.Dial("tcp", node.Neighbours[i].Address+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, message) + } +} + +func sendToParent(node Node, message string, serverNbr string) { + tablMessage := strings.Split(message, " ") + newMessage := "" + if tablMessage[4][len(tablMessage[4])-1] == '\n' { + tablMessage[4] = tablMessage[4][:len(tablMessage[4])-1] + } + for i := 0; i < 5; i++ { + newMessage = newMessage + " " + tablMessage[i] + if i == 4 { + newMessage = newMessage + " " + strconv.Itoa(rate) + "\n" + } + } + newMessage = "R" + TrimLeftChar(newMessage) + // sender, _ := net.ResolveTCPAddr("tcp", node.Address+":0") + // receiver, _ := net.ResolveTCPAddr("tcp", removePortInString(parent)+":8000") + conn, err := net.Dial("tcp", removePortInString(parent)+":8000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprint(conn, newMessage) + parent = "" + mode = 0 + rate = 0 + println() +} + +func sendToClient(node Node) { + conn, err := net.Dial("tcp", removePortInString(client)+":9000") + if err != nil { + fmt.Println(err) + return + } + fmt.Fprintln(conn, rate) + parent = "" + client = "" + mode = 0 + rate = 0 +} + +func main() { + start(os.Args[1]) +} diff --git a/alexey-cloud/workspace.code-workspace b/alexey-cloud/workspace.code-workspace new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/alexey-cloud/workspace.code-workspace @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/alexey/README.md b/alexey/README.md index 594ba23b6d799bdc34bc5cb27e52d47fbb76f8c0..3dd7e590268fd3114a6f2549e2eab49482c2bb87 100644 --- a/alexey/README.md +++ b/alexey/README.md @@ -6,4 +6,5 @@ So for server 1 its "bash script.sh 1", "bash script.sh 5" for server 5 After that do: go build ./main -And the programme will ask you to type in what you need. +And the programme will ask you to type in what you need. +For cloud version you need my machines images, and the call client back for rate doesnt work.