obsidian

module
v0.0.0-...-719fc17 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 18, 2022 License: MIT

README

Obsidian

Obsidian is my CLI for testing against gRPC servers. While the CLI is written in Go, it's still able to talk to any gRPC server in any language. Obsidian exposes a plugin to protoc to allow serialization and deserialization of all structured data for better performance, better maintainability and smaller size by using the protobuf plugin when interacting with the gRPC server.

Install

To install the protoc plugin binary run:

go get -u github.com/DanielPickens/Obsidian/cmd/protoc-gen-Obsidian

Example

To generate code and to test remote procedural calls to a requested client service.

protoc path/to/file.proto --Obsidian_out=.

It is recommended to place the above command as a Go generate comment in a main.go file.

Create a main.go file that references the generated code.

package main

import (
	"fmt"
	"os"

	"github.com/DanielPickens/Obsidian"
	
	_ "github.com/DanielPickens/Obsidian/example/internal/pb"
)



func main() {
	Obsidian.SetCmdInfo(
		"example-rpc",
		"Make calls to the Example service",
		"example-rpc command has been autogenerated via the protoc plugin https://github.com/DanielPickens/Obsidian/cmd/protoc-gen-Obsidian",
	)
	if err := Obsidian.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
}

The above code is a working example in the ./example directory from this project.

To initiate run:

# Start the server
go run ./example/server/main.go
# Install the CLI
go install ./example/example-rpc
# Make a few calls to the server
example-rpc --addr localhost:50051 example getNumber
example-rpc --addr localhost:50051 example echo --input '{"str":"this is a string", "int": 42, "db": 6.9, "kv" : {"key":"value"}}'

Server

Obsidian wraps the normal grpc protoc plugin so that the tested code can be used by the server as well. Whether you do so is up to you as it is easy enough to generate a call request twice, once for the server without Obsidian and once for the client with Obsidian. This makes it easier to view the code in the server when client application can directly call a method on a server application on a different machine as if it were a local object in the same process. This is also useful for testing. This can be done by running the server with the Obsidian plugin to test procedural calls made from client application to server. Generating the code twice allows the client and server to be decoupled since they do not have to import the same package.

Usage

Using Obsidian allows you to browse the schema for gRPC services, either by querying a server that supports server reflection, by reading proto source files, or by loading in compiled "protoset" files. In fact, the way Obsidian has encoded as a path for the protoc plugin that transforms JSON request data into a binary encoded protobuf is highly useful for this schema. So, if the server you interact with does not support reflection, you will either need the proto source files that define the service or need protoset files that Obsidian can use.

The main objective for this tool is to invoke RPC methods on a gRPC server from the command-line. gRPC servers use a binary encoding on the wire (protocol buffers, or "protobufs" for short). Obsidian is able to decode the binary encoding into a JSON object and then encode the JSON object back into a binary encoding. This is done by using the protocol buffers plugin for protoc.

Docker

Pull the docker image:

docker pull DanielPickens/Obsidian:latest
# Run the service in docker container
docker run DanielPickens/Obsidian api.grpc.me:443 list

Note that there are some pitfalls when using docker:

  • If you need to interact with a server listening on the host client's network, you must specify the host as host.docker.internal instead of localhost (for Mac or Windows) OR have the container use the host network with -network="host" (Linux only).
  • If you need to add proto source files or descriptor sets, you must mount the folder containing the files as a volume (-v $(pwd):/protos) and adjust the import paths to container paths accordingly.
  • If you want to provide the request message via stdin, using the -d @ option, you need to use the -i flag on the docker command in your Dockerfile.

Listing Services

To list all services exposed by a server, use the "list" verb. When using .proto source or protoset files instead of server reflection, this lists all services defined in the source or protoset files. When using server reflection, this lists all services that the server supports.

# Server reflection support
Obsidian localhost:8787 list
# Using compiled protoset files
Obsidian -protoset my-protos.bin list
# Using proto sources

Obsidian -import-path ../protos -proto my-stuff.proto list

The "list" verb also lets you see all methods in a particular service:

Obsidian localhost:8787 list my.custom.server.Service

Directories

Path Synopsis
cmd
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL