github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/devicetwin/dtmanager/communicate.go (about) 1 package dtmanager 2 3 import ( 4 "encoding/json" 5 "errors" 6 "strings" 7 "time" 8 9 "k8s.io/klog" 10 11 beehiveContext "github.com/kubeedge/beehive/pkg/core/context" 12 "github.com/kubeedge/beehive/pkg/core/model" 13 connect "github.com/kubeedge/kubeedge/edge/pkg/common/cloudconnection" 14 "github.com/kubeedge/kubeedge/edge/pkg/devicetwin/dtcommon" 15 "github.com/kubeedge/kubeedge/edge/pkg/devicetwin/dtcontext" 16 "github.com/kubeedge/kubeedge/edge/pkg/devicetwin/dttype" 17 ) 18 19 var ( 20 //ActionCallBack map for action to callback 21 ActionCallBack map[string]CallBack 22 ) 23 24 //CommWorker deal app response event 25 type CommWorker struct { 26 Worker 27 Group string 28 } 29 30 //Start worker 31 func (cw CommWorker) Start() { 32 initActionCallBack() 33 for { 34 select { 35 case msg, ok := <-cw.ReceiverChan: 36 klog.Info("receive msg commModule") 37 if !ok { 38 return 39 } 40 if dtMsg, isDTMessage := msg.(*dttype.DTMessage); isDTMessage { 41 if fn, exist := ActionCallBack[dtMsg.Action]; exist { 42 _, err := fn(cw.DTContexts, dtMsg.Identity, dtMsg.Msg) 43 if err != nil { 44 klog.Errorf("CommModule deal %s event failed: %v", dtMsg.Action, err) 45 } 46 } else { 47 klog.Errorf("CommModule deal %s event failed, not found callback", dtMsg.Action) 48 } 49 } 50 51 case <-time.After(time.Duration(60) * time.Second): 52 cw.checkConfirm(cw.DTContexts, nil) 53 case v, ok := <-cw.HeartBeatChan: 54 if !ok { 55 return 56 } 57 if err := cw.DTContexts.HeartBeat(cw.Group, v); err != nil { 58 return 59 } 60 } 61 } 62 } 63 64 func initActionCallBack() { 65 ActionCallBack = make(map[string]CallBack) 66 ActionCallBack[dtcommon.SendToCloud] = dealSendToCloud 67 ActionCallBack[dtcommon.SendToEdge] = dealSendToEdge 68 ActionCallBack[dtcommon.LifeCycle] = dealLifeCycle 69 ActionCallBack[dtcommon.Confirm] = dealConfirm 70 } 71 72 func dealSendToEdge(context *dtcontext.DTContext, resource string, msg interface{}) (interface{}, error) { 73 beehiveContext.Send(dtcommon.EventHubModule, *msg.(*model.Message)) 74 return nil, nil 75 } 76 func dealSendToCloud(context *dtcontext.DTContext, resource string, msg interface{}) (interface{}, error) { 77 if strings.Compare(context.State, dtcommon.Disconnected) == 0 { 78 klog.Infof("Disconnected with cloud,not send msg to cloud") 79 return nil, nil 80 } 81 message, ok := msg.(*model.Message) 82 if !ok { 83 return nil, errors.New("msg not Message type") 84 } 85 beehiveContext.Send(dtcommon.HubModule, *message) 86 msgID := message.GetID() 87 context.ConfirmMap.Store(msgID, &dttype.DTMessage{Msg: message, Action: dtcommon.SendToCloud, Type: dtcommon.CommModule}) 88 return nil, nil 89 } 90 func dealLifeCycle(context *dtcontext.DTContext, resource string, msg interface{}) (interface{}, error) { 91 klog.Infof("CONNECTED EVENT") 92 message, ok := msg.(*model.Message) 93 if !ok { 94 return nil, errors.New("msg not Message type") 95 } 96 connectedInfo, _ := (message.Content.(string)) 97 if strings.Compare(connectedInfo, connect.CloudConnected) == 0 { 98 if strings.Compare(context.State, dtcommon.Disconnected) == 0 { 99 _, err := detailRequest(context, msg) 100 if err != nil { 101 klog.Errorf("detail request: %v", err) 102 return nil, err 103 } 104 } 105 context.State = dtcommon.Connected 106 } else if strings.Compare(connectedInfo, connect.CloudDisconnected) == 0 { 107 context.State = dtcommon.Disconnected 108 } 109 return nil, nil 110 } 111 func dealConfirm(context *dtcontext.DTContext, resource string, msg interface{}) (interface{}, error) { 112 klog.Infof("CONFIRM EVENT") 113 value, ok := msg.(*model.Message) 114 115 if ok { 116 parentMsgID := value.GetParentID() 117 klog.Infof("CommModule deal confirm msgID %s", parentMsgID) 118 context.ConfirmMap.Delete(parentMsgID) 119 } else { 120 return nil, errors.New("CommModule deal confirm, type not correct") 121 } 122 return nil, nil 123 } 124 125 func detailRequest(context *dtcontext.DTContext, msg interface{}) (interface{}, error) { 126 //todo eventid uuid 127 getDetail := dttype.GetDetailNode{ 128 EventType: "group_membership_event", 129 EventID: "123", 130 Operation: "detail", 131 GroupID: context.NodeName, 132 TimeStamp: time.Now().UnixNano() / 1000000} 133 getDetailJSON, marshalErr := json.Marshal(getDetail) 134 if marshalErr != nil { 135 klog.Errorf("Marshal request error while request detail, err: %#v", marshalErr) 136 return nil, marshalErr 137 } 138 139 message := context.BuildModelMessage("resource", "", "membership/detail", "get", string(getDetailJSON)) 140 klog.Info("Request detail") 141 msgID := message.GetID() 142 context.ConfirmMap.Store(msgID, &dttype.DTMessage{Msg: message, Action: dtcommon.SendToCloud, Type: dtcommon.CommModule}) 143 beehiveContext.Send(dtcommon.HubModule, *message) 144 return nil, nil 145 } 146 147 func (cw CommWorker) checkConfirm(context *dtcontext.DTContext, msg interface{}) (interface{}, error) { 148 klog.Info("CheckConfirm") 149 context.ConfirmMap.Range(func(key interface{}, value interface{}) bool { 150 dtmsg, ok := value.(*dttype.DTMessage) 151 klog.Info("has msg") 152 if !ok { 153 154 } else { 155 klog.Info("redo task due to no recv") 156 if fn, exist := ActionCallBack[dtmsg.Action]; exist { 157 _, err := fn(cw.DTContexts, dtmsg.Identity, dtmsg.Msg) 158 if err != nil { 159 klog.Errorf("CommModule deal %s event failed: %v", dtmsg.Action, err) 160 } 161 } else { 162 klog.Errorf("CommModule deal %s event failed, not found callback", dtmsg.Action) 163 } 164 165 } 166 return true 167 }) 168 return nil, nil 169 }