gremlin

package module
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2020 License: MIT Imports: 13 Imported by: 0

README

Gremlin Server Client for Go

This library will allow you to connect to any graph database that supports TinkerPop3 using Go. This includes databases like JanusGraph and Neo4J. TinkerPop3 uses Gremlin Server to communicate with clients using either WebSockets or REST API. This library talks to Gremlin Server using WebSockets.

NB: Please note that this driver is currently looking for maintainers.

Installation

go get github.com/go-gremlin/gremlin

Usage

Export the list of databases you want to connect to as GREMLIN_SERVERS like so:-

export GREMLIN_SERVERS="ws://server1:8182/gremlin, ws://server2:8182/gremlin"

Import the library eg import "github.com/go-gremlin/gremlin".

Parse and save your cluster of services. You only need to do this once before submitting any queries (Perhaps in main()):-

	if err := gremlin.NewCluster(); err != nil {
		// handle error here
	}

Instead of using an environment variable, you can also pass the servers directly to NewCluster(). This is more convenient in development. For example:-

	if err := gremlin.NewCluster("ws://dev.local:8182/gremlin", "ws://staging.local:8182/gremlin"); err != nil {
		// handle error
	}

To actually run queries against the database, make sure the package is imported and issue a gremlin query like this:-

	data, err := gremlin.Query(`g.V()`).Exec()
	if err != nil  {
		// handle error
	}

data is a JSON array in bytes []byte if any data is returned otherwise it is nil. For example you can print it using:-

	fmt.Println(string(data))

or unmarshal it as desired.

You can also execute a query with bindings like this:-

	data, err := gremlin.Query(`g.V().has("name", userName).valueMap()`).Bindings(gremlin.Bind{"userName": "john"}).Exec()

You can also execute a query with Session, Transaction and Aliases

	aliases := make(map[string]string)
	aliases["g"] = fmt.Sprintf("%s.g", "demo-graph")
	session := "de131c80-84c0-417f-abdf-29ad781a7d04"  //use UUID generator
	data, err := gremlin.Query(`g.V().has("name", userName).valueMap()`).Bindings(gremlin.Bind{"userName": "john"}).Session(session).ManageTransaction(true).SetProcessor("session").Aliases(aliases).Exec()

Authentication

For authentication, you can set environment variables GREMLIN_USER and GREMLIN_PASS and create a Client, passing functional parameter OptAuthEnv

	auth := gremlin.OptAuthEnv()
	client, err := gremlin.NewClient("ws://remote.example.com:443/gremlin", auth)
	data, err = client.ExecQuery(`g.V()`)
	if err != nil {
		panic(err)
	}
	doStuffWith(data)

If you don't like environment variables you can authenticate passing username and password string in the following way:

	auth := gremlin.OptAuthUserPass("myusername", "mypass")
	client, err := gremlin.NewClient("ws://remote.example.com:443/gremlin", auth)
	data, err = client.ExecQuery(`g.V()`)
	if err != nil {
		panic(err)
	}
	doStuffWith(data)

Documentation

Index

Constants

View Source
const (
	StatusSuccess                  = 200
	StatusNoContent                = 204
	StatusPartialContent           = 206
	StatusUnauthorized             = 401
	StatusAuthenticate             = 407
	StatusMalformedRequest         = 498
	StatusInvalidRequestArguments  = 499
	StatusServerError              = 500
	StatusScriptEvaluationError    = 597
	StatusServerTimeout            = 598
	StatusServerSerializationError = 599
)
View Source
const TheBigestMaxGremlinConnectionsLimit = 5

Variables

View Source
var ErrorMsg = map[int]string{
	StatusUnauthorized:             "Unauthorized",
	StatusAuthenticate:             "Authenticate",
	StatusMalformedRequest:         "Malformed Request",
	StatusInvalidRequestArguments:  "Invalid Request Arguments",
	StatusServerError:              "Server Error",
	StatusScriptEvaluationError:    "Script Evaluation Error",
	StatusServerTimeout:            "Server Timeout",
	StatusServerSerializationError: "Server Serialization Error",
}

Functions

func CreateConnection

func CreateConnection() (conn net.Conn, server *url.URL, err error)

func GraphSONSerializer

func GraphSONSerializer(req *Request) ([]byte, error)

func NewCluster

func NewCluster(s ...string) (err error)

func SplitServers

func SplitServers(connString string) (servers []*url.URL, err error)

Types

type AuthInfo

type AuthInfo struct {
	ChallengeId string
	User        string
	Pass        string
}

AuthInfo includes all info related with SASL authentication with the Gremlin server ChallengeId is the requestID in the 407 status (AUTHENTICATE) response given by the server. We have to send an authentication request with that same RequestID in order to solve the challenge.

func NewAuthInfo

func NewAuthInfo(options ...OptAuth) (*AuthInfo, error)

Constructor for different authentication possibilities

type Bind

type Bind map[string]interface{}

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

func (*Connection) ReadResponse

func (c *Connection) ReadResponse() (data []byte, err error)

type FormattedReq

type FormattedReq struct {
	Op        string       `json:"op"`
	RequestId interface{}  `json:"requestId"`
	Args      *RequestArgs `json:"args"`
	Processor string       `json:"processor"`
}

Formats the requests in the appropriate way

func NewFormattedReq

func NewFormattedReq(req *Request) FormattedReq

type OptAuth

type OptAuth func(*AuthInfo) error

func OptAuthEnv

func OptAuthEnv() OptAuth

Sets authentication info from environment variables GREMLIN_USER and GREMLIN_PASS

func OptAuthUserPass

func OptAuthUserPass(user, pass string) OptAuth

Sets authentication information from username and password

type Pool

type Pool struct {
	MaxConnections int
	Auth           []OptAuth
	Connections    chan Connection
	// contains filtered or unexported fields
}

Clients include the necessary info to connect to the server and the underlying socket

func NewClient

func NewClient(urlStr string, origin string, maxConn []int, options ...OptAuth) (*Pool, error)

func (*Pool) Authenticate

func (p *Pool) Authenticate(requestId string) ([]byte, error)

Authenticates the connection

func (*Pool) Exec

func (p *Pool) Exec(req *Request) ([]byte, error)

func (*Pool) ExecQuery

func (p *Pool) ExecQuery(query string) ([]byte, error)

func (*Pool) Get

func (p *Pool) Get() Connection

func (*Pool) Put

func (p *Pool) Put(conn Connection)

Put - put used connection back to poll and get positive status if it's gone well

type Request

type Request struct {
	RequestId string       `json:"requestId"`
	Op        string       `json:"op"`
	Processor string       `json:"processor"`
	Args      *RequestArgs `json:"args"`
}

func Close

func Close() *Request

func Query

func Query(query string) *Request

func (*Request) Aliases

func (req *Request) Aliases(aliases map[string]string) *Request

func (*Request) Bindings

func (req *Request) Bindings(bindings Bind) *Request

func (*Request) ManageTransaction

func (req *Request) ManageTransaction(flag bool) *Request

func (*Request) Session

func (req *Request) Session(session string) *Request

func (*Request) SetProcessor

func (req *Request) SetProcessor(processor string) *Request

type RequestArgs

type RequestArgs struct {
	Gremlin           string            `json:"gremlin,omitempty"`
	Session           string            `json:"session,omitempty"`
	Bindings          Bind              `json:"bindings,omitempty"`
	Language          string            `json:"language,omitempty"`
	Rebindings        Bind              `json:"rebindings,omitempty"`
	Sasl              string            `json:"sasl,omitempty"`
	BatchSize         int               `json:"batchSize,omitempty"`
	ManageTransaction bool              `json:"manageTransaction,omitempty"`
	Aliases           map[string]string `json:"aliases,omitempty"`
}

type Response

type Response struct {
	RequestId string          `json:"requestId"`
	Status    *ResponseStatus `json:"status"`
	Result    *ResponseResult `json:"result"`
}

func (Response) String

func (r Response) String() string

Implementation of the stringer interface. Useful for exploration

type ResponseResult

type ResponseResult struct {
	Data json.RawMessage        `json:"data"`
	Meta map[string]interface{} `json:"meta"`
}

type ResponseStatus

type ResponseStatus struct {
	Code       int                    `json:"code"`
	Attributes map[string]interface{} `json:"attributes"`
	Message    string                 `json:"message"`
}

Jump to

Keyboard shortcuts

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