github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edge/pkg/servicebus/servicebus.go (about) 1 package servicebus 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "strings" 9 "time" 10 11 "k8s.io/klog" 12 13 "github.com/kubeedge/beehive/pkg/core" 14 beehiveContext "github.com/kubeedge/beehive/pkg/core/context" 15 "github.com/kubeedge/beehive/pkg/core/model" 16 "github.com/kubeedge/kubeedge/edge/pkg/common/modules" 17 "github.com/kubeedge/kubeedge/edge/pkg/servicebus/util" 18 "github.com/kubeedge/kubeedge/pkg/apis/componentconfig/edgecore/v1alpha1" 19 ) 20 21 const ( 22 sourceType = "router_rest" 23 maxBodySize = 5 * 1e6 24 ) 25 26 // servicebus struct 27 type servicebus struct { 28 enable bool 29 } 30 31 func newServicebus(enable bool) *servicebus { 32 return &servicebus{ 33 enable: enable, 34 } 35 } 36 37 // Register register servicebus 38 func Register(s *v1alpha1.ServiceBus) { 39 core.Register(newServicebus(s.Enable)) 40 } 41 42 func (*servicebus) Name() string { 43 return "servicebus" 44 } 45 46 func (*servicebus) Group() string { 47 return modules.BusGroup 48 } 49 50 func (sb *servicebus) Enable() bool { 51 return sb.enable 52 } 53 54 func (sb *servicebus) Start() { 55 // no need to call TopicInit now, we have fixed topic 56 var htc = new(http.Client) 57 htc.Timeout = time.Second * 10 58 59 var uc = new(util.URLClient) 60 uc.Client = htc 61 62 //Get message from channel 63 for { 64 select { 65 case <-beehiveContext.Done(): 66 klog.Warning("ServiceBus stop") 67 return 68 default: 69 70 } 71 msg, err := beehiveContext.Receive("servicebus") 72 if err != nil { 73 klog.Warningf("servicebus receive msg error %v", err) 74 continue 75 } 76 go func() { 77 klog.Infof("ServiceBus receive msg") 78 source := msg.GetSource() 79 if source != sourceType { 80 return 81 } 82 resource := msg.GetResource() 83 r := strings.Split(resource, ":") 84 if len(r) != 2 { 85 m := "the format of resource " + resource + " is incorrect" 86 klog.Warningf(m) 87 code := http.StatusBadRequest 88 if response, err := buildErrorResponse(msg.GetID(), m, code); err == nil { 89 beehiveContext.SendToGroup(modules.HubGroup, response) 90 } 91 return 92 } 93 content, err := json.Marshal(msg.GetContent()) 94 if err != nil { 95 klog.Errorf("marshall message content failed %v", err) 96 m := "error to marshal request msg content" 97 code := http.StatusBadRequest 98 if response, err := buildErrorResponse(msg.GetID(), m, code); err == nil { 99 beehiveContext.SendToGroup(modules.HubGroup, response) 100 } 101 return 102 } 103 var httpRequest util.HTTPRequest 104 if err := json.Unmarshal(content, &httpRequest); err != nil { 105 m := "error to parse http request" 106 code := http.StatusBadRequest 107 klog.Errorf(m, err) 108 if response, err := buildErrorResponse(msg.GetID(), m, code); err == nil { 109 beehiveContext.SendToGroup(modules.HubGroup, response) 110 } 111 return 112 } 113 operation := msg.GetOperation() 114 targetURL := "http://127.0.0.1:" + r[0] + "/" + r[1] 115 resp, err := uc.HTTPDo(operation, targetURL, httpRequest.Header, httpRequest.Body) 116 if err != nil { 117 m := "error to call service" 118 code := http.StatusNotFound 119 klog.Errorf(m, err) 120 if response, err := buildErrorResponse(msg.GetID(), m, code); err == nil { 121 beehiveContext.SendToGroup(modules.HubGroup, response) 122 } 123 return 124 } 125 resp.Body = http.MaxBytesReader(nil, resp.Body, maxBodySize) 126 resBody, err := ioutil.ReadAll(resp.Body) 127 if err != nil { 128 if err.Error() == "http: request body too large" { 129 err = fmt.Errorf("response body too large") 130 } 131 m := "error to receive response, err: " + err.Error() 132 code := http.StatusInternalServerError 133 klog.Errorf(m, err) 134 if response, err := buildErrorResponse(msg.GetID(), m, code); err == nil { 135 beehiveContext.SendToGroup(modules.HubGroup, response) 136 } 137 return 138 } 139 140 response := util.HTTPResponse{Header: resp.Header, StatusCode: resp.StatusCode, Body: resBody} 141 responseMsg := model.NewMessage(msg.GetID()) 142 responseMsg.Content = response 143 responseMsg.SetRoute("servicebus", modules.UserGroup) 144 beehiveContext.SendToGroup(modules.HubGroup, *responseMsg) 145 }() 146 } 147 } 148 149 func buildErrorResponse(parentID string, content string, statusCode int) (model.Message, error) { 150 responseMsg := model.NewMessage(parentID) 151 h := http.Header{} 152 h.Add("Server", "kubeedge-edgecore") 153 c := util.HTTPResponse{Header: h, StatusCode: statusCode, Body: []byte(content)} 154 responseMsg.Content = c 155 responseMsg.SetRoute("servicebus", modules.UserGroup) 156 return *responseMsg, nil 157 }