예제 #1
0
파일: save.go 프로젝트: jmptrader/geo-api
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
}
예제 #2
0
파일: api.go 프로젝트: justintv90/micro
func (s *Say) Hello(ctx context.Context, req *api.Request, rsp *api.Response) error {
	log.Info("Received Say.Hello API request")

	name, ok := req.Get["name"]
	if !ok || len(name.Values) == 0 {
		return errors.BadRequest("go.micro.api.greeter", "Name cannot be blank")
	}

	request := client.NewRequest("go.micro.srv.greeter", "Say.Hello", &hello.Request{
		Name: strings.Join(name.Values, " "),
	})

	response := &hello.Response{}

	if err := client.Call(ctx, request, response); err != nil {
		return err
	}

	rsp.StatusCode = 200
	b, _ := json.Marshal(map[string]string{
		"message": response.Msg,
	})
	rsp.Body = string(b)

	return nil
}
예제 #3
0
파일: read.go 프로젝트: jmptrader/geo-api
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
}
예제 #4
0
파일: search.go 프로젝트: jmptrader/geo-api
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
}
예제 #5
0
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()
}
예제 #6
0
func rpcHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}
	defer r.Body.Close()

	var service, method string
	var request interface{}

	// response content type
	w.Header().Set("Content-Type", "application/json")

	switch r.Header.Get("Content-Type") {
	case "application/json":
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			e := errors.BadRequest("go.micro.api", err.Error())
			w.WriteHeader(400)
			w.Write([]byte(e.Error()))
			return
		}

		var body map[string]interface{}
		err = json.Unmarshal(b, &body)
		if err != nil {
			e := errors.BadRequest("go.micro.api", err.Error())
			w.WriteHeader(400)
			w.Write([]byte(e.Error()))
			return
		}

		service = body["service"].(string)
		method = body["method"].(string)
		request = body["request"]
	default:
		r.ParseForm()
		service = r.Form.Get("service")
		method = r.Form.Get("method")
		json.Unmarshal([]byte(r.Form.Get("request")), &request)
	}

	var response map[string]interface{}
	req := client.NewJsonRequest(service, method, request)
	err := client.Call(context.Background(), req, &response)
	if err != nil {
		log.Errorf("Error calling %s.%s: %v", service, method, err)
		ce := errors.Parse(err.Error())
		switch ce.Code {
		case 0:
			w.WriteHeader(500)
		default:
			w.WriteHeader(int(ce.Code))
		}
		w.Write([]byte(ce.Error()))
		return
	}

	b, _ := json.Marshal(response)
	w.Header().Set("Content-Length", strconv.Itoa(len(b)))
	w.Write(b)
}