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  }