func (l *Location) Read(ctx context.Context, req *api.Request, rsp *api.Response) error { id := extractValue(req.Post["id"]) if len(id) == 0 { return errors.BadRequest(server.Config().Name()+".read", "Require Id") } request := client.NewRequest("go.micro.srv.geo", "Location.Read", &read.Request{ Id: id, }) response := &read.Response{} err := client.Call(ctx, request, response) if err != nil { return errors.InternalServerError(server.Config().Name()+".read", "failed to read location") } b, _ := json.Marshal(response.Entity) rsp.StatusCode = 200 rsp.Body = string(b) return nil }
func (l *Location) Save(ctx context.Context, req *api.Request, rsp *api.Response) error { var latlon map[string]float64 err := json.Unmarshal([]byte(extractValue(req.Post["location"])), &latlon) if err != nil { return errors.BadRequest(server.Config().Name()+".search", "invalid location") } unix, _ := strconv.ParseInt(extractValue(req.Post["timestamp"]), 10, 64) entity := &proto.Entity{ Id: extractValue(req.Post["id"]), Type: extractValue(req.Post["type"]), Location: &proto.Location{ Latitude: latlon["latitude"], Longitude: latlon["longitude"], Timestamp: time.Unix(unix, 0).Unix(), }, } if len(entity.Id) == 0 { return errors.BadRequest(server.Config().Name()+".save", "ID cannot be blank") } p := client.NewPublication(topic, entity) if err := client.Publish(ctx, p); err != nil { log.Errorf("Error publishing to topic %s: %v", topic, err) return errors.InternalServerError(server.Config().Name()+".save", err.Error()) } log.Infof("Publishing entity ID %s", entity.Id) rsp.StatusCode = 200 rsp.Body = `{}` return nil }
func (r *rpcClient) stream(ctx context.Context, address string, request Request, responseChan interface{}) (Streamer, error) { msg := &transport.Message{ Header: make(map[string]string), } md, ok := c.GetMetadata(ctx) if ok { for k, v := range md { msg.Header[k] = v } } msg.Header["Content-Type"] = request.ContentType() c, err := r.opts.transport.Dial(address, transport.WithStream()) if err != nil { return nil, errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err)) } client := rpc.NewClientWithCodec(newRpcPlusCodec(msg, c)) call := client.StreamGo(request.Method(), request.Request(), responseChan) return &rpcStream{ request: request, call: call, client: client, }, nil }
func (h *httpBroker) ServeHTTP(w http.ResponseWriter, req *http.Request) { if req.Method != "POST" { err := errors.BadRequest("go.micro.broker", "Method not allowed") http.Error(w, err.Error(), http.StatusMethodNotAllowed) return } defer req.Body.Close() b, err := ioutil.ReadAll(req.Body) if err != nil { errr := errors.InternalServerError("go.micro.broker", fmt.Sprintf("Error reading request body: %v", err)) w.WriteHeader(500) w.Write([]byte(errr.Error())) return } var m *Message if err = json.Unmarshal(b, &m); err != nil { errr := errors.InternalServerError("go.micro.broker", fmt.Sprintf("Error parsing request body: %v", err)) w.WriteHeader(500) w.Write([]byte(errr.Error())) return } topic := m.Header[":topic"] delete(m.Header, ":topic") if len(topic) == 0 { errr := errors.InternalServerError("go.micro.broker", "Topic not found") w.WriteHeader(500) w.Write([]byte(errr.Error())) return } h.RLock() for _, subscriber := range h.subscribers[topic] { subscriber.fn(m) } h.RUnlock() }
func (r *rpcClient) Stream(ctx context.Context, request Request, responseChan interface{}) (Streamer, error) { service, err := registry.GetService(request.Service()) if err != nil { return nil, errors.InternalServerError("go.micro.client", err.Error()) } if len(service.Nodes) == 0 { return nil, errors.NotFound("go.micro.client", "Service not found") } n := rand.Int() % len(service.Nodes) node := service.Nodes[n] address := node.Address if node.Port > 0 { address = fmt.Sprintf("%s:%d", address, node.Port) } return r.stream(ctx, address, request, responseChan) }
func (l *Location) Search(ctx context.Context, req *api.Request, rsp *api.Response) error { radius, _ := strconv.ParseFloat(extractValue(req.Post["radius"]), 64) typ := extractValue(req.Post["type"]) entities, _ := strconv.ParseInt(extractValue(req.Post["num_entities"]), 10, 64) var latlon map[string]float64 err := json.Unmarshal([]byte(extractValue(req.Post["center"])), &latlon) if err != nil { return errors.BadRequest(server.Config().Name()+".search", "invalid center point") } if len(typ) == 0 { return errors.BadRequest(server.Config().Name()+".search", "type cannot be blank") } if entities == 0 { return errors.BadRequest(server.Config().Name()+".search", "num_entities must be greater than 0") } request := client.NewRequest("go.micro.srv.geo", "Location.Search", &search.Request{ Center: &common.Location{ Latitude: latlon["latitude"], Longitude: latlon["longitude"], }, Radius: radius, NumEntities: entities, Type: typ, }) response := &search.Response{} err = client.Call(ctx, request, response) if err != nil { return errors.InternalServerError(server.Config().Name()+".search", "could not retrieve results") } b, _ := json.Marshal(response.Entities) rsp.StatusCode = 200 rsp.Body = string(b) return nil }
func (r *rpcClient) call(ctx context.Context, address string, request Request, response interface{}) error { msg := &transport.Message{ Header: make(map[string]string), } md, ok := c.GetMetadata(ctx) if ok { for k, v := range md { msg.Header[k] = v } } msg.Header["Content-Type"] = request.ContentType() c, err := r.opts.transport.Dial(address) if err != nil { return errors.InternalServerError("go.micro.client", fmt.Sprintf("Error sending request: %v", err)) } client := rpc.NewClientWithCodec(newRpcPlusCodec(msg, c)) return client.Call(ctx, request.Method(), request.Request(), response) }