Skip to content

gudtech/scamp-go

Repository files navigation

CircleCI SCAMP Go Lang Edition

The scamp package provides all the facilities necessary for participating in a SCAMP environment:

  • Parsing the discovery cache and building a directory of available services
  • Parsing packets streams
  • Parsing and verifying messages

// inventory map[string]int

// severity = expectedInventory.checkIsBad(inventory)

// if severity < happy { // incident = newIncident() // inventoryDiff = diff(inventoryPrev, inventoryNow) // incident.remember(inventoryPrev) // } else { // incident.close() // }

Architecture

Remote services are invoked by first establishing a Connection (TLS under the hood). This Connection can then be used to spawn Sessions which send a Request and block until a Reply is provided.

Usage

func main() {
	scamp.Initialize("/etc/SCAMP/soa.conf")

	conn := new(scamp.Connection)
	err := conn.Connect("127.0.0.1:30100")
	defer conn.Close()

	if err != nil {
		scamp.Error.Printf("could not connect! `%s`\n", err)
		return
	}

	request := scamp.Request{
		Action:         "helloworld.hello",
		envelopeFormat: scamp.ENVELOPE_JSON,
		Version:        1,
	}
	conn.SendRequest(request)
	reply, err := conn.RecvReply()
	if err != nil {
		scamp.Error.Printf("error receving reply: `%s`", err)
	}
	scamp.Info.Printf("got reply: `%s`", reply)
}

Running the test suite

export GOPATH=$PWD go test scamp

Documentation

export GOPATH=$PWD
godoc -http=:6060
# open http://localhost:6060/

CLI

Need to run two components without discovery? Generate a fake discovery cache using the cli

go run cli/scamp.go -announcepath=fixtures/sample_service_spec -keypath=fixtures/sample.key -certpath=fixtures/sample.crt

and then copy this text to /tmp/discovery.cache in your gt-dispatcher.

Tasking

Features

  • Setup Go project
  • TLS session setup
  • cert verification
  • Parse packet
  • Generate packet
  • Generate request
    • Generate request header JSON
  • Parse reply
  • Parse request
    • Route to action based on header JSON
  • Generate reply
  • Verify TLS certificate with /etc/authorized_services
  • Manage connection msgno
  • Parse service cache
  • Choose service listen port randomly from within configured range
  • Announce service
    • Copy Service details to ServiceProxy (which can serialize)
    • Write ServiceProxy to UDP multicast
    • Investigate merging Service/ServiceProxy
  • Route RPC based on service cache
  • Use go logging library
  • AuthZ service support
    • Ticket parsing
    • Ticket verification
    • Put it to use?
  • Chunk body to 128k
  • Reconnect logic
  • What to do if connection goes down during Session exchange?
  • Time out connections
  • ACK packets
    • Modify when sent based on message token
  • Nuke session code and move to client with bidirectional packet streams
  • Audit how connections are freed from demux lookup structure
  • RequestId should be generated on Message allocation, not Message send

Important Restructuring

  • Stream messages bodies
    • Session stream interface? Reader/Writer for bytes? Benefit: integration with patterns/helpers in (io lib)[http://golang.org/pkg/io]
  • Unify concepts of Request/Reply with Message and move that distinction to the direction of the Session
    • Rewrite Request/Reply code to reuse session Reader/Writer under the hood

Rad/Cool Ideas

  • Ragel state machine specification to generate go code

Bugs

  • Fix bug where sending envelope type JSON fails silently (should at least emit 'unknown type' to STDERR)
  • Fix bug where header "type": "request" fails silently (should at least emit 'unknown type' to STDERR)
  • Fix reference to documentation message_id which should read request_id
  • Move to interface design. Message parts which implement Packet so we can specialize Header vs Data which have different bodies from different data types.