github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/metamanager/process.go (about)

     1  package metamanager
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	"k8s.io/api/core/v1"
    10  	"k8s.io/klog"
    11  
    12  	"github.com/kubeedge/beehive/pkg/common/util"
    13  	beehiveContext "github.com/kubeedge/beehive/pkg/core/context"
    14  	"github.com/kubeedge/beehive/pkg/core/model"
    15  	"github.com/kubeedge/kubeedge/common/constants"
    16  	connect "github.com/kubeedge/kubeedge/edge/pkg/common/cloudconnection"
    17  	messagepkg "github.com/kubeedge/kubeedge/edge/pkg/common/message"
    18  	"github.com/kubeedge/kubeedge/edge/pkg/common/modules"
    19  	metaManagerConfig "github.com/kubeedge/kubeedge/edge/pkg/metamanager/config"
    20  	"github.com/kubeedge/kubeedge/edge/pkg/metamanager/dao"
    21  )
    22  
    23  //Constants to check metamanager processes
    24  const (
    25  	OK = "OK"
    26  
    27  	GroupResource     = "resource"
    28  	OperationMetaSync = "meta-internal-sync"
    29  
    30  	OperationFunctionAction = "action"
    31  
    32  	OperationFunctionActionResult = "action_result"
    33  
    34  	EdgeFunctionModel   = "edgefunction"
    35  	CloudFunctionModel  = "funcmgr"
    36  	CloudControlerModel = "edgecontroller"
    37  )
    38  
    39  func feedbackError(err error, info string, request model.Message) {
    40  	errInfo := "Something wrong"
    41  	if err != nil {
    42  		errInfo = fmt.Sprintf(info+": %v", err)
    43  	}
    44  	errResponse := model.NewErrorMessage(&request, errInfo).SetRoute(MetaManagerModuleName, request.GetGroup())
    45  	if request.GetSource() == modules.EdgedModuleName {
    46  		sendToEdged(errResponse, request.IsSync())
    47  	} else {
    48  		sendToCloud(errResponse)
    49  	}
    50  }
    51  
    52  func sendToEdged(message *model.Message, sync bool) {
    53  	if sync {
    54  		beehiveContext.SendResp(*message)
    55  	} else {
    56  		beehiveContext.Send(modules.EdgedModuleName, *message)
    57  	}
    58  }
    59  
    60  func sendToEdgeMesh(message *model.Message, sync bool) {
    61  	if sync {
    62  		beehiveContext.SendResp(*message)
    63  	} else {
    64  		beehiveContext.Send(modules.EdgeMeshModuleName, *message)
    65  	}
    66  }
    67  
    68  func sendToCloud(message *model.Message) {
    69  	beehiveContext.SendToGroup(string(metaManagerConfig.Config.ContextSendGroup), *message)
    70  }
    71  
    72  // Resource format: <namespace>/<restype>[/resid]
    73  // return <reskey, restype, resid>
    74  func parseResource(resource string) (string, string, string) {
    75  	tokens := strings.Split(resource, constants.ResourceSep)
    76  	resType := ""
    77  	resID := ""
    78  	switch len(tokens) {
    79  	case 2:
    80  		resType = tokens[len(tokens)-1]
    81  	case 3:
    82  		resType = tokens[len(tokens)-2]
    83  		resID = tokens[len(tokens)-1]
    84  	default:
    85  	}
    86  	return resource, resType, resID
    87  }
    88  
    89  // is resource type require remote query
    90  func requireRemoteQuery(resType string) bool {
    91  	return resType == model.ResourceTypeConfigmap ||
    92  		resType == model.ResourceTypeSecret ||
    93  		resType == constants.ResourceTypeEndpoints ||
    94  		resType == constants.ResourceTypePersistentVolume ||
    95  		resType == constants.ResourceTypePersistentVolumeClaim ||
    96  		resType == constants.ResourceTypeVolumeAttachment ||
    97  		resType == model.ResourceTypeNode
    98  }
    99  
   100  // if resource type is EdgeMesh related
   101  func isEdgeMeshResource(resType string) bool {
   102  	return resType == constants.ResourceTypeService ||
   103  		resType == constants.ResourceTypeServiceList ||
   104  		resType == constants.ResourceTypeEndpoints ||
   105  		resType == model.ResourceTypePodlist
   106  }
   107  
   108  func isConnected() bool {
   109  	return metaManagerConfig.Connected
   110  }
   111  
   112  func msgDebugInfo(message *model.Message) string {
   113  	return fmt.Sprintf("msgID[%s] resource[%s]", message.GetID(), message.GetResource())
   114  }
   115  
   116  func resourceUnchanged(resType string, resKey string, content []byte) bool {
   117  	if resType == model.ResourceTypePodStatus {
   118  		dbRecord, err := dao.QueryMeta("key", resKey)
   119  		if err == nil && len(*dbRecord) > 0 && string(content) == (*dbRecord)[0] {
   120  			return true
   121  		}
   122  	}
   123  
   124  	return false
   125  }
   126  
   127  func (m *metaManager) processInsert(message model.Message) {
   128  	var err error
   129  	var content []byte
   130  	switch message.GetContent().(type) {
   131  	case []uint8:
   132  		content = message.GetContent().([]byte)
   133  	default:
   134  		content, err = json.Marshal(message.GetContent())
   135  		if err != nil {
   136  			klog.Errorf("marshal update message content failed, %s", msgDebugInfo(&message))
   137  			feedbackError(err, "Error to marshal message content", message)
   138  			return
   139  		}
   140  	}
   141  	resKey, resType, _ := parseResource(message.GetResource())
   142  	switch resType {
   143  	case constants.ResourceTypeServiceList:
   144  		var svcList []v1.Service
   145  		err = json.Unmarshal(content, &svcList)
   146  		if err != nil {
   147  			klog.Errorf("Unmarshal insert message content failed, %s", msgDebugInfo(&message))
   148  			feedbackError(err, "Error to unmarshal", message)
   149  			return
   150  		}
   151  		for _, svc := range svcList {
   152  			data, err := json.Marshal(svc)
   153  			if err != nil {
   154  				klog.Errorf("Marshal service content failed, %v", svc)
   155  				continue
   156  			}
   157  			meta := &dao.Meta{
   158  				Key:   fmt.Sprintf("%s/%s/%s", svc.Namespace, constants.ResourceTypeService, svc.Name),
   159  				Type:  constants.ResourceTypeService,
   160  				Value: string(data)}
   161  			err = dao.SaveMeta(meta)
   162  			if err != nil {
   163  				klog.Errorf("Save meta %s failed, svc: %v, err: %v", string(data), svc, err)
   164  				feedbackError(err, "Error to save meta to DB", message)
   165  				return
   166  			}
   167  		}
   168  	default:
   169  		meta := &dao.Meta{
   170  			Key:   resKey,
   171  			Type:  resType,
   172  			Value: string(content)}
   173  		err = dao.SaveMeta(meta)
   174  		if err != nil {
   175  			klog.Errorf("save meta failed, %s: %v", msgDebugInfo(&message), err)
   176  			feedbackError(err, "Error to save meta to DB", message)
   177  			return
   178  		}
   179  	}
   180  
   181  	if resType == constants.ResourceTypeListener {
   182  		// Notify edgemesh only
   183  		resp := message.NewRespByMessage(&message, nil)
   184  		sendToEdgeMesh(resp, true)
   185  		return
   186  	}
   187  
   188  	if isEdgeMeshResource(resType) {
   189  		// Notify edgemesh
   190  		sendToEdgeMesh(&message, false)
   191  	} else {
   192  		// Notify edged
   193  		sendToEdged(&message, false)
   194  	}
   195  
   196  	resp := message.NewRespByMessage(&message, OK)
   197  	sendToCloud(resp)
   198  }
   199  
   200  func (m *metaManager) processUpdate(message model.Message) {
   201  	var err error
   202  	var content []byte
   203  	switch message.GetContent().(type) {
   204  	case []uint8:
   205  		content = message.GetContent().([]byte)
   206  	default:
   207  		content, err = json.Marshal(message.GetContent())
   208  		if err != nil {
   209  			klog.Errorf("marshal update message content failed, %s", msgDebugInfo(&message))
   210  			feedbackError(err, "Error to marshal message content", message)
   211  			return
   212  		}
   213  	}
   214  
   215  	resKey, resType, _ := parseResource(message.GetResource())
   216  	if resType == constants.ResourceTypeServiceList || resType == constants.ResourceTypeEndpointsList || resType == model.ResourceTypePodlist {
   217  		switch resType {
   218  		case constants.ResourceTypeEndpointsList:
   219  			var epsList []v1.Endpoints
   220  			err = json.Unmarshal(content, &epsList)
   221  			if err != nil {
   222  				klog.Errorf("Unmarshal update message content failed, %s", msgDebugInfo(&message))
   223  				feedbackError(err, "Error to unmarshal", message)
   224  				return
   225  			}
   226  			for _, eps := range epsList {
   227  				data, err := json.Marshal(eps)
   228  				if err != nil {
   229  					klog.Errorf("Marshal endpoints content failed, %v", eps)
   230  					continue
   231  				}
   232  
   233  				meta := &dao.Meta{
   234  					Key:   fmt.Sprintf("%s/%s/%s", eps.Namespace, constants.ResourceTypeEndpoints, eps.Name),
   235  					Type:  constants.ResourceTypeEndpoints,
   236  					Value: string(data)}
   237  				err = dao.InsertOrUpdate(meta)
   238  				if err != nil {
   239  					klog.Errorf("Update meta failed, %v", eps)
   240  					continue
   241  				}
   242  			}
   243  			sendToEdgeMesh(&message, false)
   244  			resp := message.NewRespByMessage(&message, OK)
   245  			sendToCloud(resp)
   246  			return
   247  		case constants.ResourceTypeServiceList:
   248  			var svcList []v1.Service
   249  			err = json.Unmarshal(content, &svcList)
   250  			if err != nil {
   251  				klog.Errorf("Unmarshal update message content failed, %s", msgDebugInfo(&message))
   252  				feedbackError(err, "Error to unmarshal", message)
   253  				return
   254  			}
   255  			for _, svc := range svcList {
   256  				data, err := json.Marshal(svc)
   257  				if err != nil {
   258  					klog.Errorf("Marshal service content failed, %v", svc)
   259  					continue
   260  				}
   261  
   262  				meta := &dao.Meta{
   263  					Key:   fmt.Sprintf("%s/%s/%s", svc.Namespace, constants.ResourceTypeService, svc.Name),
   264  					Type:  constants.ResourceTypeService,
   265  					Value: string(data)}
   266  				err = dao.InsertOrUpdate(meta)
   267  				if err != nil {
   268  					klog.Errorf("Update meta failed, %v", svc)
   269  					continue
   270  				}
   271  			}
   272  			sendToEdgeMesh(&message, false)
   273  			resp := message.NewRespByMessage(&message, OK)
   274  			sendToCloud(resp)
   275  			return
   276  		case model.ResourceTypePodlist:
   277  			meta := &dao.Meta{
   278  				Key:   resKey,
   279  				Type:  resType,
   280  				Value: string(content)}
   281  			err = dao.InsertOrUpdate(meta)
   282  			if err != nil {
   283  				klog.Errorf("Update meta failed, %s", msgDebugInfo(&message))
   284  				feedbackError(err, "Error to update meta to DB", message)
   285  				return
   286  			}
   287  			sendToEdgeMesh(&message, false)
   288  			resp := message.NewRespByMessage(&message, OK)
   289  			sendToCloud(resp)
   290  			return
   291  		default:
   292  			klog.Warningf("Resource type %s unknown", resType)
   293  			return
   294  		}
   295  	}
   296  
   297  	if resourceUnchanged(resType, resKey, content) {
   298  		resp := message.NewRespByMessage(&message, OK)
   299  		sendToEdged(resp, message.IsSync())
   300  		klog.Infof("resource[%s] unchanged, no notice", resKey)
   301  		return
   302  	}
   303  
   304  	meta := &dao.Meta{
   305  		Key:   resKey,
   306  		Type:  resType,
   307  		Value: string(content)}
   308  	err = dao.InsertOrUpdate(meta)
   309  	if err != nil {
   310  		klog.Errorf("update meta failed, %s", msgDebugInfo(&message))
   311  		feedbackError(err, "Error to update meta to DB", message)
   312  		return
   313  	}
   314  
   315  	msgSource := message.GetSource()
   316  	switch msgSource {
   317  	//case core.EdgedModuleName:
   318  	case modules.EdgedModuleName:
   319  		sendToCloud(&message)
   320  		resp := message.NewRespByMessage(&message, OK)
   321  		sendToEdged(resp, message.IsSync())
   322  	case CloudControlerModel:
   323  		if isEdgeMeshResource(resType) {
   324  			sendToEdgeMesh(&message, message.IsSync())
   325  		} else {
   326  			sendToEdged(&message, message.IsSync())
   327  		}
   328  		resp := message.NewRespByMessage(&message, OK)
   329  		sendToCloud(resp)
   330  	case CloudFunctionModel:
   331  		beehiveContext.Send(EdgeFunctionModel, message)
   332  	case EdgeFunctionModel:
   333  		sendToCloud(&message)
   334  	default:
   335  		klog.Errorf("unsupport message source, %s", msgSource)
   336  	}
   337  }
   338  
   339  func (m *metaManager) processResponse(message model.Message) {
   340  	var err error
   341  	var content []byte
   342  	switch message.GetContent().(type) {
   343  	case []uint8:
   344  		content = message.GetContent().([]byte)
   345  	default:
   346  		content, err = json.Marshal(message.GetContent())
   347  		if err != nil {
   348  			klog.Errorf("marshal response message content failed, %s", msgDebugInfo(&message))
   349  			feedbackError(err, "Error to marshal message content", message)
   350  			return
   351  		}
   352  	}
   353  
   354  	resKey, resType, _ := parseResource(message.GetResource())
   355  	meta := &dao.Meta{
   356  		Key:   resKey,
   357  		Type:  resType,
   358  		Value: string(content)}
   359  	err = dao.InsertOrUpdate(meta)
   360  	if err != nil {
   361  		klog.Errorf("update meta failed, %s", msgDebugInfo(&message))
   362  		feedbackError(err, "Error to update meta to DB", message)
   363  		return
   364  	}
   365  
   366  	// Notify edged or edgemesh if the data is coming from cloud
   367  	if message.GetSource() == CloudControlerModel {
   368  		if resType == constants.ResourceTypeService || resType == constants.ResourceTypeEndpoints {
   369  			sendToEdgeMesh(&message, message.IsSync())
   370  		} else {
   371  			sendToEdged(&message, message.IsSync())
   372  		}
   373  	} else {
   374  		// Send to cloud if the update request is coming from edged
   375  		sendToCloud(&message)
   376  	}
   377  }
   378  
   379  func (m *metaManager) processDelete(message model.Message) {
   380  	err := dao.DeleteMetaByKey(message.GetResource())
   381  	if err != nil {
   382  		klog.Errorf("delete meta failed, %s", msgDebugInfo(&message))
   383  		feedbackError(err, "Error to delete meta to DB", message)
   384  		return
   385  	}
   386  
   387  	_, resType, _ := parseResource(message.GetResource())
   388  	if resType == constants.ResourceTypeService || resType == constants.ResourceTypeEndpoints {
   389  		// Notify edgemesh
   390  		sendToEdgeMesh(&message, false)
   391  		resp := message.NewRespByMessage(&message, OK)
   392  		sendToCloud(resp)
   393  		return
   394  	}
   395  	if resType == constants.ResourceTypeListener {
   396  		// Notify edgemesh only
   397  		resp := message.NewRespByMessage(&message, OK)
   398  		sendToEdgeMesh(resp, true)
   399  		return
   400  	}
   401  	// Notify edged
   402  	sendToEdged(&message, false)
   403  	resp := message.NewRespByMessage(&message, OK)
   404  	sendToCloud(resp)
   405  }
   406  
   407  func (m *metaManager) processQuery(message model.Message) {
   408  	resKey, resType, resID := parseResource(message.GetResource())
   409  	var metas *[]string
   410  	var err error
   411  	if requireRemoteQuery(resType) && isConnected() {
   412  		metas, err = dao.QueryMeta("key", resKey)
   413  		if err != nil || len(*metas) == 0 || resType == model.ResourceTypeNode || resType == constants.ResourceTypeVolumeAttachment {
   414  			m.processRemoteQuery(message)
   415  		} else {
   416  			resp := message.NewRespByMessage(&message, *metas)
   417  			resp.SetRoute(MetaManagerModuleName, resp.GetGroup())
   418  			sendToEdged(resp, message.IsSync())
   419  		}
   420  		return
   421  	}
   422  
   423  	if resID == "" {
   424  		// Get specific type resources
   425  		metas, err = dao.QueryMeta("type", resType)
   426  	} else {
   427  		metas, err = dao.QueryMeta("key", resKey)
   428  	}
   429  	if err != nil {
   430  		klog.Errorf("query meta failed, %s", msgDebugInfo(&message))
   431  		feedbackError(err, "Error to query meta in DB", message)
   432  	} else {
   433  		resp := message.NewRespByMessage(&message, *metas)
   434  		resp.SetRoute(MetaManagerModuleName, resp.GetGroup())
   435  		if resType == constants.ResourceTypeService || resType == constants.ResourceTypeEndpoints || resType == constants.ResourceTypeListener {
   436  			sendToEdgeMesh(resp, message.IsSync())
   437  		} else {
   438  			sendToEdged(resp, message.IsSync())
   439  		}
   440  	}
   441  }
   442  
   443  func (m *metaManager) processRemoteQuery(message model.Message) {
   444  	go func() {
   445  		// TODO: retry
   446  		originalID := message.GetID()
   447  		message.UpdateID()
   448  		resp, err := beehiveContext.SendSync(
   449  			string(metaManagerConfig.Config.ContextSendModule),
   450  			message,
   451  			60*time.Second) // TODO: configurable
   452  		klog.Infof("########## process get: req[%+v], resp[%+v], err[%+v]", message, resp, err)
   453  		if err != nil {
   454  			klog.Errorf("remote query failed: %v", err)
   455  			feedbackError(err, "Error to query meta in DB", message)
   456  			return
   457  		}
   458  
   459  		var content []byte
   460  		switch resp.GetContent().(type) {
   461  		case []uint8:
   462  			content = resp.GetContent().([]byte)
   463  		default:
   464  			content, err = json.Marshal(resp.GetContent())
   465  			if err != nil {
   466  				klog.Errorf("marshal remote query response content failed, %s", msgDebugInfo(&resp))
   467  				feedbackError(err, "Error to marshal message content", message)
   468  				return
   469  			}
   470  		}
   471  
   472  		resKey, resType, _ := parseResource(message.GetResource())
   473  		meta := &dao.Meta{
   474  			Key:   resKey,
   475  			Type:  resType,
   476  			Value: string(content)}
   477  		err = dao.InsertOrUpdate(meta)
   478  		if err != nil {
   479  			klog.Errorf("update meta failed, %s", msgDebugInfo(&resp))
   480  		}
   481  		resp.BuildHeader(resp.GetID(), originalID, resp.GetTimestamp())
   482  		if resType == constants.ResourceTypeService || resType == constants.ResourceTypeEndpoints {
   483  			sendToEdgeMesh(&resp, message.IsSync())
   484  		} else {
   485  			sendToEdged(&resp, message.IsSync())
   486  		}
   487  
   488  		respToCloud := message.NewRespByMessage(&resp, OK)
   489  		sendToCloud(respToCloud)
   490  	}()
   491  }
   492  
   493  func (m *metaManager) processNodeConnection(message model.Message) {
   494  	content, _ := message.GetContent().(string)
   495  	klog.Infof("node connection event occur: %s", content)
   496  	if content == connect.CloudConnected {
   497  		metaManagerConfig.Connected = true
   498  	} else if content == connect.CloudDisconnected {
   499  		metaManagerConfig.Connected = false
   500  	}
   501  }
   502  
   503  func (m *metaManager) processSync(message model.Message) {
   504  	m.syncPodStatus()
   505  }
   506  
   507  func (m *metaManager) syncPodStatus() {
   508  	klog.Infof("start to sync pod status")
   509  	podStatusRecords, err := dao.QueryAllMeta("type", model.ResourceTypePodStatus)
   510  	if err != nil {
   511  		klog.Errorf("list pod status failed: %v", err)
   512  		return
   513  	}
   514  	if len(*podStatusRecords) <= 0 {
   515  		klog.Infof("list pod status, no record, skip sync")
   516  		return
   517  	}
   518  
   519  	var namespace string
   520  	content := make([]interface{}, 0, len(*podStatusRecords))
   521  	for _, v := range *podStatusRecords {
   522  		if namespace == "" {
   523  			namespace, _, _, _ = util.ParseResourceEdge(v.Key, model.QueryOperation)
   524  		}
   525  		podKey := strings.Replace(v.Key, constants.ResourceSep+model.ResourceTypePodStatus+constants.ResourceSep, constants.ResourceSep+model.ResourceTypePod+constants.ResourceSep, 1)
   526  		podRecord, err := dao.QueryMeta("key", podKey)
   527  		if err != nil {
   528  			klog.Errorf("query pod[%s] failed: %v", podKey, err)
   529  			return
   530  		}
   531  
   532  		if len(*podRecord) <= 0 {
   533  			// pod already deleted, clear the corresponding podstatus record
   534  			err = dao.DeleteMetaByKey(v.Key)
   535  			klog.Infof("pod[%s] already deleted, clear podstatus record, result:%v", podKey, err)
   536  			continue
   537  		}
   538  
   539  		var podStatus interface{}
   540  		err = json.Unmarshal([]byte(v.Value), &podStatus)
   541  		if err != nil {
   542  			klog.Errorf("unmarshal podstatus[%s] failed, content[%s]: %v", v.Key, v.Value, err)
   543  			continue
   544  		}
   545  		content = append(content, podStatus)
   546  	}
   547  
   548  	msg := model.NewMessage("").BuildRouter(MetaManagerModuleName, GroupResource, namespace+constants.ResourceSep+model.ResourceTypePodStatus, model.UpdateOperation).FillBody(content)
   549  	sendToCloud(msg)
   550  	klog.Infof("sync pod status successful, %s", msgDebugInfo(msg))
   551  }
   552  
   553  func (m *metaManager) processFunctionAction(message model.Message) {
   554  
   555  	var err error
   556  	var content []byte
   557  	switch message.GetContent().(type) {
   558  	case []uint8:
   559  		content = message.GetContent().([]byte)
   560  	default:
   561  		content, err = json.Marshal(message.GetContent())
   562  		if err != nil {
   563  			klog.Errorf("marshal save message content failed, %s: %v", msgDebugInfo(&message), err)
   564  			feedbackError(err, "Error to marshal message content", message)
   565  			return
   566  		}
   567  	}
   568  
   569  	resKey, resType, _ := parseResource(message.GetResource())
   570  	meta := &dao.Meta{
   571  		Key:   resKey,
   572  		Type:  resType,
   573  		Value: string(content)}
   574  	err = dao.SaveMeta(meta)
   575  	if err != nil {
   576  		klog.Errorf("save meta failed, %s: %v", msgDebugInfo(&message), err)
   577  		feedbackError(err, "Error to save meta to DB", message)
   578  		return
   579  	}
   580  
   581  	beehiveContext.Send(EdgeFunctionModel, message)
   582  }
   583  
   584  func (m *metaManager) processFunctionActionResult(message model.Message) {
   585  	var err error
   586  	var content []byte
   587  	switch message.GetContent().(type) {
   588  	case []uint8:
   589  		content = message.GetContent().([]byte)
   590  	default:
   591  		content, err = json.Marshal(message.GetContent())
   592  		if err != nil {
   593  			klog.Errorf("marshal save message content failed, %s: %v", msgDebugInfo(&message), err)
   594  			feedbackError(err, "Error to marshal message content", message)
   595  			return
   596  		}
   597  	}
   598  
   599  	resKey, resType, _ := parseResource(message.GetResource())
   600  	meta := &dao.Meta{
   601  		Key:   resKey,
   602  		Type:  resType,
   603  		Value: string(content)}
   604  	err = dao.SaveMeta(meta)
   605  	if err != nil {
   606  		klog.Errorf("save meta failed, %s: %v", msgDebugInfo(&message), err)
   607  		feedbackError(err, "Error to save meta to DB", message)
   608  		return
   609  	}
   610  
   611  	sendToCloud(&message)
   612  
   613  }
   614  
   615  func (m *metaManager) processVolume(message model.Message) {
   616  	klog.Info("process volume started")
   617  	back, err := beehiveContext.SendSync(modules.EdgedModuleName, message, constants.CSISyncMsgRespTimeout)
   618  	klog.Infof("process volume get: req[%+v], back[%+v], err[%+v]", message, back, err)
   619  	if err != nil {
   620  		klog.Errorf("process volume send to edged failed: %v", err)
   621  	}
   622  
   623  	resp := message.NewRespByMessage(&message, back.GetContent())
   624  	sendToCloud(resp)
   625  	klog.Infof("process volume send to cloud resp[%+v]", resp)
   626  }
   627  
   628  func (m *metaManager) process(message model.Message) {
   629  	operation := message.GetOperation()
   630  	switch operation {
   631  	case model.InsertOperation:
   632  		m.processInsert(message)
   633  	case model.UpdateOperation:
   634  		m.processUpdate(message)
   635  	case model.DeleteOperation:
   636  		m.processDelete(message)
   637  	case model.QueryOperation:
   638  		m.processQuery(message)
   639  	case model.ResponseOperation:
   640  		m.processResponse(message)
   641  	case messagepkg.OperationNodeConnection:
   642  		m.processNodeConnection(message)
   643  	case OperationMetaSync:
   644  		m.processSync(message)
   645  	case OperationFunctionAction:
   646  		m.processFunctionAction(message)
   647  	case OperationFunctionActionResult:
   648  		m.processFunctionActionResult(message)
   649  	case constants.CSIOperationTypeCreateVolume,
   650  		constants.CSIOperationTypeDeleteVolume,
   651  		constants.CSIOperationTypeControllerPublishVolume,
   652  		constants.CSIOperationTypeControllerUnpublishVolume:
   653  		m.processVolume(message)
   654  	}
   655  }
   656  
   657  func (m *metaManager) runMetaManager() {
   658  	go func() {
   659  		for {
   660  			select {
   661  			case <-beehiveContext.Done():
   662  				klog.Warning("MetaManager mainloop stop")
   663  				return
   664  			default:
   665  
   666  			}
   667  			if msg, err := beehiveContext.Receive(m.Name()); err == nil {
   668  				klog.Infof("get a message %+v", msg)
   669  				m.process(msg)
   670  			} else {
   671  				klog.Errorf("get a message %+v: %v", msg, err)
   672  			}
   673  		}
   674  	}()
   675  }