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)
}