You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

context.go 2.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package messagelayer
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  7. "k8s.io/apimachinery/pkg/watch"
  8. "k8s.io/klog/v2"
  9. "github.com/edgeai-neptune/neptune/pkg/globalmanager/messagelayer/model"
  10. wsContext "github.com/edgeai-neptune/neptune/pkg/globalmanager/messagelayer/ws"
  11. )
  12. // MessageLayer define all functions that message layer must implement
  13. type MessageLayer interface {
  14. SendResourceObject(nodeName string, eventType watch.EventType, obj interface{}) error
  15. ReceiveResourceUpdate() (*ResourceUpdateSpec, error)
  16. Done() <-chan struct{}
  17. }
  18. // ContextMessageLayer build on context
  19. type ContextMessageLayer struct {
  20. }
  21. type ResourceUpdateSpec struct {
  22. Kind string
  23. Namespace string
  24. Name string
  25. Operation string
  26. Content []byte
  27. }
  28. // SendResourceObject message to the node with resource object and event type
  29. func (cml *ContextMessageLayer) SendResourceObject(nodeName string, eventType watch.EventType, obj interface{}) error {
  30. var operation string
  31. switch eventType {
  32. case watch.Added:
  33. operation = "insert"
  34. case watch.Modified:
  35. operation = "update"
  36. case watch.Deleted:
  37. operation = "delete"
  38. default:
  39. // should never get here
  40. return fmt.Errorf("event type: %s unsupported", eventType)
  41. }
  42. var msg model.Message
  43. payload, _ := json.Marshal(obj)
  44. msg.Content = (payload)
  45. // For code simplicity not to duplicate the code,
  46. // here just unmarshal to unifying struct type.
  47. var om metav1.PartialObjectMetadata
  48. err := json.Unmarshal(payload, &om)
  49. if err != nil {
  50. // impossible here, just for in case
  51. return fmt.Errorf("Unmarshal error for %v, err: %w", obj, err)
  52. }
  53. namespace := om.Namespace
  54. kind := strings.ToLower(om.Kind)
  55. name := om.Name
  56. msg.Namespace = namespace
  57. msg.ResourceKind = kind
  58. msg.ResourceName = name
  59. msg.Operation = operation
  60. klog.V(2).Infof("sending %s %s/%s to node(%s)", kind, namespace, name, nodeName)
  61. klog.V(4).Infof("sending %s %s/%s to node(%s), msg:%+v", kind, namespace, name, nodeName, msg)
  62. // TODO: may need to guarantee message send to node
  63. return wsContext.SendToEdge(nodeName, &msg)
  64. }
  65. func (cml *ContextMessageLayer) ReceiveResourceUpdate() (*ResourceUpdateSpec, error) {
  66. nodeName, msg, err := wsContext.ReceiveFromEdge()
  67. if err != nil {
  68. return nil, err
  69. }
  70. klog.V(4).Infof("get message from nodeName %s:%s", nodeName, msg)
  71. namespace := msg.Namespace
  72. kind := strings.ToLower(msg.ResourceKind)
  73. name := msg.ResourceName
  74. operation := msg.Operation
  75. content := msg.Content
  76. return &ResourceUpdateSpec{
  77. Kind: kind,
  78. Namespace: namespace,
  79. Name: name,
  80. Operation: operation,
  81. Content: content,
  82. }, nil
  83. }
  84. // Done signals the message layer is done
  85. func (cml *ContextMessageLayer) Done() <-chan struct{} {
  86. return wsContext.Done()
  87. }
  88. // NewContextMessageLayer create a ContextMessageLayer
  89. func NewContextMessageLayer() MessageLayer {
  90. return &ContextMessageLayer{}
  91. }