package modules import ( "encoding/json" "errors" "fmt" "github.com/fatih/color" l4g "github.com/jeanphorn/log4go" "net" "net/rpc" ) // TODO: RM 처리와 init.go 전반적으로 DI 이용하여 구현 RM 키등록 부분 구현 예정 type Moscato struct { queue MsgQueue SendQueue chan myType MicroServiceManager NodeManager `inject:""` MatchingManager match_manager SubscriptionManager sub_manager SecureManager SecurityManager `inject:""` } type myType struct { subList []string pubMsg MsgUnit err error } type Reply struct { //RPC리턴값 CompleteLog string //제대로 받았는지 확인하는 로그 } type Receiver struct { //RPC 서버에 등록하기 위한 변수 moscato *Moscato } type Args struct { // 매개변수 JsonMsg []byte Kind int } /* MS→MM -MM 실행되면 MM서버는 열려있음(MS은 자동으로 Client)(포트 8150) -Send2MM 호출 → rpc call로 MmReceive호출해서 MM로 전달(json형식) -MmReceive에서 msgType 검사 후 그것에 맞게 msgUnit으로 MM의 Receive로 보냄 -MM의 Receive에서 해당 Message를 처리 */ func (receiver Receiver) MmReceive(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" case PM: 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" 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 = "SM received" case RM: var msg RegisterMsg err := json.Unmarshal(args.JsonMsg, &msg) if err != nil { return err } go func() { _, err := receiver.moscato.Receive(msg) if err != nil { fmt.Println(err) } }() reply.CompleteLog = "RM 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 = "WM received" default: return errors.New("message type Error: Not registered message type") } //reply.CompleteLog = "received completely" return nil } //Recieve - MM가 MS로부터 메세지 전달받음 func (moscato *Moscato) Receive(msg MsgUnit) (MsgUnit, error) { l4g.LoadConfiguration("modules/logConfig.json") //rpc call var msg_type = msg.CheckType() //메세지 타입에 따라 다르게 처리 switch msg_type { case KSM: //Key share msg case PM: //Publish msg //log.Println("PM received") l4g.LOGGER("Test").Info("PM received") moscato.queue.push(moscato.preProcessMsg(msg)) case SM: //Subscription msg //log.Println("SM received") l4g.LOGGER("Test").Info("SM received") err := moscato.SubscriptionManager.addSubscription(moscato.preProcessMsg(msg)) if err != nil { println(err) //return nil, err } case RM: //Register msg //log.Println("RM received") l4g.LOGGER("Test").Info("RM received") l4g.LOGGER("Test").Debug("RM received") var newMsg RegisterMsg newMsg = msg.(RegisterMsg) newNode := MSNode{newMsg.From, newMsg.From} resultAddNode := moscato.MicroServiceManager.AddMicroservice(newNode) if resultAddNode { //log.Println("Node added successful") l4g.LOGGER("Test").Info("Node added successful") } else { l4g.LOGGER("Test").Error("Node is already added, ignore RM") //log.Println("Node is already added, ignore RM") return msg, nil } addr, _ := moscato.MicroServiceManager.GetIpaddr(newMsg.From) moscato.SecureManager.RegKey(newMsg) fmt.Println("Registered microservice: address", addr, "/ key", moscato.SecureManager.GetNodeKey(newMsg.From)) // ackRM 메세지 전송 go moscato.Send2MS(addr, newMsg) case WM: //Withdraw msg //ip := msg.(WithdrawMsg).From //sublist := moscato.SubscriptionManager.ip2sub[ip] //fmt.Println("prev list = ", sublist) moscato.MicroServiceManager.RemoveMicroservice(msg.(WithdrawMsg).From) moscato.SecureManager.RemoveSecureKey(msg.(WithdrawMsg).From) //moscato.SubscriptionManager.delete(ip) //sublist2 := moscato.SubscriptionManager.ip2sub[ip] //fmt.Println("after list =", sublist2) default: return nil, errors.New("Message type Error: Not registered message type") } return msg, nil } //MS로 보낼때 쓸 함수 /* MM→MS -MS 실행되면 MS서버는 열려있음(MM은 자동으로 Client)(포트 8160) -Send2MS 호출 → rpc call로 MsReceive호출해서 MS로 전달(json형식) -MsReceive에서 msgType 검사 후 그것에 맞게 msgUnit으로 MS의 Receive로 보냄 -MS의 Receive에서 해당 Message를 처리 */ func (moscato *Moscato) Send2MS(ipaddress string, msg MsgUnit) { l4g.LoadConfiguration("logConfig.json") client, err := rpc.Dial("tcp", ipaddress+":8150") if err != nil { fmt.Println(err) return } defer client.Close() reply := new(Reply) jmsg, _ := msg.ConvertToJson() args := Args{ JsonMsg: jmsg, Kind: msg.CheckType(), } err = client.Call("Receiver.Receive", args, reply) if err != nil { fmt.Println(err) return } //log.Println(reply.CompleteLog) //잘 받았는지 확인 해줌 // 마이크로 서비스에게 받은 메시지는 노란색으로 출력 //log.Println(reply.CompleteLog) l4g.LOGGER("Test").Info(reply.CompleteLog) } //Matching을 용이하게 하기위한 메세지 가공 과정 func (moscato *Moscato) preProcessMsg(originalMsg MsgUnit) MsgUnit { if originalMsg.CheckType() == PM { pubMsg := originalMsg.(PublishMsg) for index := 0; index < len(pubMsg.Topic); index++ { pubMsg.Topic[index] = pubMsg.Topic[index] - moscato.SecureManager.GetNodeKey(pubMsg.From) } for index := 0; index < len(pubMsg.Value); index++ { pubMsg.Value[index] = pubMsg.Value[index] - moscato.SecureManager.GetNodeKey(pubMsg.From) } return pubMsg } else if originalMsg.CheckType() == SM { subMsg := originalMsg.(SubscriptionMsg) for index := 0; index < len(subMsg.Topic); index++ { subMsg.Topic[index] = subMsg.Topic[index] - moscato.SecureManager.GetNodeKey(subMsg.From) } for index := 0; index < len(subMsg.Value); index++ { subMsg.Value[index] = subMsg.Value[index] - moscato.SecureManager.GetNodeKey(subMsg.From) } return subMsg } return nil } //암호화 해서 보내기 func (moscato *Moscato) SendWithEncrypt() MsgUnit { for { mt := <-moscato.SendQueue if mt.err == nil { for index := 0; index < len(mt.subList); index++ { //sublist들을 돌면서 매세지를 encrypt하여 메세지 보냄 tmpNode := mt.subList[index] tmpNodeIpAddr, _ := moscato.MicroServiceManager.GetIpaddr(tmpNode) //moscato.SecureManager.ReEncPubMsg(mt.pubMsg.(PublishMsg), tmpNode) //fmt.Println("publish: ", mt.pubMsg) //moscato.Send2MS(tmpNodeIpAddr, mt.pubMsg) moscato.Send2MS(tmpNodeIpAddr, moscato.SecureManager.ReEncPubMsg(mt.pubMsg.(PublishMsg), tmpNode)) } } return nil } } func (moscato *Moscato) Run() { config := AppConfig{moscato} config.config() //모스카토 구조체 변수 초기화 receiver := Receiver{moscato: moscato} err := moscato.queue.queue_init() moscato.SendQueue = make(chan myType) moscato.SubscriptionManager.Initialize() if err != nil { fmt.Println(err) return } //go routine -> matching 동작 go func() { for { msg := moscato.queue.pop(true) go moscato.Matching(msg) go moscato.SendWithEncrypt() } }() //go moscato.CheckQueue() //rpc 등록 -> Receive 함수 err = rpc.Register(receiver) if err != nil { println(err) return } go Listen() color.Blue("initializing complete.") fmt.Scanln() } func Listen() { /* MS→MM일때 ⇒ port : 8160으로 열기 (MM이 Server, MS가 Client) */ l, err1 := net.Listen("tcp", ":8160") if err1 != nil { //log.Fatal(fmt.Sprintf("Unable to listen on given port: %s", err1)) l4g.LOGGER("Test").Critical("Unable to listen on given port: %s", err1) } defer l.Close() for { conn, _ := l.Accept() go rpc.ServeConn(conn) } }