<commit_before>package main

import (
	"encoding/xml"
	"os"
	"path/filepath"
	"strings"
)

var (
	parsedFiles map[string]struct{}
)

func parseXSDFile(fname string) ([]xsdSchema, error) {
	schemas := []xsdSchema{}
	parsedFiles = make(map[string]struct{})
	schemas, err := parse(fname)
	if err != nil {
		return nil, err
	}
	return schemas, nil
}

func parse(fname string) ([]xsdSchema, error) {
	f, err := os.Open(fname)
	if err != nil {
		return nil, err
	}

	var schema xsdSchema
	if err := xml.NewDecoder(f).Decode(&schema); err != nil {
		return nil, err
	}
	f.Close()

	schemas := []xsdSchema{schema}
	dir, file := filepath.Split(fname)
	parsedFiles[file] = struct{}{}
	for _, imp := range schema.Imports {
		if _, ok := parsedFiles[imp.Location]; ok {
			continue
		}
		s, err := parse(filepath.Join(dir, imp.Location))
		if err != nil {
			return nil, err
		}
		schemas = append(schemas, s...)
	}
	return schemas, nil
}

// xsdSchema is the Go representation of an XSD schema.
type xsdSchema struct {
	XMLName      xml.Name
	Ns           string           `xml:"xmlns,attr"`
	Imports      []xsdImport      `xml:"import"`
	Elements     []xsdElement     `xml:"element"`
	ComplexTypes []xsdComplexType `xml:"complexType"`
	SimpleTypes  []xsdSimpleType  `xml:"simpleType"`
}

// ns parses the namespace from a value in the expected format
// http://host/namespace/v1
func (s xsdSchema) ns() string {
	split := strings.Split(s.Ns, "/")
	if len(split) > 2 {
		return split[len(split)-2]
	}
	return ""
}

type xsdImport struct {
	Location string `xml:"schemaLocation,attr"`
}

type xsdElement struct {
	Name        string          `xml:"name,attr"`
	Type        string          `xml:"type,attr"`
	Default     string          `xml:"default,attr"`
	Min         string          `xml:"minOccurs,attr"`
	Max         string          `xml:"maxOccurs,attr"`
	Annotation  string          `xml:"annotation>documentation"`
	ComplexType *xsdComplexType `xml:"complexType"` // inline complex type
	SimpleType  *xsdSimpleType  `xml:"simpleType"`  // inline simple type
}

func (e xsdElement) isList() bool {
	return e.Max == "unbounded"
}

func (e xsdElement) inlineType() bool {
	return e.Type == ""
}

type xsdComplexType struct {
	Name           string             `xml:"name,attr"`
	Abstract       string             `xml:"abstract,attr"`
	Annotation     string             `xml:"annotation>documentation"`
	Sequence       []xsdElement       `xml:"sequence>element"`
	Attributes     []xsdAttribute     `xml:"attribute"`
	ComplexContent *xsdComplexContent `xml:"complexContent"`
	SimpleContent  *xsdSimpleContent  `xml:"simpleContent"`
}

type xsdComplexContent struct {
	Extension   *xsdExtension   `xml:"extension"`
	Restriction *xsdRestriction `xml:"restriction"`
}

type xsdSimpleContent struct {
	Extension   *xsdExtension   `xml:"extension"`
	Restriction *xsdRestriction `xml:"restriction"`
}

type xsdExtension struct {
	Base       string         `xml:"base,attr"`
	Attributes []xsdAttribute `xml:"attribute"`
	Sequence   []xsdElement   `xml:"sequence>element"`
}

type xsdAttribute struct {
	Name       string `xml:"name,attr"`
	Type       string `xml:"type,attr"`
	Use        string `xml:"use,attr"`
	Annotation string `xml:"annotation>documentation"`
}

type xsdSimpleType struct {
	Name        string         `xml:"name,attr"`
	Annotation  string         `xml:"annotation>documentation"`
	Restriction xsdRestriction `xml:"restriction"`
}

type xsdRestriction struct {
	Base        string           `xml:"base,attr"`
	Pattern     xsdPattern       `xml:"pattern"`
	Enumeration []xsdEnumeration `xml:"enumeration"`
}

type xsdPattern struct {
	Value string `xml:"value,attr"`
}

type xsdEnumeration struct {
	Value string `xml:"value,attr"`
}
<commit_msg>#3 handle XSD's with Windows-1252 encoding<commit_after>package main

import (
	"encoding/xml"
	"golang.org/x/text/encoding/charmap"
	"io"
	"os"
	"path/filepath"
	"strings"
)

var (
	parsedFiles map[string]struct{}
)

func parseXSDFile(fname string) ([]xsdSchema, error) {
	schemas := []xsdSchema{}
	parsedFiles = make(map[string]struct{})
	schemas, err := parse(fname)
	if err != nil {
		return nil, err
	}
	return schemas, nil
}

// makeCharsetReader returns special readers as needed for xml encodings, or
// nil.
func makeCharsetReader(charset string, input io.Reader) (io.Reader, error) {
	if charset == "Windows-1252" {
		return charmap.Windows1252.NewDecoder().Reader(input), nil
	}
	return nil, nil
}

func parse(fname string) ([]xsdSchema, error) {
	f, err := os.Open(fname)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	var schema xsdSchema

	d := xml.NewDecoder(f)

	// handle special character sets
	d.CharsetReader = makeCharsetReader

	if err := d.Decode(&schema); err != nil {
		return nil, err
	}

	schemas := []xsdSchema{schema}
	dir, file := filepath.Split(fname)
	parsedFiles[file] = struct{}{}
	for _, imp := range schema.Imports {
		if _, ok := parsedFiles[imp.Location]; ok {
			continue
		}
		s, err := parse(filepath.Join(dir, imp.Location))
		if err != nil {
			return nil, err
		}
		schemas = append(schemas, s...)
	}
	return schemas, nil
}

// xsdSchema is the Go representation of an XSD schema.
type xsdSchema struct {
	XMLName      xml.Name
	Ns           string           `xml:"xmlns,attr"`
	Imports      []xsdImport      `xml:"import"`
	Elements     []xsdElement     `xml:"element"`
	ComplexTypes []xsdComplexType `xml:"complexType"`
	SimpleTypes  []xsdSimpleType  `xml:"simpleType"`
}

// ns parses the namespace from a value in the expected format
// http://host/namespace/v1
func (s xsdSchema) ns() string {
	split := strings.Split(s.Ns, "/")
	if len(split) > 2 {
		return split[len(split)-2]
	}
	return ""
}

type xsdImport struct {
	Location string `xml:"schemaLocation,attr"`
}

type xsdElement struct {
	Name        string          `xml:"name,attr"`
	Type        string          `xml:"type,attr"`
	Default     string          `xml:"default,attr"`
	Min         string          `xml:"minOccurs,attr"`
	Max         string          `xml:"maxOccurs,attr"`
	Annotation  string          `xml:"annotation>documentation"`
	ComplexType *xsdComplexType `xml:"complexType"` // inline complex type
	SimpleType  *xsdSimpleType  `xml:"simpleType"`  // inline simple type
}

func (e xsdElement) isList() bool {
	return e.Max == "unbounded"
}

func (e xsdElement) inlineType() bool {
	return e.Type == ""
}

type xsdComplexType struct {
	Name           string             `xml:"name,attr"`
	Abstract       string             `xml:"abstract,attr"`
	Annotation     string             `xml:"annotation>documentation"`
	Sequence       []xsdElement       `xml:"sequence>element"`
	Attributes     []xsdAttribute     `xml:"attribute"`
	ComplexContent *xsdComplexContent `xml:"complexContent"`
	SimpleContent  *xsdSimpleContent  `xml:"simpleContent"`
}

type xsdComplexContent struct {
	Extension   *xsdExtension   `xml:"extension"`
	Restriction *xsdRestriction `xml:"restriction"`
}

type xsdSimpleContent struct {
	Extension   *xsdExtension   `xml:"extension"`
	Restriction *xsdRestriction `xml:"restriction"`
}

type xsdExtension struct {
	Base       string         `xml:"base,attr"`
	Attributes []xsdAttribute `xml:"attribute"`
	Sequence   []xsdElement   `xml:"sequence>element"`
}

type xsdAttribute struct {
	Name       string `xml:"name,attr"`
	Type       string `xml:"type,attr"`
	Use        string `xml:"use,attr"`
	Annotation string `xml:"annotation>documentation"`
}

type xsdSimpleType struct {
	Name        string         `xml:"name,attr"`
	Annotation  string         `xml:"annotation>documentation"`
	Restriction xsdRestriction `xml:"restriction"`
}

type xsdRestriction struct {
	Base        string           `xml:"base,attr"`
	Pattern     xsdPattern       `xml:"pattern"`
	Enumeration []xsdEnumeration `xml:"enumeration"`
}

type xsdPattern struct {
	Value string `xml:"value,attr"`
}

type xsdEnumeration struct {
	Value string `xml:"value,attr"`
}
<|endoftext|>


<commit_before>// Yam (Yet Another Mux)

package main

import (
	"fmt"
	"net/http"
	"net/url"
	"strings"
)

type handler func(http.ResponseWriter, *http.Request)

func optionsHandler(route *Route) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		methods := []string{}
		for key, _ := range route.handlers {
			methods = append(methods, key)
		}
		w.Header().Add("Allow", strings.Join(methods, ", "))
	})
}

type Yam struct {
	Root *Route
}

func New() *Yam {
	return &Yam{
		Root: &Route{},
	}
}

func (y *Yam) Route(path string) *Route {
	return route(path, y.Root)
}

func route(path string, router *Route) *Route {
	parts := strings.Split(path, "/")[1:]
	routes := router.Routes

	fmt.Println("Start Router:", router.path)
	fmt.Println("Stat Path:", path)
	fullPath := router.path + path

	for i, part := range parts {
		fmt.Println("Part:", part)
		if i == len(parts)-1 {

			for _, route := range routes {
				if route.leaf == part {
					fmt.Println("Route Exists")
					fmt.Println("--------------")
					return route
				}
			}

			route := &Route{leaf: part, path: fullPath}
			fmt.Println("Add:", route.path)
			fmt.Println("Router:", router.path)
			router.Routes = append(router.Routes, route)

			fmt.Println("--------------")

			return route

		} else {
			for _, route := range routes {
				if route.leaf == part {
					fmt.Println("Leaf:", route.leaf)
					router = route
				} else {
					fmt.Println("Router:", router.path)
					route := &Route{leaf: part, path: router.path + path}
					router.Routes = append(router.Routes, route)
					router = route
				}
			}

		}
	}

	return nil
}

func (y *Yam) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	parts := strings.Split(r.URL.Path, "/")[1:]
	fmt.Println(parts)
	routes := y.Root.Routes

	for i, part := range parts {
		fmt.Println(part)
		for _, route := range routes {
			fmt.Println("Leaf:", route.leaf)
			match := false
			// Pattern Match
			if strings.HasPrefix(route.leaf, ":") {
				fmt.Println("Pattern Match")
				match = true
				values := url.Values{}
				values.Add(route.leaf, part)
				r.URL.RawQuery = url.Values(values).Encode() + "&" + r.URL.RawQuery
			} else { // Exact match
				fmt.Println("Exact Match")
				if route.leaf == part {
					match = true
				}
			}

			if match {
				fmt.Println("Leaf ==", part)
				if i < len(parts)-1 {
					routes = route.Routes
					break
				} else {
					fmt.Println("Found: ", route.path)

					handler := route.handlers[r.Method]
					if handler != nil {
						handler.ServeHTTP(w, r)
						return
					}

					fmt.Println("No handler for method")
					w.WriteHeader(http.StatusMethodNotAllowed)
					return

				}
			}
		}
	}

	// If we get here then we have not found a route
	fmt.Println("Not Found")
	w.WriteHeader(http.StatusNotFound)
}

type Route struct {
	leaf   string   // a part of a URL path, /foo/bar - a leaf would be foo and bar
	path   string   // full url path
	Routes []*Route // Routes that live under this route

	handlers map[string]http.Handler
}

func (r *Route) Route(path string) *Route {
	return route(path, r)
}

func (r *Route) Add(method string, handler http.Handler) *Route {
	if r.handlers == nil {
		r.handlers = make(map[string]http.Handler)
	}

	if r.handlers["OPTIONS"] == nil {
		r.handlers["OPTIONS"] = optionsHandler(r)
	}

	r.handlers[method] = handler

	return r
}

func (r *Route) Head(h handler) *Route {
	r.Add("HEAD", http.HandlerFunc(h))

	return r
}

func (r *Route) Get(h handler) *Route {
	r.Add("GET", http.HandlerFunc(h))

	// Implement the HEAD handler by default for all GET requests - HEAD
	// should not return a body so we wrap it in a middleware
	head := func(n http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// Serve the handler
			n.ServeHTTP(w, r)
			// Flush the body so we don't write to the client
			if f, ok := w.(http.Flusher); ok {
				f.Flush()
			}
		})
	}

	// Apply the head middleware to the head handler
	r.Add("HEAD", head(http.HandlerFunc(h)))

	return r
}

func (r *Route) Post(h handler) *Route {
	r.Add("POST", http.HandlerFunc(h))

	return r
}

func (r *Route) Put(h handler) *Route {
	r.Add("PUT", http.HandlerFunc(h))

	return r
}

func (r *Route) Delete(h handler) *Route {
	r.Add("DELETE", http.HandlerFunc(h))

	return r
}

func (r *Route) Patch(h handler) *Route {
	r.Add("PATCH", http.HandlerFunc(h))

	return r
}

func GetRootHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get Root Handler"))
}

func GetFooHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get Foo Handler"))
}

func GetAHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get A Handler"))
}

func GetBHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get B Handler"))
}

func GetCHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get C Handler"))
}

func GetDHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get D Handler"))
}

func main() {
	y := New()

	y.Route("/").Get(GetRootHandler)
	y.Route("/get").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("GET"))
	})
	y.Route("/post").Post(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("POST"))
	})
	y.Route("/put").Put(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("PUT"))
	})
	y.Route("/patch").Patch(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("PATCH"))
	})
	y.Route("/delete").Delete(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("DELETE"))
	})

	a := y.Route("/a").Get(GetAHandler)
	a.Route("/b").Get(GetBHandler)
	a.Route("/b").Put(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("PUT B Handler"))
	})
	c := a.Route("/b/c").Get(GetCHandler)
	c.Route("/d").Get(GetDHandler)
	e := c.Route("/d/e").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("E Handler"))
	})
	e.Route("/f").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("F Handler"))
	})

	// Pattern Matching
	a.Route("/:foo").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("A :foo Handler\n"))
		w.Write([]byte(r.URL.Query().Get(":foo")))
	})

	bar := a.Route("/:foo/:bar").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("/a/:foo/:bar Handler\n"))
		w.Write([]byte(r.URL.Query().Get(":foo")))
		w.Write([]byte("\n"))
		w.Write([]byte(r.URL.Query().Get(":bar")))
	})

	bar.Route("/baz").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Foo", "Bar")
		w.Write([]byte("baz\n"))
		w.Write([]byte(r.URL.Query().Get(":foo")))
		w.Write([]byte("\n"))
		w.Write([]byte(r.URL.Query().Get(":bar")))
	})

	fmt.Printf("%+v\n", y)

	http.ListenAndServe(":5000", y)
}
<commit_msg>TRACE request support<commit_after>// Yam (Yet Another Mux)

package main

import (
	"fmt"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strings"
)

type handler func(http.ResponseWriter, *http.Request)

func optionsHandler(route *Route) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		methods := []string{}
		for key, _ := range route.handlers {
			methods = append(methods, key)
		}
		w.Header().Add("Allow", strings.Join(methods, ", "))
	})
}

type Yam struct {
	Root *Route
}

func New() *Yam {
	return &Yam{
		Root: &Route{},
	}
}

func (y *Yam) Route(path string) *Route {
	return route(path, y.Root)
}

func route(path string, router *Route) *Route {
	parts := strings.Split(path, "/")[1:]
	routes := router.Routes

	fmt.Println("Start Router:", router.path)
	fmt.Println("Stat Path:", path)
	fullPath := router.path + path

	for i, part := range parts {
		fmt.Println("Part:", part)
		if i == len(parts)-1 {

			for _, route := range routes {
				if route.leaf == part {
					fmt.Println("Route Exists")
					fmt.Println("--------------")
					return route
				}
			}

			route := &Route{leaf: part, path: fullPath}
			fmt.Println("Add:", route.path)
			fmt.Println("Router:", router.path)
			router.Routes = append(router.Routes, route)

			fmt.Println("--------------")

			return route

		} else {
			for _, route := range routes {
				if route.leaf == part {
					fmt.Println("Leaf:", route.leaf)
					router = route
				} else {
					fmt.Println("Router:", router.path)
					route := &Route{leaf: part, path: router.path + path}
					router.Routes = append(router.Routes, route)
					router = route
				}
			}

		}
	}

	return nil
}

func (y *Yam) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	parts := strings.Split(r.URL.Path, "/")[1:]
	fmt.Println(parts)
	routes := y.Root.Routes

	for i, part := range parts {
		fmt.Println(part)
		for _, route := range routes {
			fmt.Println("Leaf:", route.leaf)
			match := false
			// Pattern Match
			if strings.HasPrefix(route.leaf, ":") {
				fmt.Println("Pattern Match")
				match = true
				values := url.Values{}
				values.Add(route.leaf, part)
				r.URL.RawQuery = url.Values(values).Encode() + "&" + r.URL.RawQuery
			} else { // Exact match
				fmt.Println("Exact Match")
				if route.leaf == part {
					match = true
				}
			}

			if match {
				fmt.Println("Leaf ==", part)
				if i < len(parts)-1 {
					routes = route.Routes
					break
				} else {
					fmt.Println("Found: ", route.path)

					handler := route.handlers[r.Method]
					if handler != nil {
						handler.ServeHTTP(w, r)
						return
					}

					fmt.Println("No handler for method")
					w.WriteHeader(http.StatusMethodNotAllowed)
					return

				}
			}
		}
	}

	// If we get here then we have not found a route
	fmt.Println("Not Found")
	w.WriteHeader(http.StatusNotFound)
}

type Route struct {
	leaf   string   // a part of a URL path, /foo/bar - a leaf would be foo and bar
	path   string   // full url path
	Routes []*Route // Routes that live under this route

	handlers map[string]http.Handler
}

func (r *Route) Route(path string) *Route {
	return route(path, r)
}

func (r *Route) Add(method string, handler http.Handler) *Route {
	if r.handlers == nil {
		r.handlers = make(map[string]http.Handler)
	}

	if r.handlers["OPTIONS"] == nil {
		r.handlers["OPTIONS"] = optionsHandler(r)
	}

	if r.handlers["TRACE"] == nil {
		r.handlers["TRACE"] = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			dump, _ := httputil.DumpRequest(r, false)
			w.Write(dump)
		})
	}

	r.handlers[method] = handler

	return r
}

func (r *Route) Head(h handler) *Route {
	r.Add("HEAD", http.HandlerFunc(h))

	return r
}

func (r *Route) Get(h handler) *Route {
	r.Add("GET", http.HandlerFunc(h))

	// Implement the HEAD handler by default for all GET requests - HEAD
	// should not return a body so we wrap it in a middleware
	head := func(n http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			// Serve the handler
			n.ServeHTTP(w, r)
			// Flush the body so we don't write to the client
			if f, ok := w.(http.Flusher); ok {
				f.Flush()
			}
		})
	}

	// Apply the head middleware to the head handler
	r.Add("HEAD", head(http.HandlerFunc(h)))

	return r
}

func (r *Route) Post(h handler) *Route {
	r.Add("POST", http.HandlerFunc(h))

	return r
}

func (r *Route) Put(h handler) *Route {
	r.Add("PUT", http.HandlerFunc(h))

	return r
}

func (r *Route) Delete(h handler) *Route {
	r.Add("DELETE", http.HandlerFunc(h))

	return r
}

func (r *Route) Patch(h handler) *Route {
	r.Add("PATCH", http.HandlerFunc(h))

	return r
}

func GetRootHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get Root Handler"))
}

func GetFooHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get Foo Handler"))
}

func GetAHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get A Handler"))
}

func GetBHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get B Handler"))
}

func GetCHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get C Handler"))
}

func GetDHandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("Get D Handler"))
}

func main() {
	y := New()

	y.Route("/").Get(GetRootHandler)
	y.Route("/get").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("GET"))
	})
	y.Route("/post").Post(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("POST"))
	})
	y.Route("/put").Put(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("PUT"))
	})
	y.Route("/patch").Patch(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("PATCH"))
	})
	y.Route("/delete").Delete(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("DELETE"))
	})

	a := y.Route("/a").Get(GetAHandler)
	a.Route("/b").Get(GetBHandler)
	a.Route("/b").Put(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("PUT B Handler"))
	})
	c := a.Route("/b/c").Get(GetCHandler)
	c.Route("/d").Get(GetDHandler)
	e := c.Route("/d/e").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("E Handler"))
	})
	e.Route("/f").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("F Handler"))
	})

	// Pattern Matching
	a.Route("/:foo").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("A :foo Handler\n"))
		w.Write([]byte(r.URL.Query().Get(":foo")))
	})

	bar := a.Route("/:foo/:bar").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("/a/:foo/:bar Handler\n"))
		w.Write([]byte(r.URL.Query().Get(":foo")))
		w.Write([]byte("\n"))
		w.Write([]byte(r.URL.Query().Get(":bar")))
	})

	bar.Route("/baz").Get(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Foo", "Bar")
		w.Write([]byte("baz\n"))
		w.Write([]byte(r.URL.Query().Get(":foo")))
		w.Write([]byte("\n"))
		w.Write([]byte(r.URL.Query().Get(":bar")))
	})

	fmt.Printf("%+v\n", y)

	http.ListenAndServe(":5000", y)
}
<|endoftext|>


<commit_before>// Package zmq provides ZeroMQ bindings for Go.
package zmq

/*

#cgo LDFLAGS: -lzmq

#include <zmq.h>
#include <stdlib.h>
#include <string.h>

static int my_errno() {
	return errno;
}

*/
import "C"

import (
	"errors"
	"sync"
	"unsafe"
)

var (
	// ErrTerminated is returned when a socket's context has been closed.
	ErrTerminated = errors.New("zmq context has been terminated")
	// ErrTimeout is returned when an operation times out or a non-blocking operation cannot run immediately.
	ErrTimeout     = errors.New("zmq timeout")
	ErrInterrupted = errors.New("system call interrupted")
)

type SocketType int

const (
	Req    SocketType = C.ZMQ_REQ
	Rep               = C.ZMQ_REP
	Dealer            = C.ZMQ_DEALER
	Router            = C.ZMQ_ROUTER
	Pub               = C.ZMQ_PUB
	Sub               = C.ZMQ_SUB
	XPub              = C.ZMQ_XPUB
	XSub              = C.ZMQ_XSUB
	Push              = C.ZMQ_PUSH
	Pull              = C.ZMQ_PULL
	Pair              = C.ZMQ_PAIR
)

type DeviceType int

const (
	Queue     DeviceType = C.ZMQ_QUEUE
	Forwarder            = C.ZMQ_FORWARDER
	Streamer             = C.ZMQ_STREAMER
)

/* Context */

// A Context manages multiple Sockets. Contexts are thread-safe.
type Context struct {
	ctx unsafe.Pointer
}

// Creates a new Context with the given number of dedicated IO threads.
func NewContextThreads(nthreads int) (ctx *Context, err error) {
	ptr := C.zmq_init(C.int(nthreads))
	if ptr == nil {
		return nil, zmqerr()
	}
	return &Context{ptr}, nil
}

// Creates a new Context with the default number of IO threads (one).
func NewContext() (*Context, error) {
	return NewContextThreads(1)
}

// Closes the Context. Close will block until all related Sockets are closed, and all pending messages are either
// physically transferred to the network or the socket's linger period expires.
func (c *Context) Close() {
	for {
		r := C.zmq_term(c.ctx)
		if r == -1 {
			if C.my_errno() == C.EINTR {
				continue
			}
			panic(zmqerr())
		}
		break
	}
}

// Creates a new Socket of the specified type.
func (c *Context) Socket(socktype SocketType) (sock *Socket, err error) {
	ptr := C.zmq_socket(c.ctx, C.int(socktype))
	if ptr == nil {
		return nil, zmqerr()
	}
	sock = &Socket{
		ctx:  c,
		sock: ptr,
	}
	sock.SetLinger(0)
	return
}

/* Global context */

var (
	globalCtx  *Context = nil
	globalLock sync.Mutex
)

// Returns the default Context. Note that the context will not be created until
// the first call to DefaultContext.
func DefaultContext() *Context {
	globalLock.Lock()
	defer globalLock.Unlock()
	if globalCtx == nil {
		var err error
		if globalCtx, err = NewContext(); err != nil {
			panic(err)
		}
	}
	return globalCtx
}

// Creates a new socket using the default context (see DefaultContext).
func NewSocket(socktype SocketType) (*Socket, error) {
	return DefaultContext().Socket(socktype)
}

/* Socket */

// A ZeroMQ Socket.
type Socket struct {
	ctx  *Context
	sock unsafe.Pointer
}

// Closes the socket.
func (s *Socket) Close() {
	C.zmq_close(s.sock)
}

// Binds the socket to the specified local endpoint address.
func (s *Socket) Bind(endpoint string) (err error) {
	cstr := C.CString(endpoint)
	defer C.free(unsafe.Pointer(cstr))
	r := C.zmq_bind(s.sock, cstr)
	if r == -1 {
		err = zmqerr()
	}
	return
}

// Connects the socket to the specified remote endpoint.
func (s *Socket) Connect(endpoint string) (err error) {
	cstr := C.CString(endpoint)
	defer C.free(unsafe.Pointer(cstr))
	r := C.zmq_connect(s.sock, cstr)
	if r == -1 {
		err = zmqerr()
	}
	return
}

// Sends a single message part. The `more` flag is used to specify whether this is the last part of the message (false),
// or if there are more parts to follow (true). SendPart is fairly low-level, and usually Send will be the preferred
// method to use.
func (s *Socket) SendPart(part []byte, more bool) (err error) {
	for {
		err = nil
		var msg C.zmq_msg_t
		toMsg(&msg, part)
		flags := C.int(0)
		if more {
			flags = C.ZMQ_SNDMORE
		}
		r := C.zmq_msg_send(&msg, s.sock, flags)
		if r == -1 {
			err = zmqerr()
		}
		C.zmq_msg_close(&msg)
		if err != ErrInterrupted {
			break
		}
	}
	return
}

// Sends a message containing a number of parts.
func (s *Socket) Send(parts [][]byte) (err error) {
	for _, part := range parts[:len(parts)-1] {
		if err = s.SendPart(part, true); err != nil {
			return
		}
	}
	return s.SendPart(parts[len(parts)-1], false)
}

// Receives a single part along with a boolean flag (more) indicating whether more parts of the same message follow
// (true), or this is the last part of the message (false). As with Send/SendPart, this is fairly low-level and Recv
// should generally be used instead.
func (s *Socket) RecvPart() (part []byte, more bool, err error) {
	var msg C.zmq_msg_t
	C.zmq_msg_init(&msg)
	for {
		err = nil
		r := C.zmq_msg_recv(&msg, s.sock, 0)
		if r == -1 {
			err = zmqerr()
		}
		if err != ErrInterrupted {
			break
		}
	}
	if err != nil {
		C.zmq_msg_close(&msg)
		return
	}
	part = fromMsg(&msg)
	// Check for more parts
	more = (s.getInt(C.ZMQ_RCVMORE) != 0)
	return
}

// Receives a multi-part message.
func (s *Socket) Recv() (parts [][]byte, err error) {
	parts = make([][]byte, 0)
	for more := true; more; {
		var part []byte
		if part, more, err = s.RecvPart(); err != nil {
			return
		}
		parts = append(parts, part)
	}
	return
}

// Subscribe sets up a filter for incoming messages on Sub sockets.
func (s *Socket) Subscribe(filter []byte) {
	s.setBinary(C.ZMQ_SUBSCRIBE, filter)
}

// Unsubscribes from a filter on a Sub socket.
func (s *Socket) Unsubscribe(filter []byte) {
	s.setBinary(C.ZMQ_UNSUBSCRIBE, filter)
}

/* Device */

// Creates and runs a ZeroMQ Device. See zmq_device(3) for more details.
func Device(deviceType DeviceType, frontend, backend *Socket) {
	C.zmq_device(C.int(deviceType), frontend.sock, backend.sock)
}

// Version reports 0MQ library version
func Version() (int, int, int) {
	var major, minor, patch C.int
	C.zmq_version(&major, &minor, &patch)

	return int(major), int(minor), int(patch)
}

/* Utilities */

func zmqerr() error {
	eno := C.my_errno()
	switch eno {
	case C.ETERM:
		return ErrTerminated
	case C.EAGAIN:
		return ErrTimeout
	case C.EINTR:
		return ErrInterrupted
	}
	str := C.GoString(C.zmq_strerror(eno))
	return errors.New(str)
}

func toMsg(msg *C.zmq_msg_t, data []byte) {
	C.zmq_msg_init_size(msg, C.size_t(len(data)))
	if len(data) > 0 {
		C.memcpy(C.zmq_msg_data(msg), unsafe.Pointer(&data[0]), C.size_t(len(data)))
	}
}
func fromMsg(msg *C.zmq_msg_t) []byte {
	defer C.zmq_msg_close(msg)
	return C.GoBytes(C.zmq_msg_data(msg), C.int(C.zmq_msg_size(msg)))
}
<commit_msg>Added named return values to Version()<commit_after>// Package zmq provides ZeroMQ bindings for Go.
package zmq

/*

#cgo LDFLAGS: -lzmq

#include <zmq.h>
#include <stdlib.h>
#include <string.h>

static int my_errno() {
	return errno;
}

*/
import "C"

import (
	"errors"
	"sync"
	"unsafe"
)

var (
	// ErrTerminated is returned when a socket's context has been closed.
	ErrTerminated = errors.New("zmq context has been terminated")
	// ErrTimeout is returned when an operation times out or a non-blocking operation cannot run immediately.
	ErrTimeout     = errors.New("zmq timeout")
	ErrInterrupted = errors.New("system call interrupted")
)

type SocketType int

const (
	Req    SocketType = C.ZMQ_REQ
	Rep               = C.ZMQ_REP
	Dealer            = C.ZMQ_DEALER
	Router            = C.ZMQ_ROUTER
	Pub               = C.ZMQ_PUB
	Sub               = C.ZMQ_SUB
	XPub              = C.ZMQ_XPUB
	XSub              = C.ZMQ_XSUB
	Push              = C.ZMQ_PUSH
	Pull              = C.ZMQ_PULL
	Pair              = C.ZMQ_PAIR
)

type DeviceType int

const (
	Queue     DeviceType = C.ZMQ_QUEUE
	Forwarder            = C.ZMQ_FORWARDER
	Streamer             = C.ZMQ_STREAMER
)

/* Context */

// A Context manages multiple Sockets. Contexts are thread-safe.
type Context struct {
	ctx unsafe.Pointer
}

// Creates a new Context with the given number of dedicated IO threads.
func NewContextThreads(nthreads int) (ctx *Context, err error) {
	ptr := C.zmq_init(C.int(nthreads))
	if ptr == nil {
		return nil, zmqerr()
	}
	return &Context{ptr}, nil
}

// Creates a new Context with the default number of IO threads (one).
func NewContext() (*Context, error) {
	return NewContextThreads(1)
}

// Closes the Context. Close will block until all related Sockets are closed, and all pending messages are either
// physically transferred to the network or the socket's linger period expires.
func (c *Context) Close() {
	for {
		r := C.zmq_term(c.ctx)
		if r == -1 {
			if C.my_errno() == C.EINTR {
				continue
			}
			panic(zmqerr())
		}
		break
	}
}

// Creates a new Socket of the specified type.
func (c *Context) Socket(socktype SocketType) (sock *Socket, err error) {
	ptr := C.zmq_socket(c.ctx, C.int(socktype))
	if ptr == nil {
		return nil, zmqerr()
	}
	sock = &Socket{
		ctx:  c,
		sock: ptr,
	}
	sock.SetLinger(0)
	return
}

/* Global context */

var (
	globalCtx  *Context = nil
	globalLock sync.Mutex
)

// Returns the default Context. Note that the context will not be created until
// the first call to DefaultContext.
func DefaultContext() *Context {
	globalLock.Lock()
	defer globalLock.Unlock()
	if globalCtx == nil {
		var err error
		if globalCtx, err = NewContext(); err != nil {
			panic(err)
		}
	}
	return globalCtx
}

// Creates a new socket using the default context (see DefaultContext).
func NewSocket(socktype SocketType) (*Socket, error) {
	return DefaultContext().Socket(socktype)
}

/* Socket */

// A ZeroMQ Socket.
type Socket struct {
	ctx  *Context
	sock unsafe.Pointer
}

// Closes the socket.
func (s *Socket) Close() {
	C.zmq_close(s.sock)
}

// Binds the socket to the specified local endpoint address.
func (s *Socket) Bind(endpoint string) (err error) {
	cstr := C.CString(endpoint)
	defer C.free(unsafe.Pointer(cstr))
	r := C.zmq_bind(s.sock, cstr)
	if r == -1 {
		err = zmqerr()
	}
	return
}

// Connects the socket to the specified remote endpoint.
func (s *Socket) Connect(endpoint string) (err error) {
	cstr := C.CString(endpoint)
	defer C.free(unsafe.Pointer(cstr))
	r := C.zmq_connect(s.sock, cstr)
	if r == -1 {
		err = zmqerr()
	}
	return
}

// Sends a single message part. The `more` flag is used to specify whether this is the last part of the message (false),
// or if there are more parts to follow (true). SendPart is fairly low-level, and usually Send will be the preferred
// method to use.
func (s *Socket) SendPart(part []byte, more bool) (err error) {
	for {
		err = nil
		var msg C.zmq_msg_t
		toMsg(&msg, part)
		flags := C.int(0)
		if more {
			flags = C.ZMQ_SNDMORE
		}
		r := C.zmq_msg_send(&msg, s.sock, flags)
		if r == -1 {
			err = zmqerr()
		}
		C.zmq_msg_close(&msg)
		if err != ErrInterrupted {
			break
		}
	}
	return
}

// Sends a message containing a number of parts.
func (s *Socket) Send(parts [][]byte) (err error) {
	for _, part := range parts[:len(parts)-1] {
		if err = s.SendPart(part, true); err != nil {
			return
		}
	}
	return s.SendPart(parts[len(parts)-1], false)
}

// Receives a single part along with a boolean flag (more) indicating whether more parts of the same message follow
// (true), or this is the last part of the message (false). As with Send/SendPart, this is fairly low-level and Recv
// should generally be used instead.
func (s *Socket) RecvPart() (part []byte, more bool, err error) {
	var msg C.zmq_msg_t
	C.zmq_msg_init(&msg)
	for {
		err = nil
		r := C.zmq_msg_recv(&msg, s.sock, 0)
		if r == -1 {
			err = zmqerr()
		}
		if err != ErrInterrupted {
			break
		}
	}
	if err != nil {
		C.zmq_msg_close(&msg)
		return
	}
	part = fromMsg(&msg)
	// Check for more parts
	more = (s.getInt(C.ZMQ_RCVMORE) != 0)
	return
}

// Receives a multi-part message.
func (s *Socket) Recv() (parts [][]byte, err error) {
	parts = make([][]byte, 0)
	for more := true; more; {
		var part []byte
		if part, more, err = s.RecvPart(); err != nil {
			return
		}
		parts = append(parts, part)
	}
	return
}

// Subscribe sets up a filter for incoming messages on Sub sockets.
func (s *Socket) Subscribe(filter []byte) {
	s.setBinary(C.ZMQ_SUBSCRIBE, filter)
}

// Unsubscribes from a filter on a Sub socket.
func (s *Socket) Unsubscribe(filter []byte) {
	s.setBinary(C.ZMQ_UNSUBSCRIBE, filter)
}

/* Device */

// Creates and runs a ZeroMQ Device. See zmq_device(3) for more details.
func Device(deviceType DeviceType, frontend, backend *Socket) {
	C.zmq_device(C.int(deviceType), frontend.sock, backend.sock)
}

// Version reports 0MQ library version.
func Version() (major, minor, patch int) {
	var ma, mi, pa C.int
	C.zmq_version(&ma, &mi, &pa)
	return int(ma), int(mi), int(pa)
}

/* Utilities */

func zmqerr() error {
	eno := C.my_errno()
	switch eno {
	case C.ETERM:
		return ErrTerminated
	case C.EAGAIN:
		return ErrTimeout
	case C.EINTR:
		return ErrInterrupted
	}
	str := C.GoString(C.zmq_strerror(eno))
	return errors.New(str)
}

func toMsg(msg *C.zmq_msg_t, data []byte) {
	C.zmq_msg_init_size(msg, C.size_t(len(data)))
	if len(data) > 0 {
		C.memcpy(C.zmq_msg_data(msg), unsafe.Pointer(&data[0]), C.size_t(len(data)))
	}
}
func fromMsg(msg *C.zmq_msg_t) []byte {
	defer C.zmq_msg_close(msg)
	return C.GoBytes(C.zmq_msg_data(msg), C.int(C.zmq_msg_size(msg)))
}
<|endoftext|>


<commit_before>/*
	Copyright (c) 2015-2016 Christopher Young
	Distributable under the terms of The "BSD New"" License
	that can be found in the LICENSE file, herein included
	as part of this header.

	datalog.go: Log stratux data as it is received. Bucket data into timestamp time slots.

*/

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"os"
	"reflect"
	"strconv"
	"strings"
	"time"
)

const (
	LOG_TIMESTAMP_RESOLUTION = 250 * time.Millisecond
)

type StratuxTimestamp struct {
	id                   int64
	Time_type_preference int // 0 = stratuxClock, 1 = gpsClock, 2 = gpsClock extrapolated via stratuxClock.
	StratuxClock_value   time.Time
	GPSClock_value       time.Time
	PreferredTime_value  time.Time
}

var dataLogTimestamp StratuxTimestamp // Current timestamp bucket.

/*
	checkTimestamp().
		Verify that our current timestamp is within the LOG_TIMESTAMP_RESOLUTION bucket.
		 Returns false if the timestamp was changed, true if it is still valid.
*/

//FIXME: time -> stratuxClock
func checkTimestamp() bool {
	if time.Since(dataLogTimestamp.StratuxClock_value) >= LOG_TIMESTAMP_RESOLUTION {
		//FIXME: mutex.
		dataLogTimestamp.id = 0
		dataLogTimestamp.Time_type_preference = 0 // stratuxClock.
		dataLogTimestamp.StratuxClock_value = stratuxClock.Time
		dataLogTimestamp.GPSClock_value = time.Time{}
		dataLogTimestamp.PreferredTime_value = stratuxClock.Time

		return false
	}
	return true
}

type SQLiteMarshal struct {
	FieldType string
	Marshal   func(v reflect.Value) string
}

func boolMarshal(v reflect.Value) string {
	b := v.Bool()
	if b {
		return "1"
	}
	return "0"
}

func intMarshal(v reflect.Value) string {
	return strconv.FormatInt(v.Int(), 10)
}

func uintMarshal(v reflect.Value) string {
	return strconv.FormatUint(v.Uint(), 10)
}

func floatMarshal(v reflect.Value) string {
	return strconv.FormatFloat(v.Float(), 'f', 10, 64)
}

func stringMarshal(v reflect.Value) string {
	return v.String()
}

func notsupportedMarshal(v reflect.Value) string {
	return ""
}

func structCanBeMarshalled(v reflect.Value) bool {
	m := v.MethodByName("String")
	if m.IsValid() && !m.IsNil() {
		return true
	}
	return false
}

func structMarshal(v reflect.Value) string {
	if structCanBeMarshalled(v) {
		m := v.MethodByName("String")
		in := make([]reflect.Value, 0)
		ret := m.Call(in)
		if len(ret) > 0 {
			return ret[0].String()
		}
	}
	return ""
}

var sqliteMarshalFunctions = map[string]SQLiteMarshal{
	"bool":         {FieldType: "INTEGER", Marshal: boolMarshal},
	"int":          {FieldType: "INTEGER", Marshal: intMarshal},
	"uint":         {FieldType: "INTEGER", Marshal: uintMarshal},
	"float":        {FieldType: "REAL", Marshal: floatMarshal},
	"string":       {FieldType: "TEXT", Marshal: stringMarshal},
	"struct":       {FieldType: "STRING", Marshal: structMarshal},
	"notsupported": {FieldType: "notsupported", Marshal: notsupportedMarshal},
}

var sqlTypeMap = map[reflect.Kind]string{
	reflect.Bool:          "bool",
	reflect.Int:           "int",
	reflect.Int8:          "int",
	reflect.Int16:         "int",
	reflect.Int32:         "int",
	reflect.Int64:         "int",
	reflect.Uint:          "uint",
	reflect.Uint8:         "uint",
	reflect.Uint16:        "uint",
	reflect.Uint32:        "uint",
	reflect.Uint64:        "uint",
	reflect.Uintptr:       "notsupported",
	reflect.Float32:       "float",
	reflect.Float64:       "float",
	reflect.Complex64:     "notsupported",
	reflect.Complex128:    "notsupported",
	reflect.Array:         "notsupported",
	reflect.Chan:          "notsupported",
	reflect.Func:          "notsupported",
	reflect.Interface:     "notsupported",
	reflect.Map:           "notsupported",
	reflect.Ptr:           "notsupported",
	reflect.Slice:         "notsupported",
	reflect.String:        "string",
	reflect.Struct:        "struct",
	reflect.UnsafePointer: "notsupported",
}

func makeTable(i interface{}, tbl string, db *sql.DB) {
	val := reflect.ValueOf(i)

	fields := make([]string, 0)
	for i := 0; i < val.NumField(); i++ {
		kind := val.Field(i).Kind()
		fieldName := val.Type().Field(i).Name
		sqlTypeAlias := sqlTypeMap[kind]

		// Check that if the field is a struct that it can be marshalled.
		if sqlTypeAlias == "struct" && !structCanBeMarshalled(val.Field(i)) {
			continue
		}
		if sqlTypeAlias == "notsupported" || fieldName == "id" {
			continue
		}
		sqlType := sqliteMarshalFunctions[sqlTypeAlias].FieldType
		s := fieldName + " " + sqlType
		fields = append(fields, s)
	}

	// Add the timestamp_id field to link up with the timestamp table.
	if tbl != "timestamp" {
		fields = append(fields, "timestamp_id INTEGER")
	}

	tblCreate := fmt.Sprintf("CREATE TABLE %s (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, %s)", tbl, strings.Join(fields, ", "))
	_, err := db.Exec(tblCreate)
	fmt.Printf("%s\n", tblCreate)
	if err != nil {
		fmt.Printf("ERROR: %s\n", err.Error())
	}
}

func insertData(i interface{}, tbl string, db *sql.DB) int64 {
	checkTimestamp()
	val := reflect.ValueOf(i)

	keys := make([]string, 0)
	values := make([]string, 0)
	for i := 0; i < val.NumField(); i++ {
		kind := val.Field(i).Kind()
		fieldName := val.Type().Field(i).Name
		sqlTypeAlias := sqlTypeMap[kind]

		if sqlTypeAlias == "notsupported" || fieldName == "id" {
			continue
		}

		v := sqliteMarshalFunctions[sqlTypeAlias].Marshal(val.Field(i))

		keys = append(keys, fieldName)
		values = append(values, v)
	}

	// Add the timestamp_id field to link up with the timestamp table.
	if tbl != "timestamp" {
		keys = append(keys, "timestamp_id")
		values = append(values, strconv.FormatInt(dataLogTimestamp.id, 10))
	}

	tblInsert := fmt.Sprintf("INSERT INTO %s (%s) VALUES(%s)", tbl, strings.Join(keys, ","),
		strings.Join(strings.Split(strings.Repeat("?", len(keys)), ""), ","))

	fmt.Printf("%s\n", tblInsert)
	ifs := make([]interface{}, len(values))
	for i := 0; i < len(values); i++ {
		ifs[i] = values[i]
	}
	res, err := db.Exec(tblInsert, ifs...)
	if err != nil {
		fmt.Printf("ERROR: %s\n", err.Error())
	}
	id, err := res.LastInsertId()
	if err == nil {
		return id
	}

	return 0
}

type DataLogRow struct {
	tbl  string
	data interface{}
}

var dataLogChan chan DataLogRow

func dataLogWriter() {
	dataLogChan := make(chan DataLogRow, 10240)

	// Check if we need to create a new database.
	createDatabase := false

	if _, err := os.Stat(dataLogFile); os.IsNotExist(err) {
		createDatabase = true
		log.Printf("creating new database '%s'.\n", dataLogFile)
	}

	db, err := sql.Open("sqlite3", dataLogFile)
	if err != nil {
		log.Printf("sql.Open(): %s\n", err.Error())
	}
	defer db.Close()

	// Do we need to create the database?
	if createDatabase {
		makeTable(dataLogTimestamp, "timestamp", db)
		makeTable(mySituation, "mySituation", db)
		makeTable(globalStatus, "status", db)
		makeTable(globalSettings, "settings", db)
		makeTable(TrafficInfo{}, "traffic", db)
	}

	for {
		//FIXME: measure latency from here to end of block. Messages may need to be timestamped *before* executing everything here.
		r := <-dataLogChan
		if r.tbl == "mySituation" && isGPSClockValid() {
			// Piggyback a GPS time update from this update.
			if t, ok := r.data.(SituationData); ok {
				dataLogTimestamp.id = 0
				dataLogTimestamp.Time_type_preference = 1 // gpsClock.
				dataLogTimestamp.StratuxClock_value = stratuxClock.Time
				dataLogTimestamp.GPSClock_value = t.GPSTime
				dataLogTimestamp.PreferredTime_value = t.GPSTime
			}
		}

		// Check if our time bucket has expired or has never been entered.
		if !checkTimestamp() || dataLogTimestamp.id == 0 {
			dataLogTimestamp.id = insertData(dataLogTimestamp, "timestamp", db)
		}
		insertData(r.data, r.tbl, db)
	}
}

func logSituation() {
	dataLogChan <- DataLogRow{tbl: "mySituation", data: mySituation}
}

func logStatus() {
	dataLogChan <- DataLogRow{tbl: "status", data: globalStatus}
}

func logSettings() {
	dataLogChan <- DataLogRow{tbl: "settings", data: globalSettings}
}

func logTraffic(ti TrafficInfo) {
	dataLogChan <- DataLogRow{tbl: "traffic", data: ti}
}

func initDataLog() {
	go dataLogWriter()
}
<commit_msg>Typo.<commit_after>/*
	Copyright (c) 2015-2016 Christopher Young
	Distributable under the terms of The "BSD New"" License
	that can be found in the LICENSE file, herein included
	as part of this header.

	datalog.go: Log stratux data as it is received. Bucket data into timestamp time slots.

*/

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"os"
	"reflect"
	"strconv"
	"strings"
	"time"
)

const (
	LOG_TIMESTAMP_RESOLUTION = 250 * time.Millisecond
)

type StratuxTimestamp struct {
	id                   int64
	Time_type_preference int // 0 = stratuxClock, 1 = gpsClock, 2 = gpsClock extrapolated via stratuxClock.
	StratuxClock_value   time.Time
	GPSClock_value       time.Time
	PreferredTime_value  time.Time
}

var dataLogTimestamp StratuxTimestamp // Current timestamp bucket.

/*
	checkTimestamp().
		Verify that our current timestamp is within the LOG_TIMESTAMP_RESOLUTION bucket.
		 Returns false if the timestamp was changed, true if it is still valid.
*/

//FIXME: time -> stratuxClock
func checkTimestamp() bool {
	if time.Since(dataLogTimestamp.StratuxClock_value) >= LOG_TIMESTAMP_RESOLUTION {
		//FIXME: mutex.
		dataLogTimestamp.id = 0
		dataLogTimestamp.Time_type_preference = 0 // stratuxClock.
		dataLogTimestamp.StratuxClock_value = stratuxClock.Time
		dataLogTimestamp.GPSClock_value = time.Time{}
		dataLogTimestamp.PreferredTime_value = stratuxClock.Time

		return false
	}
	return true
}

type SQLiteMarshal struct {
	FieldType string
	Marshal   func(v reflect.Value) string
}

func boolMarshal(v reflect.Value) string {
	b := v.Bool()
	if b {
		return "1"
	}
	return "0"
}

func intMarshal(v reflect.Value) string {
	return strconv.FormatInt(v.Int(), 10)
}

func uintMarshal(v reflect.Value) string {
	return strconv.FormatUint(v.Uint(), 10)
}

func floatMarshal(v reflect.Value) string {
	return strconv.FormatFloat(v.Float(), 'f', 10, 64)
}

func stringMarshal(v reflect.Value) string {
	return v.String()
}

func notsupportedMarshal(v reflect.Value) string {
	return ""
}

func structCanBeMarshalled(v reflect.Value) bool {
	m := v.MethodByName("String")
	if m.IsValid() && !m.IsNil() {
		return true
	}
	return false
}

func structMarshal(v reflect.Value) string {
	if structCanBeMarshalled(v) {
		m := v.MethodByName("String")
		in := make([]reflect.Value, 0)
		ret := m.Call(in)
		if len(ret) > 0 {
			return ret[0].String()
		}
	}
	return ""
}

var sqliteMarshalFunctions = map[string]SQLiteMarshal{
	"bool":         {FieldType: "INTEGER", Marshal: boolMarshal},
	"int":          {FieldType: "INTEGER", Marshal: intMarshal},
	"uint":         {FieldType: "INTEGER", Marshal: uintMarshal},
	"float":        {FieldType: "REAL", Marshal: floatMarshal},
	"string":       {FieldType: "TEXT", Marshal: stringMarshal},
	"struct":       {FieldType: "STRING", Marshal: structMarshal},
	"notsupported": {FieldType: "notsupported", Marshal: notsupportedMarshal},
}

var sqlTypeMap = map[reflect.Kind]string{
	reflect.Bool:          "bool",
	reflect.Int:           "int",
	reflect.Int8:          "int",
	reflect.Int16:         "int",
	reflect.Int32:         "int",
	reflect.Int64:         "int",
	reflect.Uint:          "uint",
	reflect.Uint8:         "uint",
	reflect.Uint16:        "uint",
	reflect.Uint32:        "uint",
	reflect.Uint64:        "uint",
	reflect.Uintptr:       "notsupported",
	reflect.Float32:       "float",
	reflect.Float64:       "float",
	reflect.Complex64:     "notsupported",
	reflect.Complex128:    "notsupported",
	reflect.Array:         "notsupported",
	reflect.Chan:          "notsupported",
	reflect.Func:          "notsupported",
	reflect.Interface:     "notsupported",
	reflect.Map:           "notsupported",
	reflect.Ptr:           "notsupported",
	reflect.Slice:         "notsupported",
	reflect.String:        "string",
	reflect.Struct:        "struct",
	reflect.UnsafePointer: "notsupported",
}

func makeTable(i interface{}, tbl string, db *sql.DB) {
	val := reflect.ValueOf(i)

	fields := make([]string, 0)
	for i := 0; i < val.NumField(); i++ {
		kind := val.Field(i).Kind()
		fieldName := val.Type().Field(i).Name
		sqlTypeAlias := sqlTypeMap[kind]

		// Check that if the field is a struct that it can be marshalled.
		if sqlTypeAlias == "struct" && !structCanBeMarshalled(val.Field(i)) {
			continue
		}
		if sqlTypeAlias == "notsupported" || fieldName == "id" {
			continue
		}
		sqlType := sqliteMarshalFunctions[sqlTypeAlias].FieldType
		s := fieldName + " " + sqlType
		fields = append(fields, s)
	}

	// Add the timestamp_id field to link up with the timestamp table.
	if tbl != "timestamp" {
		fields = append(fields, "timestamp_id INTEGER")
	}

	tblCreate := fmt.Sprintf("CREATE TABLE %s (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, %s)", tbl, strings.Join(fields, ", "))
	_, err := db.Exec(tblCreate)
	fmt.Printf("%s\n", tblCreate)
	if err != nil {
		fmt.Printf("ERROR: %s\n", err.Error())
	}
}

func insertData(i interface{}, tbl string, db *sql.DB) int64 {
	checkTimestamp()
	val := reflect.ValueOf(i)

	keys := make([]string, 0)
	values := make([]string, 0)
	for i := 0; i < val.NumField(); i++ {
		kind := val.Field(i).Kind()
		fieldName := val.Type().Field(i).Name
		sqlTypeAlias := sqlTypeMap[kind]

		if sqlTypeAlias == "notsupported" || fieldName == "id" {
			continue
		}

		v := sqliteMarshalFunctions[sqlTypeAlias].Marshal(val.Field(i))

		keys = append(keys, fieldName)
		values = append(values, v)
	}

	// Add the timestamp_id field to link up with the timestamp table.
	if tbl != "timestamp" {
		keys = append(keys, "timestamp_id")
		values = append(values, strconv.FormatInt(dataLogTimestamp.id, 10))
	}

	tblInsert := fmt.Sprintf("INSERT INTO %s (%s) VALUES(%s)", tbl, strings.Join(keys, ","),
		strings.Join(strings.Split(strings.Repeat("?", len(keys)), ""), ","))

	fmt.Printf("%s\n", tblInsert)
	ifs := make([]interface{}, len(values))
	for i := 0; i < len(values); i++ {
		ifs[i] = values[i]
	}
	res, err := db.Exec(tblInsert, ifs...)
	if err != nil {
		fmt.Printf("ERROR: %s\n", err.Error())
	}
	id, err := res.LastInsertId()
	if err == nil {
		return id
	}

	return 0
}

type DataLogRow struct {
	tbl  string
	data interface{}
}

var dataLogChan chan DataLogRow

func dataLogWriter() {
	dataLogChan = make(chan DataLogRow, 10240)

	// Check if we need to create a new database.
	createDatabase := false

	if _, err := os.Stat(dataLogFile); os.IsNotExist(err) {
		createDatabase = true
		log.Printf("creating new database '%s'.\n", dataLogFile)
	}

	db, err := sql.Open("sqlite3", dataLogFile)
	if err != nil {
		log.Printf("sql.Open(): %s\n", err.Error())
	}
	defer db.Close()

	// Do we need to create the database?
	if createDatabase {
		makeTable(dataLogTimestamp, "timestamp", db)
		makeTable(mySituation, "mySituation", db)
		makeTable(globalStatus, "status", db)
		makeTable(globalSettings, "settings", db)
		makeTable(TrafficInfo{}, "traffic", db)
	}

	for {
		//FIXME: measure latency from here to end of block. Messages may need to be timestamped *before* executing everything here.
		r := <-dataLogChan
		if r.tbl == "mySituation" && isGPSClockValid() {
			// Piggyback a GPS time update from this update.
			if t, ok := r.data.(SituationData); ok {
				dataLogTimestamp.id = 0
				dataLogTimestamp.Time_type_preference = 1 // gpsClock.
				dataLogTimestamp.StratuxClock_value = stratuxClock.Time
				dataLogTimestamp.GPSClock_value = t.GPSTime
				dataLogTimestamp.PreferredTime_value = t.GPSTime
			}
		}

		// Check if our time bucket has expired or has never been entered.
		if !checkTimestamp() || dataLogTimestamp.id == 0 {
			dataLogTimestamp.id = insertData(dataLogTimestamp, "timestamp", db)
		}
		insertData(r.data, r.tbl, db)
	}
}

func logSituation() {
	dataLogChan <- DataLogRow{tbl: "mySituation", data: mySituation}
}

func logStatus() {
	dataLogChan <- DataLogRow{tbl: "status", data: globalStatus}
}

func logSettings() {
	dataLogChan <- DataLogRow{tbl: "settings", data: globalSettings}
}

func logTraffic(ti TrafficInfo) {
	dataLogChan <- DataLogRow{tbl: "traffic", data: ti}
}

func initDataLog() {
	go dataLogWriter()
}
<|endoftext|>


<commit_before>package client

import (
	"sourcegraph.com/sourcegraph/api_router"
	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

// UnitsService communicates with the source unit-related endpoints in
// the Sourcegraph API.
type UnitsService interface {
	// Get fetches a unit.
	Get(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error)

	// List units.
	List(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error)
}

// UnitSpec specifies a source unit.
type UnitSpec struct {
	Repo     string
	CommitID string
	UnitType string
	Unit     string
}

func SpecFromUnit(u *unit.RepoSourceUnit) *UnitSpec {
	return &UnitSpec{
		Repo:     string(u.Repo),
		CommitID: u.CommitID,
		UnitType: u.UnitType,
		Unit:     u.Unit,
	}
}

func (s *UnitSpec) RouteVars() map[string]string {
	m := map[string]string{"RepoURI": s.Repo, "UnitType": s.UnitType, "Unit": s.Unit}
	if s.CommitID != "" {
		m["Rev"] = s.CommitID
	}
	return m
}

// unitsService implements UnitsService.
type unitsService struct {
	client *Client
}

var _ UnitsService = &unitsService{}

// UnitListOptions specifies options for UnitsService.List.
type UnitListOptions struct {
	// Filters
	RepositoryURI string `url:",omitempty"`
	CommitID      string `url:",omitempty"`
	UnitType      string `url:",omitempty"`
	Unit          string `url:",omitempty"`

	// Paging
	ListOptions
}

func (s *unitsService) Get(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error) {
	url, err := s.client.url(api_router.Unit, spec.RouteVars(), nil)
	if err != nil {
		return nil, nil, err
	}

	req, err := s.client.NewRequest("GET", url.String(), nil)
	if err != nil {
		return nil, nil, err
	}

	var u unit.RepoSourceUnit
	resp, err := s.client.Do(req, &u)
	if err != nil {
		return nil, resp, err
	}

	return &u, resp, nil
}

func (s *unitsService) List(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error) {
	url, err := s.client.url(api_router.Units, nil, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := s.client.NewRequest("GET", url.String(), nil)
	if err != nil {
		return nil, nil, err
	}

	var units []*unit.RepoSourceUnit
	resp, err := s.client.Do(req, &units)
	if err != nil {
		return nil, resp, err
	}

	return units, resp, nil
}

type MockUnitsService struct {
	List_ func(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error)
	Get_  func(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error)
}

var _ UnitsService = MockUnitsService{}

func (s MockUnitsService) List(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error) {
	if s.List_ == nil {
		return nil, &HTTPResponse{}, nil
	}
	return s.List_(opt)
}

func (s MockUnitsService) Get(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error) {
	if s.Get_ == nil {
		return nil, &HTTPResponse{}, nil
	}
	return s.Get_(spec)
}
<commit_msg>source unit page<commit_after>package client

import (
	"sourcegraph.com/sourcegraph/api_router"
	"sourcegraph.com/sourcegraph/srcgraph/unit"
)

// UnitsService communicates with the source unit-related endpoints in
// the Sourcegraph API.
type UnitsService interface {
	// Get fetches a unit.
	Get(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error)

	// List units.
	List(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error)
}

// UnitSpec specifies a source unit.
type UnitSpec struct {
	Repo     string
	CommitID string
	UnitType string
	Unit     string
}

func SpecFromUnit(u *unit.RepoSourceUnit) *UnitSpec {
	return &UnitSpec{
		Repo:     string(u.Repo),
		CommitID: u.CommitID,
		UnitType: u.UnitType,
		Unit:     u.Unit,
	}
}

func UnitSpecFromRouteVars(vars map[string]string) *UnitSpec {
	return &UnitSpec{
		Repo:     vars["RepoURI"],
		CommitID: vars["Rev"],
		UnitType: vars["UnitType"],
		Unit:     vars["Unit"],
	}
}

func (s *UnitSpec) RouteVars() map[string]string {
	m := map[string]string{"RepoURI": s.Repo, "UnitType": s.UnitType, "Unit": s.Unit}
	if s.CommitID != "" {
		m["Rev"] = s.CommitID
	}
	return m
}

// unitsService implements UnitsService.
type unitsService struct {
	client *Client
}

var _ UnitsService = &unitsService{}

// UnitListOptions specifies options for UnitsService.List.
type UnitListOptions struct {
	// Filters
	RepositoryURI string `url:",omitempty"`
	CommitID      string `url:",omitempty"`
	UnitType      string `url:",omitempty"`
	Unit          string `url:",omitempty"`

	// Paging
	ListOptions
}

func (s *unitsService) Get(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error) {
	url, err := s.client.url(api_router.Unit, spec.RouteVars(), nil)
	if err != nil {
		return nil, nil, err
	}

	req, err := s.client.NewRequest("GET", url.String(), nil)
	if err != nil {
		return nil, nil, err
	}

	var u unit.RepoSourceUnit
	resp, err := s.client.Do(req, &u)
	if err != nil {
		return nil, resp, err
	}

	return &u, resp, nil
}

func (s *unitsService) List(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error) {
	url, err := s.client.url(api_router.Units, nil, opt)
	if err != nil {
		return nil, nil, err
	}

	req, err := s.client.NewRequest("GET", url.String(), nil)
	if err != nil {
		return nil, nil, err
	}

	var units []*unit.RepoSourceUnit
	resp, err := s.client.Do(req, &units)
	if err != nil {
		return nil, resp, err
	}

	return units, resp, nil
}

type MockUnitsService struct {
	List_ func(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error)
	Get_  func(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error)
}

var _ UnitsService = MockUnitsService{}

func (s MockUnitsService) List(opt *UnitListOptions) ([]*unit.RepoSourceUnit, Response, error) {
	if s.List_ == nil {
		return nil, &HTTPResponse{}, nil
	}
	return s.List_(opt)
}

func (s MockUnitsService) Get(spec *UnitSpec) (*unit.RepoSourceUnit, Response, error) {
	if s.Get_ == nil {
		return nil, &HTTPResponse{}, nil
	}
	return s.Get_(spec)
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"encoding/json"
	"os"
	"strconv"

	"github.com/fatih/color"
)

// User ...
type User struct {
	ID       int    `json:"id"`
	Username string `json:"username"`
	Email    string `json:"email"`
	GroupID  int    `json:"group_id"`
	IsAdmin  bool   `json:"admin"`
}

// ListUsers ...
func (m *Manager) ListUsers(token string) (users []User, err error) {
	body, _, err := m.doRequest("/api/users/", "GET", []byte(""), token, "")
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal([]byte(body), &users)
	if err != nil {
		return nil, err
	}
	return users, err
}

// GetUser ...
func (m *Manager) GetUser(token string, userid string) (user User, err error) {
	res, _, err := m.doRequest("/api/users/"+userid, "GET", nil, token, "application/yaml")
	if err != nil {
		return user, err
	}
	err = json.Unmarshal([]byte(res), &user)
	if err != nil {
		return user, err
	}
	return user, nil
}

// CreateUser ...
func (m *Manager) CreateUser(token string, name string, email string, user string, password string) error {
	c, err := m.createClient(token, name)
	if err != nil {
		color.Red(err.Error() + ": Group " + name + " already exists")
		os.Exit(1)
	}

	payload := []byte(`{"group_id": ` + c + `, "username": "` + user + `", "email": "` + email + `", "password": "` + password + `"}`)
	_, _, err = m.doRequest("/api/users/", "POST", payload, token, "")
	if err != nil {
		return err
	}
	color.Green("SUCCESS: User " + user + " created")
	return nil
}

// ChangePassword ...
func (m *Manager) ChangePassword(token string, userid int, username string, usergroup int, oldpassword string, newpassword string) error {
	payload := []byte(`{"id":` + strconv.Itoa(userid) + `, "username": "` + username + `", "group_id": ` + strconv.Itoa(usergroup) + `, "password": "` + newpassword + `", "oldpassword": "` + oldpassword + `"}`)
	_, _, err := m.doRequest("/api/users/"+strconv.Itoa(userid), "PUT", payload, token, "application/yaml")
	if err != nil {
		return err
	}
	return nil
}

// ChangePasswordByAdmin ...
func (m *Manager) ChangePasswordByAdmin(token string, userid int, username string, usergroup int, newpassword string) error {
	payload := []byte(`{"id":` + strconv.Itoa(userid) + `, "username": "` + username + `", "group_id": ` + strconv.Itoa(usergroup) + `, "password": "` + newpassword + `"}`)
	_, _, err := m.doRequest("/api/users/"+string(userid), "PUT", payload, token, "application/yaml")
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>Do not create a group when creating an user<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"encoding/json"
	"strconv"

	"github.com/fatih/color"
)

// User ...
type User struct {
	ID       int    `json:"id"`
	Username string `json:"username"`
	Email    string `json:"email"`
	GroupID  int    `json:"group_id"`
	IsAdmin  bool   `json:"admin"`
}

// ListUsers ...
func (m *Manager) ListUsers(token string) (users []User, err error) {
	body, _, err := m.doRequest("/api/users/", "GET", []byte(""), token, "")
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal([]byte(body), &users)
	if err != nil {
		return nil, err
	}
	return users, err
}

// GetUser ...
func (m *Manager) GetUser(token string, userid string) (user User, err error) {
	res, _, err := m.doRequest("/api/users/"+userid, "GET", nil, token, "application/yaml")
	if err != nil {
		return user, err
	}
	err = json.Unmarshal([]byte(res), &user)
	if err != nil {
		return user, err
	}
	return user, nil
}

// CreateUser ...
func (m *Manager) CreateUser(token string, name string, email string, user string, password string) error {
	payload := []byte(`{"group_id": 0, "username": "` + user + `", "email": "` + email + `", "password": "` + password + `"}`)
	_, _, err := m.doRequest("/api/users/", "POST", payload, token, "")
	if err != nil {
		return err
	}
	color.Green("SUCCESS: User " + user + " created")
	return nil
}

// ChangePassword ...
func (m *Manager) ChangePassword(token string, userid int, username string, usergroup int, oldpassword string, newpassword string) error {
	payload := []byte(`{"id":` + strconv.Itoa(userid) + `, "username": "` + username + `", "group_id": ` + strconv.Itoa(usergroup) + `, "password": "` + newpassword + `", "oldpassword": "` + oldpassword + `"}`)
	_, _, err := m.doRequest("/api/users/"+strconv.Itoa(userid), "PUT", payload, token, "application/yaml")
	if err != nil {
		return err
	}
	return nil
}

// ChangePasswordByAdmin ...
func (m *Manager) ChangePasswordByAdmin(token string, userid int, username string, usergroup int, newpassword string) error {
	payload := []byte(`{"id":` + strconv.Itoa(userid) + `, "username": "` + username + `", "group_id": ` + strconv.Itoa(usergroup) + `, "password": "` + newpassword + `"}`)
	_, _, err := m.doRequest("/api/users/"+string(userid), "PUT", payload, token, "application/yaml")
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package openbaton

type AutoScalePolicy struct {
	ID                 string          `json:"id"`
	Version            int             `json:"version"`
	Name               string          `json:"name"`
	Threshold          float64         `json:"threshold"`
	ComparisonOperator string          `json:"comparisonOperator"`
	Period             int             `json:"period"`
	Cooldown           int             `json:"cooldown"`
	Mode               ScalingMode     `json:"mode"`
	Type               ScalingType     `json:"type"`
	Alarms             []*ScalingAlarm `json:"alarms"`
	Actions            []ScalingAction `json:"actions"`
}

type ConnectionPoint struct {
	ID      string `json:"id"`
	Version int    `json:"version"`
	Type    string `json:"type"`
}

// ConstituentVNF as described in ETSI GS NFV-MAN 001 V1.1.1 (2014-12)
type ConstituentVNF struct {
	ID                    string          `json:"id"`
	VnfReference          string          `json:"vnf_reference"`
	VnfFlavourIDReference string          `json:"vnf_flavour_id_reference"`
	RedundancyModel       RedundancyModel `json:"redundancy_modelid"`
	Affinity              string          `json:"affinity"`
	Capability            string          `json:"capability"`
	NumberOfInstances     int             `json:"number_of_instancesid"`
	Version               int             `json:"version"`
}

type Event string

const (
	EventGranted  Event = "GRANTED"
	EventAllocate Event = "ALLOCATE"
	EventScale    Event = "SCALE"
	EventRelease  Event = "RELEASE"
	EventError    Event = "ERROR"

	EventInstantiate     Event = "INSTANTIATE"
	EventTerminate       Event = "TERMINATE"
	EventConfigure       Event = "CONFIGURE"
	EventStart           Event = "START"
	EventStop            Event = "STOP"
	EventHeal            Event = "HEAL"
	EventScaleOut        Event = "SCALE_OUT"
	EventScaleIn         Event = "SCALE_IN"
	EventScaleUp         Event = "SCALE_UP"
	EventScaleDown       Event = "SCALE_DOWN"
	EventUpdate          Event = "UPDATE"
	EventUpdateRollback  Event = "UPDATE_ROLLBACK"
	EventUpgrade         Event = "UPGRADE"
	EventUpgradeRollback Event = "UPGRADE_ROLLBACK"
	EventReset           Event = "RESET"
)

type HighAvailability struct {
	ID               string          `json:"id"`
	Version          int             `json:"version"`
	ResiliencyLevel  ResiliencyLevel `json:"resiliencyLevel"`
	GeoRedundancy    bool            `json:"geoRedundancy"`
	RedundancyScheme string          `json:"redundancyScheme"`
}

type Ip struct {
	ID      string `json:"id"`
	Version int    `json:"version"`
	NetName string `json:"netname"`
	Ip      string `json:"ip"`
}

// A LifecycleEvent as specified in ETSI GS NFV-MAN 001 V1.1.1 (2014-12)
type LifecycleEvent struct {
	ID              string   `json:"id"`
	Version         int      `json:"version"`
	Event           Event    `json:"event"`
	LifecycleEvents []string `json:"lifecycle_events"`
}

type NetworkServiceDeploymentFlavour struct {
	vendor string
	version string
	number_of_endpoints int
	parent_ns string
	vnffgr_reference []*VNFForwardingGraphRecord
	descriptor_reference string
	vim_id string
	allocated_capacity []string
	status LinkStatus
	notification []string
	lifecycle_event_history []*LifecycleEvent
	audit_log []string
	connection []string
}

type RedundancyModel string

const (
	RedundancyActive  RedundancyModel = "ACTIVE"
	RedundancyStandby RedundancyModel = "STANDBY"
)

type ResiliencyLevel string

const (
	ResiliencyActiveStandbyStateless ResiliencyLevel = "ACTIVE_STANDBY_STATELESS"
	ResiliencyActiveStandbyStateful  ResiliencyLevel = "ACTIVE_STANDBY_STATEFUL"
)

type ScalingAction struct {
	ID      string            `json:"id"`
	Version int               `json:"version"`
	Type    ScalingActionType `json:"type"`
	Value   string            `json:"value"`
	Target  string            `json:"target"`
}

type ScalingActionType string

const (
	ScaleOut          ScalingActionType = "SCALE_OUT"
	ScaleOutTo        ScalingActionType = "SCALE_OUT_TO"
	ScaleOutToFlavour ScalingActionType = "SCALE_OUT_TO_FLAVOUR"
	ScaleIn           ScalingActionType = "SCALE_IN"
	ScaleInTo         ScalingActionType = "SCALE_IN_TO"
	ScaleInToFlavour  ScalingActionType = "SCALE_IN_TO_FLAVOUR"
)

type ScalingAlarm struct {
	ID                 string  `json:"id"`
	Version            int     `json:"version"`
	Metric             string  `json:"metric"`
	Statistic          string  `json:"statistic"`
	ComparisonOperator string  `json:"comparisonOperator"`
	Threshold          float64 `json:"threshold"`
	Weight             float64 `json:"weight"`
}

type ScalingMode string

const (
	ScaleModeReactive   ScalingMode = "REACTIVE"
	ScaleModeProactive  ScalingMode = "PROACTIVE"
	ScaleModePredictive ScalingMode = "PREDICTIVE"
)

type ScalingType string

const (
	ScaleTypeSingle   ScalingType = "SINGLE"
	ScaleTypeVoted    ScalingType = "VOTED"
	ScaleTypeWeighted ScalingType = "WEIGHTED"
)

type Security struct {
	ID      string `json:"id"`
	Version int    `json:"version"`
}

// VirtualLink (abstract) based on ETSI GS NFV-MAN 001 V1.1.1 (2014-12)
// The VLD describes the basic topology of the connectivity (e.g. E-LAN, E-Line, E-Tree) between one
// or more VNFs connected to this VL and other required parameters (e.g. bandwidth and QoS class).
// The VLD connection parameters are expected to have similar attributes to those used on the ports
// on VNFs in ETSI GS NFV-SWA 001 [i.8]. Therefore a set of VLs in a Network Service can be mapped
// to a Network Connectivity Topology (NCT) as defined in ETSI GS NFV-SWA 001 [i.8].
type VirtualLink struct {
	ID               string   `json:"id"`
	HbVersion        int      `json:"hb_version"`
	ExtID            string   `json:"extId"`
	RootRequirement  string   `json:"root_requirement"`
	LeafRequirement  string   `json:"leaf_requirement"`
	Qos              []string `json:"qos"`
	TestAccess       []string `json:"test_access"`
	ConnectivityType []string `json:"connectivity_type"`
	Name             string   `json:"name"`
}
<commit_msg>Added NetworkServiceDeploymentFlavour<commit_after>package openbaton

type AutoScalePolicy struct {
	ID                 string          `json:"id"`
	Version            int             `json:"version"`
	Name               string          `json:"name"`
	Threshold          float64         `json:"threshold"`
	ComparisonOperator string          `json:"comparisonOperator"`
	Period             int             `json:"period"`
	Cooldown           int             `json:"cooldown"`
	Mode               ScalingMode     `json:"mode"`
	Type               ScalingType     `json:"type"`
	Alarms             []*ScalingAlarm `json:"alarms"`
	Actions            []ScalingAction `json:"actions"`
}

type ConnectionPoint struct {
	ID      string `json:"id"`
	Version int    `json:"version"`
	Type    string `json:"type"`
}

// ConstituentVNF as described in ETSI GS NFV-MAN 001 V1.1.1 (2014-12)
type ConstituentVNF struct {
	ID                    string          `json:"id"`
	VnfReference          string          `json:"vnf_reference"`
	VnfFlavourIDReference string          `json:"vnf_flavour_id_reference"`
	RedundancyModel       RedundancyModel `json:"redundancy_modelid"`
	Affinity              string          `json:"affinity"`
	Capability            string          `json:"capability"`
	NumberOfInstances     int             `json:"number_of_instancesid"`
	Version               int             `json:"version"`
}

type Event string

const (
	EventGranted  Event = "GRANTED"
	EventAllocate Event = "ALLOCATE"
	EventScale    Event = "SCALE"
	EventRelease  Event = "RELEASE"
	EventError    Event = "ERROR"

	EventInstantiate     Event = "INSTANTIATE"
	EventTerminate       Event = "TERMINATE"
	EventConfigure       Event = "CONFIGURE"
	EventStart           Event = "START"
	EventStop            Event = "STOP"
	EventHeal            Event = "HEAL"
	EventScaleOut        Event = "SCALE_OUT"
	EventScaleIn         Event = "SCALE_IN"
	EventScaleUp         Event = "SCALE_UP"
	EventScaleDown       Event = "SCALE_DOWN"
	EventUpdate          Event = "UPDATE"
	EventUpdateRollback  Event = "UPDATE_ROLLBACK"
	EventUpgrade         Event = "UPGRADE"
	EventUpgradeRollback Event = "UPGRADE_ROLLBACK"
	EventReset           Event = "RESET"
)

type HighAvailability struct {
	ID               string          `json:"id"`
	Version          int             `json:"version"`
	ResiliencyLevel  ResiliencyLevel `json:"resiliencyLevel"`
	GeoRedundancy    bool            `json:"geoRedundancy"`
	RedundancyScheme string          `json:"redundancyScheme"`
}

type Ip struct {
	ID      string `json:"id"`
	Version int    `json:"version"`
	NetName string `json:"netname"`
	Ip      string `json:"ip"`
}

// LifecycleEvent as specified in ETSI GS NFV-MAN 001 V1.1.1 (2014-12)
type LifecycleEvent struct {
	ID              string   `json:"id"`
	Version         int      `json:"version"`
	Event           Event    `json:"event"`
	LifecycleEvents []string `json:"lifecycle_events"`
}

// NetworkServiceDeploymentFlavour as specified in ETSI GS NFV-MAN 001 V1.1.1 (2014-12)
type NetworkServiceDeploymentFlavour struct {
	Vendor string `json:"vendor"`
	Version string `json:"version"`
	NumberOfEndpoints int `json:"number_of_endpoints"`
	ParentNs string `json:"parent_ns"`
	VNFFGRReference []*VNFForwardingGraphRecord `json:"vnffgr_reference"`
	DescriptorReference string `json:"descriptor_reference"`
	VimID string `json:"vim_id"`
	AllocatedCapacity []string `json:"allocated_capacity"`
	Status LinkStatus `json:"status"`
	Notification []string `json:"notification"`
	LifecycleEventHistory []*LifecycleEvent `json:"lifecycle_event_history"`
	AuditLog []string `json:"audit_log"`
	Connection []string `json:"connection"`
}

type RedundancyModel string

const (
	RedundancyActive  RedundancyModel = "ACTIVE"
	RedundancyStandby RedundancyModel = "STANDBY"
)

type ResiliencyLevel string

const (
	ResiliencyActiveStandbyStateless ResiliencyLevel = "ACTIVE_STANDBY_STATELESS"
	ResiliencyActiveStandbyStateful  ResiliencyLevel = "ACTIVE_STANDBY_STATEFUL"
)

type ScalingAction struct {
	ID      string            `json:"id"`
	Version int               `json:"version"`
	Type    ScalingActionType `json:"type"`
	Value   string            `json:"value"`
	Target  string            `json:"target"`
}

type ScalingActionType string

const (
	ScaleOut          ScalingActionType = "SCALE_OUT"
	ScaleOutTo        ScalingActionType = "SCALE_OUT_TO"
	ScaleOutToFlavour ScalingActionType = "SCALE_OUT_TO_FLAVOUR"
	ScaleIn           ScalingActionType = "SCALE_IN"
	ScaleInTo         ScalingActionType = "SCALE_IN_TO"
	ScaleInToFlavour  ScalingActionType = "SCALE_IN_TO_FLAVOUR"
)

type ScalingAlarm struct {
	ID                 string  `json:"id"`
	Version            int     `json:"version"`
	Metric             string  `json:"metric"`
	Statistic          string  `json:"statistic"`
	ComparisonOperator string  `json:"comparisonOperator"`
	Threshold          float64 `json:"threshold"`
	Weight             float64 `json:"weight"`
}

type ScalingMode string

const (
	ScaleModeReactive   ScalingMode = "REACTIVE"
	ScaleModeProactive  ScalingMode = "PROACTIVE"
	ScaleModePredictive ScalingMode = "PREDICTIVE"
)

type ScalingType string

const (
	ScaleTypeSingle   ScalingType = "SINGLE"
	ScaleTypeVoted    ScalingType = "VOTED"
	ScaleTypeWeighted ScalingType = "WEIGHTED"
)

type Security struct {
	ID      string `json:"id"`
	Version int    `json:"version"`
}

// VirtualLink (abstract) based on ETSI GS NFV-MAN 001 V1.1.1 (2014-12)
// The VLD describes the basic topology of the connectivity (e.g. E-LAN, E-Line, E-Tree) between one
// or more VNFs connected to this VL and other required parameters (e.g. bandwidth and QoS class).
// The VLD connection parameters are expected to have similar attributes to those used on the ports
// on VNFs in ETSI GS NFV-SWA 001 [i.8]. Therefore a set of VLs in a Network Service can be mapped
// to a Network Connectivity Topology (NCT) as defined in ETSI GS NFV-SWA 001 [i.8].
type VirtualLink struct {
	ID               string   `json:"id"`
	HbVersion        int      `json:"hb_version"`
	ExtID            string   `json:"extId"`
	RootRequirement  string   `json:"root_requirement"`
	LeafRequirement  string   `json:"leaf_requirement"`
	Qos              []string `json:"qos"`
	TestAccess       []string `json:"test_access"`
	ConnectivityType []string `json:"connectivity_type"`
	Name             string   `json:"name"`
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"

	"github.com/42wim/matterbridge/bridge/config"
	"github.com/42wim/matterbridge/gateway"
	"github.com/42wim/matterbridge/gateway/bridgemap"
	"github.com/google/gops/agent"
	prefixed "github.com/matterbridge/logrus-prefixed-formatter"
	"github.com/sirupsen/logrus"
)

var (
	version = "1.22.3"
	githash string

	flagConfig  = flag.String("conf", "matterbridge.toml", "config file")
	flagDebug   = flag.Bool("debug", false, "enable debug")
	flagVersion = flag.Bool("version", false, "show version")
	flagGops    = flag.Bool("gops", false, "enable gops agent")
)

func main() {
	flag.Parse()
	if *flagVersion {
		fmt.Printf("version: %s %s\n", version, githash)
		return
	}

	rootLogger := setupLogger()
	logger := rootLogger.WithFields(logrus.Fields{"prefix": "main"})

	if *flagGops {
		if err := agent.Listen(agent.Options{}); err != nil {
			logger.Errorf("Failed to start gops agent: %#v", err)
		} else {
			defer agent.Close()
		}
	}

	logger.Printf("Running version %s %s", version, githash)
	if strings.Contains(version, "-dev") {
		logger.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.")
	}

	cfg := config.NewConfig(rootLogger, *flagConfig)
	cfg.BridgeValues().General.Debug = *flagDebug

	// if logging to a file, ensure it is closed when the program terminates
	// nolint:errcheck
	defer func() {
		if f, ok := rootLogger.Out.(*os.File); ok {
			f.Sync()
			f.Close()
		}
	}()

	r, err := gateway.NewRouter(rootLogger, cfg, bridgemap.FullMap)
	if err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	if err = r.Start(); err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	logger.Printf("Gateway(s) started succesfully. Now relaying messages")
	select {}
}

func setupLogger() *logrus.Logger {
	logger := &logrus.Logger{
		Out: os.Stdout,
		Formatter: &prefixed.TextFormatter{
			PrefixPadding: 13,
			DisableColors: true,
		},
		Level: logrus.InfoLevel,
	}
	if *flagDebug || os.Getenv("DEBUG") == "1" {
		logger.SetReportCaller(true)
		logger.Formatter = &prefixed.TextFormatter{
			PrefixPadding: 13,
			DisableColors: true,
			FullTimestamp: false,

			CallerFormatter: func(function, file string) string {
				return fmt.Sprintf(" [%s:%s]", function, file)
			},
			CallerPrettyfier: func(f *runtime.Frame) (string, string) {
				sp := strings.SplitAfter(f.File, "/matterbridge/")
				filename := f.File
				if len(sp) > 1 {
					filename = sp[1]
				}
				s := strings.Split(f.Function, ".")
				funcName := s[len(s)-1]
				return funcName, fmt.Sprintf("%s:%d", filename, f.Line)
			},
		}

		logger.Level = logrus.DebugLevel
		logger.WithFields(logrus.Fields{"prefix": "main"}).Info("Enabling debug logging.")
	}
	return logger
}
<commit_msg>Bump version<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"strings"

	"github.com/42wim/matterbridge/bridge/config"
	"github.com/42wim/matterbridge/gateway"
	"github.com/42wim/matterbridge/gateway/bridgemap"
	"github.com/google/gops/agent"
	prefixed "github.com/matterbridge/logrus-prefixed-formatter"
	"github.com/sirupsen/logrus"
)

var (
	version = "1.22.4-dev"
	githash string

	flagConfig  = flag.String("conf", "matterbridge.toml", "config file")
	flagDebug   = flag.Bool("debug", false, "enable debug")
	flagVersion = flag.Bool("version", false, "show version")
	flagGops    = flag.Bool("gops", false, "enable gops agent")
)

func main() {
	flag.Parse()
	if *flagVersion {
		fmt.Printf("version: %s %s\n", version, githash)
		return
	}

	rootLogger := setupLogger()
	logger := rootLogger.WithFields(logrus.Fields{"prefix": "main"})

	if *flagGops {
		if err := agent.Listen(agent.Options{}); err != nil {
			logger.Errorf("Failed to start gops agent: %#v", err)
		} else {
			defer agent.Close()
		}
	}

	logger.Printf("Running version %s %s", version, githash)
	if strings.Contains(version, "-dev") {
		logger.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.")
	}

	cfg := config.NewConfig(rootLogger, *flagConfig)
	cfg.BridgeValues().General.Debug = *flagDebug

	// if logging to a file, ensure it is closed when the program terminates
	// nolint:errcheck
	defer func() {
		if f, ok := rootLogger.Out.(*os.File); ok {
			f.Sync()
			f.Close()
		}
	}()

	r, err := gateway.NewRouter(rootLogger, cfg, bridgemap.FullMap)
	if err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	if err = r.Start(); err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	logger.Printf("Gateway(s) started succesfully. Now relaying messages")
	select {}
}

func setupLogger() *logrus.Logger {
	logger := &logrus.Logger{
		Out: os.Stdout,
		Formatter: &prefixed.TextFormatter{
			PrefixPadding: 13,
			DisableColors: true,
		},
		Level: logrus.InfoLevel,
	}
	if *flagDebug || os.Getenv("DEBUG") == "1" {
		logger.SetReportCaller(true)
		logger.Formatter = &prefixed.TextFormatter{
			PrefixPadding: 13,
			DisableColors: true,
			FullTimestamp: false,

			CallerFormatter: func(function, file string) string {
				return fmt.Sprintf(" [%s:%s]", function, file)
			},
			CallerPrettyfier: func(f *runtime.Frame) (string, string) {
				sp := strings.SplitAfter(f.File, "/matterbridge/")
				filename := f.File
				if len(sp) > 1 {
					filename = sp[1]
				}
				s := strings.Split(f.Function, ".")
				funcName := s[len(s)-1]
				return funcName, fmt.Sprintf("%s:%d", filename, f.Line)
			},
		}

		logger.Level = logrus.DebugLevel
		logger.WithFields(logrus.Fields{"prefix": "main"}).Info("Enabling debug logging.")
	}
	return logger
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/42wim/matterbridge/bridge/config"
	"github.com/42wim/matterbridge/gateway"
	"github.com/42wim/matterbridge/gateway/bridgemap"
	"github.com/google/gops/agent"
	prefixed "github.com/matterbridge/logrus-prefixed-formatter"
	"github.com/sirupsen/logrus"
)

var (
	version = "1.15.0"
	githash string

	flagConfig  = flag.String("conf", "matterbridge.toml", "config file")
	flagDebug   = flag.Bool("debug", false, "enable debug")
	flagVersion = flag.Bool("version", false, "show version")
	flagGops    = flag.Bool("gops", false, "enable gops agent")
)

func main() {
	flag.Parse()
	if *flagVersion {
		fmt.Printf("version: %s %s\n", version, githash)
		return
	}

	rootLogger := setupLogger()
	logger := rootLogger.WithFields(logrus.Fields{"prefix": "main"})

	if *flagGops {
		if err := agent.Listen(agent.Options{}); err != nil {
			logger.Errorf("Failed to start gops agent: %#v", err)
		} else {
			defer agent.Close()
		}
	}

	logger.Printf("Running version %s %s", version, githash)
	if strings.Contains(version, "-dev") {
		logger.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.")
	}

	cfg := config.NewConfig(rootLogger, *flagConfig)
	cfg.BridgeValues().General.Debug = *flagDebug

	r, err := gateway.NewRouter(rootLogger, cfg, bridgemap.FullMap)
	if err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	if err = r.Start(); err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	logger.Printf("Gateway(s) started succesfully. Now relaying messages")
	select {}
}

func setupLogger() *logrus.Logger {
	logger := &logrus.Logger{
		Out: os.Stdout,
		Formatter: &prefixed.TextFormatter{
			PrefixPadding: 13,
			DisableColors: true,
			FullTimestamp: true,
		},
		Level: logrus.InfoLevel,
	}
	if *flagDebug || os.Getenv("DEBUG") == "1" {
		logger.Formatter = &prefixed.TextFormatter{
			PrefixPadding:   13,
			DisableColors:   true,
			FullTimestamp:   false,
			ForceFormatting: true,
		}
		logger.Level = logrus.DebugLevel
		logger.WithFields(logrus.Fields{"prefix": "main"}).Info("Enabling debug logging.")
	}
	return logger
}
<commit_msg>Bump version<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/42wim/matterbridge/bridge/config"
	"github.com/42wim/matterbridge/gateway"
	"github.com/42wim/matterbridge/gateway/bridgemap"
	"github.com/google/gops/agent"
	prefixed "github.com/matterbridge/logrus-prefixed-formatter"
	"github.com/sirupsen/logrus"
)

var (
	version = "1.15.1-dev"
	githash string

	flagConfig  = flag.String("conf", "matterbridge.toml", "config file")
	flagDebug   = flag.Bool("debug", false, "enable debug")
	flagVersion = flag.Bool("version", false, "show version")
	flagGops    = flag.Bool("gops", false, "enable gops agent")
)

func main() {
	flag.Parse()
	if *flagVersion {
		fmt.Printf("version: %s %s\n", version, githash)
		return
	}

	rootLogger := setupLogger()
	logger := rootLogger.WithFields(logrus.Fields{"prefix": "main"})

	if *flagGops {
		if err := agent.Listen(agent.Options{}); err != nil {
			logger.Errorf("Failed to start gops agent: %#v", err)
		} else {
			defer agent.Close()
		}
	}

	logger.Printf("Running version %s %s", version, githash)
	if strings.Contains(version, "-dev") {
		logger.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.")
	}

	cfg := config.NewConfig(rootLogger, *flagConfig)
	cfg.BridgeValues().General.Debug = *flagDebug

	r, err := gateway.NewRouter(rootLogger, cfg, bridgemap.FullMap)
	if err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	if err = r.Start(); err != nil {
		logger.Fatalf("Starting gateway failed: %s", err)
	}
	logger.Printf("Gateway(s) started succesfully. Now relaying messages")
	select {}
}

func setupLogger() *logrus.Logger {
	logger := &logrus.Logger{
		Out: os.Stdout,
		Formatter: &prefixed.TextFormatter{
			PrefixPadding: 13,
			DisableColors: true,
			FullTimestamp: true,
		},
		Level: logrus.InfoLevel,
	}
	if *flagDebug || os.Getenv("DEBUG") == "1" {
		logger.Formatter = &prefixed.TextFormatter{
			PrefixPadding:   13,
			DisableColors:   true,
			FullTimestamp:   false,
			ForceFormatting: true,
		}
		logger.Level = logrus.DebugLevel
		logger.WithFields(logrus.Fields{"prefix": "main"}).Info("Enabling debug logging.")
	}
	return logger
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/42wim/matterbridge/bridge/config"
	"github.com/42wim/matterbridge/gateway"
	"github.com/42wim/matterbridge/gateway/samechannel"
	log "github.com/Sirupsen/logrus"
	"github.com/google/gops/agent"
	"strings"
)

var (
	version = "0.13.0"
	githash string
)

func init() {
	log.SetFormatter(&log.TextFormatter{FullTimestamp: true})
}

func main() {
	flagConfig := flag.String("conf", "matterbridge.toml", "config file")
	flagDebug := flag.Bool("debug", false, "enable debug")
	flagVersion := flag.Bool("version", false, "show version")
	flagGops := flag.Bool("gops", false, "enable gops agent")
	flag.Parse()
	if *flagGops {
		agent.Listen(&agent.Options{})
		defer agent.Close()
	}
	if *flagVersion {
		fmt.Printf("version: %s %s\n", version, githash)
		return
	}
	flag.Parse()
	if *flagDebug {
		log.Info("Enabling debug")
		log.SetLevel(log.DebugLevel)
	}
	log.Printf("Running version %s %s", version, githash)
	if strings.Contains(version, "-dev") {
		log.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.")
	}
	cfg := config.NewConfig(*flagConfig)

	g := gateway.New(cfg)
	sgw := samechannelgateway.New(cfg)
	gwconfigs := sgw.GetConfig()
	for _, gw := range append(gwconfigs, cfg.Gateway...) {
		if !gw.Enable {
			continue
		}
		err := g.AddConfig(&gw)
		if err != nil {
			log.Fatalf("Starting gateway failed: %s", err)
		}
	}
	err := g.Start()
	if err != nil {
		log.Fatalf("Starting gateway failed: %s", err)
	}
	log.Printf("Gateway(s) started succesfully. Now relaying messages")
	select {}
}
<commit_msg>Bump version<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/42wim/matterbridge/bridge/config"
	"github.com/42wim/matterbridge/gateway"
	"github.com/42wim/matterbridge/gateway/samechannel"
	log "github.com/Sirupsen/logrus"
	"github.com/google/gops/agent"
	"strings"
)

var (
	version = "0.13.1-dev"
	githash string
)

func init() {
	log.SetFormatter(&log.TextFormatter{FullTimestamp: true})
}

func main() {
	flagConfig := flag.String("conf", "matterbridge.toml", "config file")
	flagDebug := flag.Bool("debug", false, "enable debug")
	flagVersion := flag.Bool("version", false, "show version")
	flagGops := flag.Bool("gops", false, "enable gops agent")
	flag.Parse()
	if *flagGops {
		agent.Listen(&agent.Options{})
		defer agent.Close()
	}
	if *flagVersion {
		fmt.Printf("version: %s %s\n", version, githash)
		return
	}
	flag.Parse()
	if *flagDebug {
		log.Info("Enabling debug")
		log.SetLevel(log.DebugLevel)
	}
	log.Printf("Running version %s %s", version, githash)
	if strings.Contains(version, "-dev") {
		log.Println("WARNING: THIS IS A DEVELOPMENT VERSION. Things may break.")
	}
	cfg := config.NewConfig(*flagConfig)

	g := gateway.New(cfg)
	sgw := samechannelgateway.New(cfg)
	gwconfigs := sgw.GetConfig()
	for _, gw := range append(gwconfigs, cfg.Gateway...) {
		if !gw.Enable {
			continue
		}
		err := g.AddConfig(&gw)
		if err != nil {
			log.Fatalf("Starting gateway failed: %s", err)
		}
	}
	err := g.Start()
	if err != nil {
		log.Fatalf("Starting gateway failed: %s", err)
	}
	log.Printf("Gateway(s) started succesfully. Now relaying messages")
	select {}
}
<|endoftext|>


<commit_before>package main

import (
	"math/rand"
	"time"
)

// Deck is an array of Card objects.
type Deck []Card

// InitializeDeck will create a deck of 52 cards and shuffle them.
func InitializeDeck() (deck Deck) {
	deck = CreateDeckOfCards()
	deck.Shuffle()
	return
}

// Shuffle does a random swap of each element in the array.
func (deck *Deck) Shuffle() Deck {
	rand.Seed(time.Now().UTC().UnixNano())
	d := *deck
	for i := range d {
		r := rand.Intn(len(d))
		d[i], d[r] = d[r], d[i]
	}
	return d
}

// Deal cards to player's hands.
func (deck *Deck) Deal(hand Hand) {
	for hand.HandSize < 10 {
		hand.AddCardToHand(*deck)
	}
}
<commit_msg>Added draw and Deal methods to Deck<commit_after>package main

import (
	"math/rand"
	"time"
)

// Deck is an array of Card objects.
type Deck []Card

// InitializeDeck will create a deck of 52 cards and shuffle them.
func InitializeDeck() (deck Deck) {
	deck = CreateDeckOfCards()
	deck.Shuffle()
	return
}

// Shuffle does a random swap of each element in the array.
func (deck *Deck) Shuffle() Deck {
	rand.Seed(time.Now().UTC().UnixNano())
	d := *deck
	for i := range d {
		r := rand.Intn(len(d))
		d[i], d[r] = d[r], d[i]
	}
	return d
}

// Deal cards to player's hands
func (deck *Deck) Deal(p1, p2 *Player) {
	count := 0
	for len(p1.Hand) <= 10 {
		if count%2 == 0 {
			deck.DrawCard(&p1.Hand)
		} else {
			deck.DrawCard(&p2.Hand)
		}
		count++
	}
}

// DrawCard by popping a card from the Deck and appending it to a player's hand.
func (deck *Deck) DrawCard(hand *Hand) {
	d := *deck
	card := d[len(d)-1]
	d = d[:len(d)-1]
	*hand = append(*hand, card)
}
<|endoftext|>