RESTful API Client - hqzhang/cloudtestbed GitHub Wiki
#Protobuf and gRCP
Example Addition in Remote server
## write proto: service.proto in myproto directory
syntax = "proto3";
package proto;
message Request {
int64 a = 1;
int64 b = 2;
}
message Response {
int64 result = 1;
}
service AddService {
rpc Add(Request) returns (Response);
rpc Multiply(Request) returns (Response);
}
## generate proto and ssh key
openssl genrsa -out server.key 2048
protoc --proto_path=myproto --go_out=plugins=grpc:myproto service.proto
openssl req -new -x509 -sha256 -key server.key \
-out server.crt -days 3650 -subj "/C=CA/ST=Ontario/L=Ottawa/O=CBS Inc./OU=IT/CN=www.example.com"
## create server/main.go as
package main
import (
"context"
"flag"
"fmt"
"log"
"net"
proto "../myproto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
var port = flag.Int("port", 50051, "the port to serve on")
type server struct { }
func (s *server) Add(ctx context.Context, request *proto.Request) ( *proto.Response, error) {
log.Println("request Add()")
a, b := request.GetA(), request.GetB()
result := a + b
return &proto.Response{Result: result}, nil
}
func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// Create tls based credential.
creds, err := credentials.NewServerTLSFromFile("../server.crt", "../server.key")
if err != nil {
log.Fatalf("failed to create credentials: %v", err)
}
srv := grpc.NewServer(grpc.Creds(creds))
// Register EchoServer on the server.
proto.RegisterAddServiceServer(srv, &server{} )
if err := srv.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
## create client/main.go
package main
import (
"context"
"flag"
"log"
"time"
proto "../myproto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"crypto/tls"
)
var addr = flag.String("addr", "localhost:50051", "the address to connect to")
func main() {
flag.Parse()
config := &tls.Config{
InsecureSkipVerify: true,
}
// Set up a connection to the server.
creds := credentials.NewTLS(config)
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
// Make a echo client and send an RPC.
client := proto.NewAddServiceClient(conn)
// Contact the server and print out its response.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := client.Add(ctx, &proto.Request{A: 2,B: 3})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Add 2 and 3: %d", r.GetResult())
}
## Tested
go run server/main.go
go run client/main.go
2020/05/21 11:37:59 Add 2 and 3: 5
#RESTClient in Golang
func main() {
logging.InitLogger(os.Stdout, os.Stdout, os.Stdout, os.Stderr)
ksClient := restclient.NewrestClient("http://localhost:8888/hello")
ksClient.DoRequest("")
}
package restclient
import (
"bytes"
"cto-github.cisco.com/appstate/logging"
// "encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
)
type restClient struct {
urlBase string
}
func NewrestClient(endpointURI string) *restClient {
return &restClient{
urlBase: endpointURI,
}
}
func (ref *restClient) buildRequest(url string, request string) *http.Request {
fmt.Printf("Restclient buildRequest: START")
/*/
json_req := make(map[string]*RestclientRequest)
json_req["auth"] = Restclient_request
json_req_final, err1 := json.Marshal(json_req)
if err1 != nil {
panic(err1)
}
*/
json_req_final := request
logging.Info.Printf("Restclient json_req_final = %s\n", json_req_final)
var request_str = []byte(json_req_final)
req, err2 := http.NewRequest("POST", url, bytes.NewBuffer(request_str))
if err2 != nil {
panic(err2)
}
req.Header.Set("User-Agent", "python-Restclientclient")
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
logging.Info.Printf("Restclient buildRequest: END")
return req
}
func (ref *restClient) parseResponse(resp *http.Response) (int, string, error) {
logging.Info.Printf("Restclient parseResponse: START")
body, err3 := ioutil.ReadAll(resp.Body)
if err3 != nil {
panic(err3)
}
logging.Info.Println("response=%s\n", string(body) )
/*var Restclient_response_access *RestclientResponseAccess
err4 := json.Unmarshal(body, &Restclient_response_access)
if err4 != nil {
panic(err4)
}
Restclient_response := Restclient_response_access.RestclientResponse
*/
logging.Info.Printf("Restclient parseResponse: END")
return resp.StatusCode, "", nil
}
func (ref *restClient) DoRequest(request string) (string, error) {
logging.Info.Printf("Restclient Authenticate: START")
url := ref.urlBase
auth_req := ref.buildRequest(url, request)
client := &http.Client{}
resp, err5 := client.Do(auth_req)
if err5 != nil {
panic(err5)
}
defer resp.Body.Close()
if resp.StatusCode == 200 || resp.StatusCode == 203 {
_, Restclient_response, _ := ref.parseResponse(resp)
logging.Info.Printf("\nRestclient PARSED response = |%s|\n\n", Restclient_response)
return Restclient_response, nil
}
var str string
switch resp.StatusCode {
case 401:str = "Unauthorized"
case 400:str = "BadRequest"
case 403:str = "Forbidden"
case 404:str = "ItemNotFound"
case 405:str = "BadMethod"
case 503:str = "ServiceUnavailable"
case 413:str = "OverLimit"
}
err_msg := fmt.Sprintf("Restclient Authenticate: Restclient responded %d:%s", resp.StatusCode, str)
return "", errors.New(err_msg)
}