| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590 |
- package main
- // TODO: 등록확인 되기 전에는 PM,SM 전송 불가하게 만들 것, 실행파일로 만든 후, AWS 이용해서 여러개 마이크로서비스 상태에서 테스트 해볼것
-
- import (
- "bufio"
- "encoding/json"
- "errors"
- "fmt"
- "github.com/fatih/color"
- "log"
- "math/rand"
- "net"
- "net/rpc"
- "os"
- "os/signal"
- "strconv"
- "strings"
- "syscall"
- "unicode"
- )
-
- const (
- KGM = 1 + iota
- KSM
- PM
- SM
- RM
- WM
- )
-
- type Message struct {
- From string //ip 주소
- Version string
- Time string
- Kind int //종류
- }
-
- type MsgUnit interface {
- // ConvertToJson - send 전 json 형식으로 바꾸는 함수
- ConvertToJson() ([]byte, error)
- // CheckType - Message 의 타입을 알려줌
- CheckType() int
- }
-
- type RegisterMsg struct {
- Message
- PrivateKey int64
- }
-
- type SubscriptionMsg struct {
- Message
- Topic []int64 //대주제
- Value []int64 //피연산자
- Operator []string //연산자
- IsAlpha bool //value가 숫자인지 문자열인지
- }
-
- type PublishMsg struct {
- Message
- Topic []int64 //대주제
- Value []int64 //Topic 의 세부적인 내용
- Content []int64 // 내용
- }
-
- type WithdrawMsg struct {
- Message
- }
-
-
-
- type Receiver struct {
- thisNodeAddr string
- microService MicroService
- }
-
- type MicroService struct {
-
- ClientAddr string
- PrivateKey int64
- ShareKey int64
- // 메세지 미들웨어에 연결되어 있는가
- IsConnected chan bool
- MMAddress string
- }
-
- func (receiver Receiver) Receive(args Args, reply *Reply) error{
- switch args.Kind {
-
- case KSM:
- //var msg KeyShareMsg
- //err := json.Unmarshal(args.JsonMsg, &msg)
- //if err != nil {
- // return err
- //}
- //go func() {
- // _, err := receiver.moscato.Receive(msg)
- // if err != nil {
- //
- // }
- //}()
- //reply.CompleteLog = "received completely"
- case PM:
- var msg PublishMsg
- err := json.Unmarshal(args.JsonMsg, &msg)
- if err != nil {
- return err
- }
- go func() {
- receiver.microService.Receive(msg)
- }()
- reply.CompleteLog = "[" + receiver.thisNodeAddr + "] : pubMsg received"
- //var msg PublishMsg
- //err := json.Unmarshal(args.JsonMsg, &msg)
- //if err != nil {
- // return err
- //}
- //
- //go func() {
- // _, err := receiver.moscato.Receive(msg)
- // if err != nil {
- //
- // }
- //}()
- //reply.CompleteLog = "PM received completely"
- case SM:
- //var msg SubscriptionMsg
- //err := json.Unmarshal(args.JsonMsg, &msg)
- //if err != nil {
- // return err
- //}
- //go func() {
- // _, err := receiver.moscato.Receive(msg)
- // if err != nil {
- //
- // }
- //}()
- //reply.CompleteLog = "received completely"
- case RM:
- var msg RegisterMsg
- err := json.Unmarshal(args.JsonMsg, &msg)
- if err != nil {
- return err
- }
- go func() {
- receiver.microService.Receive(msg)
- }()
- reply.CompleteLog = "[" + receiver.thisNodeAddr + "] : ackRM received"
- case WM:
- //var msg WithdrawMsg
- //err := json.Unmarshal(args.JsonMsg, &msg)
- //if err != nil {
- // return err
- //}
- //go func() {
- // _, err := receiver.moscato.Receive(msg)
- // if err != nil {
- //
- // }
- //}()
- //reply.CompleteLog = "received completely"
- default:
- return errors.New("message type Error: Not registered message type")
- }
- //reply.CompleteLog = "received completely"
- return nil
- }
-
- func (microService MicroService) Receive(msg MsgUnit){
- var msg_type = msg.CheckType()
- //메세지 타입에 따라 다르게 처리
- switch msg_type {
-
- case KSM: //Key share msg
-
- case PM: //Publish msg
- fmt.Println("----- received PM ------")
- DecryptionMsg(msg.(PublishMsg),microService.ShareKey, microService.PrivateKey)
- fmt.Println("------------------------")
-
- case SM: //Subscription msg
-
- case RM: //Register msg
-
- microService.IsConnected <- true
- log.Println("you received RM: Registered Complete!")
-
- case WM: //Withdraw msg
- //moscato.MicroServiceManager.RemoveMicroservice(msg.(*WithdrawMsg).From)
-
- default:
- errors.New("message type Error: Not registered message type")
- }
-
- return
- }
-
-
- func (msg SubscriptionMsg) ConvertToJson() ([]byte, error) {
- js := msg
- jsonBytes, err := json.Marshal(js)
- return jsonBytes, err
- }
-
- func (msg PublishMsg) ConvertToJson() ([]byte, error) {
- js := msg
- jsonBytes, err := json.Marshal(js)
- return jsonBytes, err
- }
-
- func (msg RegisterMsg) ConvertToJson() ([]byte, error) {
- js := msg
- jsonBytes, err := json.Marshal(js)
- return jsonBytes, err
- }
-
- func (msg WithdrawMsg) ConvertToJson() ([]byte, error) {
- js := msg
- jsonBytes, err := json.Marshal(js)
- return jsonBytes, err
- }
-
- func (msg Message) CheckType() int {
- return msg.Kind
- }
-
- func CreatePubMsg(msg Message, topic string, value string, content string) PublishMsg {
- //toPubMsg := new(PublishMsg)
- //toPubMsg.Message = msg
-
- intArr := []rune(topic)
- //fmt.Print("Topic length ")
- //fmt.Println(len(intArr))
- //fmt.Println(len(toPubMsg.Topic))
- var topicInt [] int64
- for index := 0; index < len(intArr); index++ {
- //toPubMsg.Topic = append(toPubMsg.Topic, int64(intArr[index]))
- topicInt = append(topicInt, int64(intArr[index]))
- }
- //fmt.Println(len(toPubMsg.Topic))
-
- intArr = []rune(value)
- var valueInt [] int64
- strInt64, _ := strconv.ParseInt(value, 10, 64)
- if unicode.IsDigit(intArr[0]){
- valueInt = append(valueInt, strInt64)
- } else {
- for index := 0; index < len(intArr); index++ {
- //toPubMsg.Value = append(toPubMsg.Value, int64(intArr[index]))
- valueInt = append(valueInt, int64(intArr[index]))
- }
- }
-
- intArr = []rune(content)
- var contentInt [] int64
- for index := 0; index < len(intArr); index++ {
- //toPubMsg.content = append(toPubMsg.content, int64(intArr[index]))
- contentInt = append(contentInt, int64(intArr[index]))
- }
-
-
- return PublishMsg{msg,topicInt,valueInt,contentInt}
- }
-
- func CreateSubMsg(msg Message, topic string, value string, operator string, isAlpha bool) SubscriptionMsg {
- //toPubMsg := new(PublishMsg)
- //toPubMsg.Message = msg
-
- intArr := []rune(topic)
- //fmt.Print("Topic length ")
- //fmt.Println(len(intArr))
- //fmt.Println(len(toPubMsg.Topic))
- var topicInt [] int64
- for index := 0; index < len(intArr); index++ {
- //toPubMsg.Topic = append(toPubMsg.Topic, int64(intArr[index]))
- topicInt = append(topicInt, int64(intArr[index]))
- }
- //fmt.Println(len(toPubMsg.Topic))
- var valueInt [] int64
- if isAlpha {
- intArr = []rune(value)
-
- for index := 0; index < len(intArr); index++ {
- //toPubMsg.Value = append(toPubMsg.Value, int64(intArr[index]))
- valueInt = append(valueInt, int64(intArr[index]))
- }
- } else {
- stringSlice := strings.Split(value, " ")
- for index:=0; index < len(stringSlice); index++ {
- strInt64, _ := strconv.ParseInt(stringSlice[index], 10, 64)
- valueInt = append(valueInt, strInt64)
- }
- }
- var operatorSlice []string
- operatorSlice = strings.Split(operator, " ")
-
-
- //intArr = []rune(content)
- //var contentInt [] int64
- //for index := 0; index < len(intArr); index++ {
- // //toPubMsg.content = append(toPubMsg.content, int64(intArr[index]))
- // contentInt = append(contentInt, int64(intArr[index]))
- //}
-
-
- return SubscriptionMsg{msg,topicInt,valueInt,operatorSlice, isAlpha}
- }
-
-
- type Args struct { // 매개변수
- JsonMsg [] byte
- Kind int
- }
-
- type Reply struct { // 리턴값
- CompleteLog string
- }
-
- func generateRanUint64() uint64 {
- return uint64(rand.Uint32())<<32 + uint64(rand.Uint32())
- }
-
- func main(){
-
- var argu string
- for _, v := range os.Args {
- if strings.Index(v, "-mma") == 0 {
- argu = strings.Replace(v, "-mma=", "",-1)
- break
- }
- }
- MMAddress := argu
- if argu == "" {
- println("there is no Message Middleware address")
- return
- }
-
-
- args := new(Args)
- reply := new(Reply)
-
- currentIP := getCurrentIPAddr()
- const debugPK = 12345
- privateKey := int64(generateRanUint64())
- shareKey := int64(9999)
-
- microService := MicroService{currentIP,privateKey, shareKey, make(chan bool), MMAddress}
- receiver := Receiver{thisNodeAddr: currentIP,microService: microService}
-
- color.Blue("<current machine address : " + currentIP + "> <MM address : " + MMAddress + ">")
- color.Blue("<private key : " + strconv.FormatUint(uint64(privateKey), 10)+">")
-
- errReg := rpc.Register(receiver)
- if errReg != nil {
- log.Println(errReg)
- return
- }
-
- client, err := rpc.Dial("tcp", microService.MMAddress + ":8160") // RPC 서버에 연결
- if err != nil {
- fmt.Println(err)
- return
- }
- defer client.Close() // main 함수가 끝나기 직전에 RPC 연결을 닫음
-
- go Listen()
-
-
- // Register 메세지 생성
- message := Message{From: microService.ClientAddr, Version: "1", Time: "1", Kind: RM}
- regMsg := RegisterMsg{message, microService.PrivateKey}
- RJsonMsg,_ := regMsg.ConvertToJson()
- args.JsonMsg = RJsonMsg
- args.Kind = RM
- err = client.Call("Receiver.MmReceive", args, reply)
- log.Println("RM sent!")
- if err != nil {
- fmt.Println(err)
- return
- }
- color.Yellow("MM: " + reply.CompleteLog)
-
-
- // 연결 되면 채널로 연결 확인이 되어야 다음 단계로 넘어감
- checkConnect := <- microService.IsConnected
- _ = checkConnect
- fmt.Scanln()
- fmt.Println("***** sending Subscription messages *****")
-
- /*
- 파일에서 subscription 읽어서 subscription 보내기
- **/
- subFile, err := os.Open("subscription.txt")
- if err != nil {
- log.Fatalf("Error when opening file: %s", err)
- }
- defer subFile.Close()
- fileScanner := bufio.NewScanner(subFile)
- var subscriptionText string
- numSub := 0
- for fileScanner.Scan(){
- subscriptionText = fileScanner.Text()
- subscriptionTextSlice := strings.Split(subscriptionText, "/")
- subTopic := subscriptionTextSlice[0]
- subValue := subscriptionTextSlice[1]
- subOperator := subscriptionTextSlice[2]
- var subIsAlpha bool
- if subscriptionTextSlice[3] == "true"{
- subIsAlpha = true
- } else if subscriptionTextSlice[3] == "false" {
- subIsAlpha = false
- } else {
- println(numSub, "subscription isAlpha type error")
- }
-
- message = Message{From: microService.ClientAddr, Version: "1", Time: "1", Kind: SM}
- subMsg := CreateSubMsg(message, subTopic, subValue, subOperator, subIsAlpha)
- //subMsg := CreateSubMsg(message, "soccer", "player", "==", true)
- //fmt.Println(pubMsg)
- subMsg = EncryptionSubMsg(subMsg,microService.ShareKey,microService.PrivateKey)
- jsonMsg,_ := subMsg.ConvertToJson()
- args.JsonMsg = jsonMsg
- args.Kind = subMsg.Kind
- //fmt.Println(subMsg)
-
- //fmt.Println(string(args.JsonMsg))
- err = client.Call("Receiver.MmReceive", args, reply)
- log.Println("SM sent! #:",numSub)
- if err != nil {
- fmt.Println(err)
- return
- }
- //log.Println(reply.CompleteLog)
- color.Yellow("MM: " + reply.CompleteLog)
-
- }
-
- fmt.Scanln()
- fmt.Println("***** sending Publish messages *****")
-
- pubFile, err := os.Open("publish.txt")
- if err != nil {
- log.Fatalf("Error when opening file: %s", err)
- }
- defer pubFile.Close()
- fileScanner2 := bufio.NewScanner(pubFile)
- var publishText string
- numPub := 0
- for fileScanner2.Scan(){
- publishText = fileScanner2.Text()
- publishTextSlice := strings.Split(publishText, "/")
- //fmt.Println(publishTextSlice)
- pubTopic := publishTextSlice[0]
- pubValue := publishTextSlice[1]
- pubContent := publishTextSlice[2]
-
-
- message = Message{From: microService.ClientAddr, Version: "1", Time: "1", Kind: PM}
- pubMsg := CreatePubMsg(message, pubTopic, pubValue, pubContent)
- //subMsg := CreateSubMsg(message, "soccer", "player", "==", true)
- //fmt.Println("Pub.txt",pubMsg)
- pubMsg = EncryptionPubMsg(pubMsg,microService.ShareKey,microService.PrivateKey)
- jsonMsg,_ := pubMsg.ConvertToJson()
- args.JsonMsg = jsonMsg
- args.Kind = pubMsg.Kind
- //fmt.Println(subMsg)
-
- //fmt.Println(string(args.JsonMsg))
- err = client.Call("Receiver.MmReceive", args, reply)
- log.Println("PM sent! #:",numPub)
- if err != nil {
- fmt.Println(err)
- return
- }
- //log.Println(reply.CompleteLog)
- color.Yellow("MM: " + reply.CompleteLog)
-
- }
-
- sigs := make(chan os.Signal, 1)
- done := make(chan bool, 1)
-
- signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
-
- go func() {
- sig := <-sigs
- withDraw(message, client)
- //fmt.Println(sig)
- _ = sig
- done <- true
- fmt.Println("\nquit Moscato Successful and terminate microservice")
- }()
-
- <-done
- return
- }
-
- func withDraw(msg Message, client *rpc.Client){
- msg.Kind = WM
- wdMsg := WithdrawMsg{msg}
- var args Args
- args.JsonMsg, _ = wdMsg.ConvertToJson()
- args.Kind = WM
- var reply Reply
- client.Call("Receiver.MmReceive", args, reply)
- }
-
- func EncryptionPubMsg(msg PublishMsg, gyKey int64, privateKey int64) PublishMsg {
- for index := range msg.Topic {
- msg.Topic[index] = msg.Topic[index] + gyKey + privateKey
- }
- for index := range msg.Value {
- msg.Value[index] = msg.Value[index] + gyKey + privateKey
- }
- for index := range msg.Content {
- msg.Content[index] = msg.Content[index] + gyKey + privateKey
- }
-
-
- return msg
- }
-
- func EncryptionSubMsg(msg SubscriptionMsg, gyKey int64, privateKey int64) SubscriptionMsg {
- for index := range msg.Topic {
- msg.Topic[index] = msg.Topic[index] + gyKey + privateKey
- }
- for index := range msg.Value {
- msg.Value[index] = msg.Value[index] + gyKey + privateKey
- }
- return msg
- }
-
- func DecryptionMsg(msg PublishMsg, gyKey int64, privateKey int64) {
- for index := range msg.Topic {
- msg.Topic[index] = msg.Topic[index] - gyKey - privateKey
- }
- for index := range msg.Value {
- msg.Value[index] = msg.Value[index] - gyKey - privateKey
- }
- for index := range msg.Content {
- msg.Content[index] = msg.Content[index] - gyKey - privateKey
- }
-
- var runeArr []rune
- for index := range msg.Topic {
- runeArr = append(runeArr, rune(int(msg.Topic[index])))
- }
- fmt.Println("Topic is: " + string(runeArr))
- runeArr = nil
-
- for index := range msg.Value {
- runeArr = append(runeArr, rune(int(msg.Value[index])))
- }
-
- if len(runeArr) == 1{
- fmt.Println("Value is: ", runeArr)
- } else {
- fmt.Println("Value is:", string(runeArr))
- }
- //if unicode.IsDigit(runeArr[0]){
- // fmt.Println("Value is: " + string(runeArr))
- //} else {
- // //for index := 0; index < len(intArr); index++ {
- // // //toPubMsg.Value = append(toPubMsg.Value, int64(intArr[index]))
- // // valueInt = append(valueInt, int64(intArr[index]))
- // //}
- //}
-
- runeArr = nil
-
- for index := range msg.Content {
- runeArr = append(runeArr, rune(int(msg.Content[index])))
- }
- fmt.Println("Content is: " + string(runeArr))
- runeArr = nil
-
- }
-
- func Listen() {
- l, err1 := net.Listen("tcp", ":8150") //MM로 부터 받는거
- if err1 != nil {
- log.Fatal(fmt.Sprintf("Unable to listen on given port: %s", err1))
- }
- defer l.Close()
-
-
- for {
- conn, _ := l.Accept()
- go rpc.ServeConn(conn)
- }
- }
|