Skip to content

Instantly share code, notes, and snippets.

@dimiro1
Last active April 10, 2017 03:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dimiro1/d38aaf4b7d84c2d5c8f0 to your computer and use it in GitHub Desktop.
Save dimiro1/d38aaf4b7d84c2d5c8f0 to your computer and use it in GitHub Desktop.
Implementation of the Thrift Servlet with golang net/http handler function
// Copyright (c) 2016, Claudemiro Alves Feitosa Neto
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package main
import (
"fmt"
"net/http"
"strconv"
"git.apache.org/thrift.git/lib/go/thrift"
"github.com/dimiro1/thrift-go/calculator"
"github.com/zenazn/goji"
"github.com/zenazn/goji/web"
)
type CalculatorHandler struct{}
func (c CalculatorHandler) Sum(a int64, b int64) (int64, error) {
return a + b, nil
}
func sum(c web.C, w http.ResponseWriter, r *http.Request) {
a, _ := strconv.ParseInt(c.URLParams["a"], 10, 64)
b, _ := strconv.ParseInt(c.URLParams["b"], 10, 64)
transport, err := thrift.NewTHttpPostClient("http://localhost:8000/calc/")
if err != nil {
fmt.Printf("Error while creating a new Client: %s\n", err)
}
client := calculator.NewCalculatorClientFactory(transport, thrift.NewTCompactProtocolFactory())
result, err := client.Sum(a, b)
if err != nil {
fmt.Printf("Error while calling the service: %s\n", err)
}
fmt.Fprint(w, result)
}
// NewThriftHandlerFunc is a function that create a ready to use Apache Thrift Handler function
func NewThriftHandlerFunc(processor thrift.TProcessor,
inPfactory, outPfactory thrift.TProtocolFactory) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
transport := thrift.NewStreamTransport(r.Body, w)
processor.Process(inPfactory.GetProtocol(transport), outPfactory.GetProtocol(transport))
}
}
func main() {
handler := CalculatorHandler{}
processor := calculator.NewCalculatorProcessor(handler)
factory := thrift.NewTCompactProtocolFactory()
goji.Get("/:a/:b", sum)
goji.Post("/calc/", NewThriftHandlerFunc(processor, factory, factory))
goji.Serve()
}
package main
import (
"net/http"
"net/http/httptest"
"testing"
"git.apache.org/thrift.git/lib/go/thrift"
"github.com/dimiro1/thrift-go/calculator"
)
var handler calculator.Calculator
var processor thrift.TProcessor
var factories []thrift.TProtocolFactory
func init() {
handler = CalculatorHandler{}
processor = calculator.NewCalculatorProcessor(handler)
factories = []thrift.TProtocolFactory{
thrift.NewTCompactProtocolFactory(),
thrift.NewTJSONProtocolFactory(),
thrift.NewTBinaryProtocolFactory(false, false),
thrift.NewTBinaryProtocolFactory(true, true),
}
}
func Test_ThriftHandlerFunc_with_TProtocol(t *testing.T) {
for _, factory := range factories {
ts := httptest.NewServer(http.HandlerFunc(NewThriftHandlerFunc(processor, factory, factory)))
defer ts.Close()
transport, err := thrift.NewTHttpPostClient(ts.URL)
if err != nil {
t.Errorf("Unexpected error: %+v\n", err)
}
client := calculator.NewCalculatorClientFactory(transport, factory)
a := int64(1)
b := int64(2)
expected, err := handler.Sum(a, b)
if err != nil {
t.Errorf("Unexpected error: %+v\n", err)
}
result, err := client.Sum(a, b)
if err != nil {
t.Errorf("Unexpected error: %+v\n", err)
}
if result != expected {
t.Errorf("Expected %d but got: %+v", expected, result)
}
}
}
service Calculator {
i64 sum(1: i64 a, 2: i64 b)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment