<commit_before>package main

import (
	"context"
	"log"

	"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
	. "github.com/onsi/gomega"

	"github.com/docker/api/azure"
	. "github.com/docker/api/tests/framework"
)

const resourceGroupName = "resourceGroupTest"

var location = "westeurope"

const contextName = "acitest"

func main() {
	SetupTest()

	It("ensures context command includes azure-login and aci-create", func() {
		output := NewDockerCommand("context", "create", "--help").ExecOrDie()
		Expect(output).To(ContainSubstring("docker context create CONTEXT BACKEND [OPTIONS] [flags]"))
		Expect(output).To(ContainSubstring("--aci-location"))
		Expect(output).To(ContainSubstring("--aci-subscription-id"))
		Expect(output).To(ContainSubstring("--aci-resource-group"))
	})

	It("should be initialized with default context", func() {
		_, err := NewCommand("docker", "context", "rm", "-f", contextName).Exec()
		if err == nil {
			log.Println("Cleaning existing test context")
		}

		NewCommand("docker", "context", "use", "default").ExecOrDie()
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(Not(ContainSubstring(contextName)))
		Expect(output).To(ContainSubstring("default *"))
	})

	It("creates a new aci context for tests", func() {
		setupTestResourecGroup(resourceGroupName)
		subscriptionID, err := azure.GetSubscriptionID(context.TODO())
		Expect(err).To(BeNil())

		NewDockerCommand("context", "create", contextName, "aci", "--aci-subscription-id", subscriptionID, "--aci-resource-group", resourceGroupName, "--aci-location", location).ExecOrDie()
		//Expect(output).To(ContainSubstring("ACI context acitest created"))
	})

	defer deleteResourceGroup(resourceGroupName)

	It("uses the aci context", func() {
		currentContext := NewCommand("docker", "context", "use", contextName).ExecOrDie()
		Expect(currentContext).To(ContainSubstring(contextName))
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(ContainSubstring("acitest *"))
	})

	It("ensures no container is running initially", func() {
		output := NewDockerCommand("ps").ExecOrDie()
		Expect(len(Lines(output))).To(Equal(1))
	})

	/*
		var nginxID string
		It("runs nginx on port 80", func() {
			NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
			output := NewDockerCommand("ps").ExecOrDie()
			Lines := Lines(output)
			Expect(len(Lines)).To(Equal(2))

			containerFields := Columns(Lines[1])
			nginxID = containerFields[0]
			Expect(containerFields[1]).To(Equal("nginx"))
			Expect(containerFields[2]).To(Equal("Running"))
			exposedIP := containerFields[3]
			Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

			url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
			output = NewCommand("curl", url).ExecOrDie()
			Expect(output).To(ContainSubstring("Welcome to nginx!"))
		})

		It("removes container nginx", func() {
			output := NewDockerCommand("rm", nginxID).ExecOrDie()
			Expect(Lines(output)[0]).To(Equal(nginxID))
		})
	*/

	It("deploys a compose app", func() {
		NewDockerCommand("compose", "up", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
		//Expect(output).To(ContainSubstring("Successfully deployed"))
		output := NewDockerCommand("ps").ExecOrDie()
		Lines := Lines(output)
		Expect(len(Lines)).To(Equal(4))
		for _, line := range Lines[1:] {
			Expect(line).To(ContainSubstring("Running"))
		}
		/*
				if strings.Contains(line, "acicompose_web") {
					webChecked = true
					containerFields := Columns(line)
					exposedIP := containerFields[3]
					Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

					url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
					output = NewCommand("curl", url).ExecOrDie()
					Expect(output).To(ContainSubstring("Docker Compose demo"))
					output = NewCommand("curl", url+"/words/noun").ExecOrDie()
					Expect(output).To(ContainSubstring("\"word\":"))
				}
			}
			Expect(webChecked).To(BeTrue())
		*/
	})

	It("get logs from web service", func() {
		output := NewDockerCommand("logs", "acidemo_web").ExecOrDie()
		Expect(output).To(ContainSubstring("Listening on port 80"))
	})

	It("shutdown compose app", func() {
		NewDockerCommand("compose", "down", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
	})
	It("switches back to default context", func() {
		output := NewCommand("docker", "context", "use", "default").ExecOrDie()
		Expect(output).To(ContainSubstring("default"))
	})

	It("deletes test context", func() {
		output := NewCommand("docker", "context", "rm", contextName).ExecOrDie()
		Expect(output).To(ContainSubstring(contextName))
	})
}

func setupTestResourecGroup(groupName string) {
	log.Println("Creating resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.CreateOrUpdate(ctx, groupName, resources.Group{
		Location: &location,
	})
	Expect(err).To(BeNil())
}

func deleteResourceGroup(groupName string) {
	log.Println("Deleting resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.Delete(ctx, groupName)
	Expect(err).To(BeNil())
}
<commit_msg>Format with goimport and refactor consts<commit_after>package main

import (
	"context"
	"log"

	"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
	"github.com/Azure/go-autorest/autorest/to"
	. "github.com/onsi/gomega"

	"github.com/docker/api/azure"
	. "github.com/docker/api/tests/framework"
)

const (
	resourceGroupName = "resourceGroupTest"
	location          = "westeurope"
	contextName       = "acitest"
)

func main() {
	SetupTest()

	It("ensures context command includes azure-login and aci-create", func() {
		output := NewDockerCommand("context", "create", "--help").ExecOrDie()
		Expect(output).To(ContainSubstring("docker context create CONTEXT BACKEND [OPTIONS] [flags]"))
		Expect(output).To(ContainSubstring("--aci-location"))
		Expect(output).To(ContainSubstring("--aci-subscription-id"))
		Expect(output).To(ContainSubstring("--aci-resource-group"))
	})

	It("should be initialized with default context", func() {
		_, err := NewCommand("docker", "context", "rm", "-f", contextName).Exec()
		if err == nil {
			log.Println("Cleaning existing test context")
		}

		NewCommand("docker", "context", "use", "default").ExecOrDie()
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(Not(ContainSubstring(contextName)))
		Expect(output).To(ContainSubstring("default *"))
	})

	It("creates a new aci context for tests", func() {
		setupTestResourecGroup(resourceGroupName)
		subscriptionID, err := azure.GetSubscriptionID(context.TODO())
		Expect(err).To(BeNil())

		NewDockerCommand("context", "create", contextName, "aci", "--aci-subscription-id", subscriptionID, "--aci-resource-group", resourceGroupName, "--aci-location", location).ExecOrDie()
		// Expect(output).To(ContainSubstring("ACI context acitest created"))
	})

	defer deleteResourceGroup(resourceGroupName)

	It("uses the aci context", func() {
		currentContext := NewCommand("docker", "context", "use", contextName).ExecOrDie()
		Expect(currentContext).To(ContainSubstring(contextName))
		output := NewCommand("docker", "context", "ls").ExecOrDie()
		Expect(output).To(ContainSubstring("acitest *"))
	})

	It("ensures no container is running initially", func() {
		output := NewDockerCommand("ps").ExecOrDie()
		Expect(len(Lines(output))).To(Equal(1))
	})

	/*
		var nginxID string
		It("runs nginx on port 80", func() {
			NewDockerCommand("run", "nginx", "-p", "80:80").ExecOrDie()
			output := NewDockerCommand("ps").ExecOrDie()
			Lines := Lines(output)
			Expect(len(Lines)).To(Equal(2))

			containerFields := Columns(Lines[1])
			nginxID = containerFields[0]
			Expect(containerFields[1]).To(Equal("nginx"))
			Expect(containerFields[2]).To(Equal("Running"))
			exposedIP := containerFields[3]
			Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

			url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
			output = NewCommand("curl", url).ExecOrDie()
			Expect(output).To(ContainSubstring("Welcome to nginx!"))
		})

		It("removes container nginx", func() {
			output := NewDockerCommand("rm", nginxID).ExecOrDie()
			Expect(Lines(output)[0]).To(Equal(nginxID))
		})
	*/

	It("deploys a compose app", func() {
		NewDockerCommand("compose", "up", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
		// Expect(output).To(ContainSubstring("Successfully deployed"))
		output := NewDockerCommand("ps").ExecOrDie()
		Lines := Lines(output)
		Expect(len(Lines)).To(Equal(4))
		for _, line := range Lines[1:] {
			Expect(line).To(ContainSubstring("Running"))
		}
		/*
				if strings.Contains(line, "acicompose_web") {
					webChecked = true
					containerFields := Columns(line)
					exposedIP := containerFields[3]
					Expect(exposedIP).To(ContainSubstring(":80->80/TCP"))

					url := strings.ReplaceAll(exposedIP, "->80/TCP", "")
					output = NewCommand("curl", url).ExecOrDie()
					Expect(output).To(ContainSubstring("Docker Compose demo"))
					output = NewCommand("curl", url+"/words/noun").ExecOrDie()
					Expect(output).To(ContainSubstring("\"word\":"))
				}
			}
			Expect(webChecked).To(BeTrue())
		*/
	})

	It("get logs from web service", func() {
		output := NewDockerCommand("logs", "acidemo_web").ExecOrDie()
		Expect(output).To(ContainSubstring("Listening on port 80"))
	})

	It("shutdown compose app", func() {
		NewDockerCommand("compose", "down", "-f", "./tests/composefiles/aci-demo/aci_demo_port.yaml", "--name", "acidemo").ExecOrDie()
	})
	It("switches back to default context", func() {
		output := NewCommand("docker", "context", "use", "default").ExecOrDie()
		Expect(output).To(ContainSubstring("default"))
	})

	It("deletes test context", func() {
		output := NewCommand("docker", "context", "rm", contextName).ExecOrDie()
		Expect(output).To(ContainSubstring(contextName))
	})
}

func setupTestResourecGroup(groupName string) {
	log.Println("Creating resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.CreateOrUpdate(ctx, groupName, resources.Group{
		Location: to.StringPtr(location),
	})
	Expect(err).To(BeNil())
}

func deleteResourceGroup(groupName string) {
	log.Println("Deleting resource group " + resourceGroupName)
	ctx := context.TODO()
	subscriptionID, err := azure.GetSubscriptionID(ctx)
	Expect(err).To(BeNil())
	gc := azure.GetGroupsClient(subscriptionID)
	_, err = gc.Delete(ctx, groupName)
	Expect(err).To(BeNil())
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net"
	"sync"
)

func udpServerProxyConnection(receiveAddressString, prefix string, in <-chan []byte, out chan<- []byte) {
	log.Printf("udpServerProxyConnection: " + prefix + " listen on " + receiveAddressString + " and send to unknown yet")

	localAddress, err := net.ResolveUDPAddr("udp", receiveAddressString)
	checkError(err)

	listenConn, err := net.ListenUDP("udp", localAddress)
	checkError(err)
	defer listenConn.Close()

	var mutex = &sync.Mutex{}
	var lastClientAddress *net.UDPAddr

	//read goroutine
	go func() {
		buf := make([]byte, 1024)
		for {
			n, address, err := listenConn.ReadFromUDP(buf[0:])
			if err != nil {
				log.Println("Error: UDP read error: ", err)
				continue
			}

			mutex.Lock()
			lastClientAddress = address
			log.Println("last client address: ", lastClientAddress)
			mutex.Unlock()

			if n > 0 {
				data := buf[0:n]
				log.Println(prefix + " " + bytesToHexString(data))

				out <- data
			}
		}
	}()

	//write local goroutine
	for {
		packet := <-in

		mutex.Lock()
		address := lastClientAddress
		mutex.Unlock()

		if address == nil {
			log.Print("Error: unknown remote address, packet skipped")
			continue
		}
		_, err := listenConn.WriteToUDP(packet, address)
		if err != nil {
			log.Println("Error: UDP write error: ", err)
			continue
		}
	}
}
<commit_msg>print last client address only once<commit_after>package main

import (
	"log"
	"net"
	"sync"
)

func udpServerProxyConnection(receiveAddressString, prefix string, in <-chan []byte, out chan<- []byte) {
	log.Printf("udpServerProxyConnection: " + prefix + " listen on " + receiveAddressString + " and send to unknown yet")

	localAddress, err := net.ResolveUDPAddr("udp", receiveAddressString)
	checkError(err)

	listenConn, err := net.ListenUDP("udp", localAddress)
	checkError(err)
	defer listenConn.Close()

	var mutex = &sync.Mutex{}
	var lastClientAddress *net.UDPAddr

	//read goroutine
	go func() {
		buf := make([]byte, 1024)
		for {
			n, address, err := listenConn.ReadFromUDP(buf[0:])
			if err != nil {
				log.Println("Error: UDP read error: ", err)
				continue
			}

			mutex.Lock()
			if lastClientAddress != address {
				lastClientAddress = address
				log.Println("last client address: ", lastClientAddress)
			}
			mutex.Unlock()

			if n > 0 {
				data := buf[0:n]
				log.Println(prefix + " " + bytesToHexString(data))

				out <- data
			}
		}
	}()

	//write local goroutine
	for {
		packet := <-in

		mutex.Lock()
		address := lastClientAddress
		mutex.Unlock()

		if address == nil {
			log.Print("Error: unknown remote address, packet skipped")
			continue
		}
		_, err := listenConn.WriteToUDP(packet, address)
		if err != nil {
			log.Println("Error: UDP write error: ", err)
			continue
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/xml"
	"fmt"
	id3 "github.com/mikkyang/id3-go"
	kingpin "gopkg.in/alecthomas/kingpin.v1"
	"net/url"
	"os"
	"path/filepath"
)

const (
	Header   = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
	iTunesNs = "http://www.itunes.com/dtds/podcast-1.0.dtd"
)

type Rss struct {
	XMLName xml.Name `xml:"rss"`
	Channel Channel  `xml:"channel"`
	Version string   `xml:"version,attr"`
	NS      string   `xml:"xmlns:itunes,attr"`
}

type Channel struct {
	Title       string  `xml:"title,omitempty"`
	Link        string  `xml:"link,omitempty"`
	Description string  `xml:"description,omitempty"`
	Images      []Image `xml:"image,omitempty"`
	Language    string  `xml:"language,omitempty"`
	Items       []Item  `xml:"item"`
}

type Image struct {
	Title  string `xml:"title,omitempty"`
	Url    string `xml:"url,omitempty"`
	Link   string `xml:"link,omitempty"`
	Width  int    `xml:"width,omitempty"`
	Height int    `xml:"height,omitempty"`
}

type Item struct {
	Title       string    `xml:"title"`
	Description string    `xml:"description"`
	Enclosure   Enclosure `xml:"enclosure"`
	Guid        string    `xml:"guid"`
	Subtitle    string    `xml:"itunes:subtitle"`
}

type Enclosure struct {
	Url    string `xml:"url,attr"`
	Length int64  `xml:"length,attr"`
	Type   string `xml:"type,attr"`
}

func fileUrl(relativePath string, baseUrl string) string {
	Url, _ := url.Parse(baseUrl)
	Url.Path += relativePath
	return Url.String()
}

func addMeta(path string, f os.FileInfo, item *Item) {
	fd, err := id3.Open(path)
	if err != nil {
		item.Title = f.Name()
	} else {
		title := fd.Title()
		author := fd.Artist()
		if len(title) > 0 {
			item.Title = title
		} else {
			item.Title = author
			if len(author) > 0 {
				item.Title += " - "
			}
			item.Title += f.Name()
		}
		item.Subtitle = author
	}
}

func visitFiles(workDir string, channel *Channel, publicUrl string) filepath.WalkFunc {
	return func(path string, f os.FileInfo, err error) error {

		if err != nil {
			return err
		}

		if !!f.IsDir() {
			return nil
		}

		matched, _ := filepath.Match("*.mp3", f.Name())
		if matched {
			url := fileUrl(path[len(workDir)-1:], publicUrl)
			item := Item{Enclosure: Enclosure{Length: f.Size(), Type: "audio/mpeg",
				Url: url}, Guid: url}
			addMeta(path, f, &item)
			channel.Items = append(channel.Items, item)
		}

		return nil

	}
}

var (
	baseUrl     = kingpin.Flag("server", "hostname (and path) to the root e.g. http://myserver.com/rss").Short('s').Default("http://localhost").URL()
	language    = kingpin.Flag("language", "the language of the RSS document, a ISO 639 value").Short('l').String()
	title       = kingpin.Flag("title", "RSS channel title").Short('t').Default("RSS FEED").String()
	description = kingpin.Flag("description", "RSS channel description").Short('d').String()
	path        = kingpin.Arg("directory", "directory to read files relative from").Required().ExistingDir()
)

func main() {

	kingpin.Version("0.0.1")
	kingpin.Parse()

	channel := &Channel{
		Title:       *title,
		Link:        (*baseUrl).String(),
		Description: *description,
		Language:    *language}
	err := filepath.Walk(*path, visitFiles(*path, channel, (*baseUrl).String()))

	if err != nil {
		fmt.Printf("%s: %v\n", os.Args[0], err)
	} else {
		output, err := xml.MarshalIndent(
			&Rss{Channel: *channel, Version: "2.0", NS: iTunesNs}, "", "  ")
		if err != nil {
			fmt.Printf("error: %v\n", err)
		} else {
			os.Stdout.WriteString(Header)
			os.Stdout.Write(output)
		}
	}

}
<commit_msg>implement --recursive flag<commit_after>package main

import (
	"encoding/xml"
	"fmt"
	id3 "github.com/mikkyang/id3-go"
	kingpin "gopkg.in/alecthomas/kingpin.v1"
	"net/url"
	"os"
	"path/filepath"
)

const (
	Header   = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
	iTunesNs = "http://www.itunes.com/dtds/podcast-1.0.dtd"
)

type Rss struct {
	XMLName xml.Name `xml:"rss"`
	Channel Channel  `xml:"channel"`
	Version string   `xml:"version,attr"`
	NS      string   `xml:"xmlns:itunes,attr"`
}

type Channel struct {
	Title       string  `xml:"title,omitempty"`
	Link        string  `xml:"link,omitempty"`
	Description string  `xml:"description,omitempty"`
	Images      []Image `xml:"image,omitempty"`
	Language    string  `xml:"language,omitempty"`
	Items       []Item  `xml:"item"`
}

type Image struct {
	Title  string `xml:"title,omitempty"`
	Url    string `xml:"url,omitempty"`
	Link   string `xml:"link,omitempty"`
	Width  int    `xml:"width,omitempty"`
	Height int    `xml:"height,omitempty"`
}

type Item struct {
	Title       string    `xml:"title"`
	Description string    `xml:"description"`
	Enclosure   Enclosure `xml:"enclosure"`
	Guid        string    `xml:"guid"`
	Subtitle    string    `xml:"itunes:subtitle"`
}

type Enclosure struct {
	Url    string `xml:"url,attr"`
	Length int64  `xml:"length,attr"`
	Type   string `xml:"type,attr"`
}

func fileUrl(relativePath string, baseUrl string) string {
	Url, _ := url.Parse(baseUrl)
	Url.Path += relativePath
	return Url.String()
}

func addMeta(path string, f os.FileInfo, item *Item) {
	fd, err := id3.Open(path)
	if err != nil {
		item.Title = f.Name()
	} else {
		title := fd.Title()
		author := fd.Artist()
		if len(title) > 0 {
			item.Title = title
		} else {
			item.Title = author
			if len(author) > 0 {
				item.Title += " - "
			}
			item.Title += f.Name()
		}
		item.Subtitle = author
	}
}

func visitFiles(workDir string, channel *Channel, publicUrl string, recursive bool) filepath.WalkFunc {
	return func(path string, f os.FileInfo, err error) error {

		if err != nil {
			return err
		}

		if f.IsDir() && path != workDir && !recursive {
			fmt.Println("skipping dir: ", path)
			return filepath.SkipDir
		}

		if !!f.IsDir() {
			return nil
		}

		matched, _ := filepath.Match("*.mp3", f.Name())
		if matched {
			url := fileUrl(path[len(workDir)-1:], publicUrl)
			item := Item{Enclosure: Enclosure{Length: f.Size(), Type: "audio/mpeg",
				Url: url}, Guid: url}
			addMeta(path, f, &item)
			channel.Items = append(channel.Items, item)
		}

		return nil

	}
}

var (
	baseUrl     = kingpin.Flag("server", "hostname (and path) to the root e.g. http://myserver.com/rss").Short('s').Default("http://localhost").URL()
	recursive   = kingpin.Flag("recursive", "how to handle the directory scan").Short('r').Bool()
	language    = kingpin.Flag("language", "the language of the RSS document, a ISO 639 value").Short('l').String()
	title       = kingpin.Flag("title", "RSS channel title").Short('t').Default("RSS FEED").String()
	description = kingpin.Flag("description", "RSS channel description").Short('d').String()
	path        = kingpin.Arg("directory", "directory to read files relative from").Required().ExistingDir()
)

func main() {

	kingpin.Version("0.0.1")
	kingpin.Parse()

	channel := &Channel{
		Title:       *title,
		Link:        (*baseUrl).String(),
		Description: *description,
		Language:    *language}

	err := filepath.Walk(*path, visitFiles(*path, channel, (*baseUrl).String(), *recursive))

	if err != nil {
		fmt.Printf("%s: %v\n", os.Args[0], err)
	} else {
		output, err := xml.MarshalIndent(
			&Rss{Channel: *channel, Version: "2.0", NS: iTunesNs}, "", "  ")
		if err != nil {
			fmt.Printf("error: %v\n", err)
		} else {
			os.Stdout.WriteString(Header)
			os.Stdout.Write(output)
		}
	}

}
<|endoftext|>


<commit_before>// Discordgo - Discord bindings for Go
// Available at https://github.com/bwmarrin/discordgo

// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains high level helper functions and easy entry points for the
// entire discordgo package.  These functions are beling developed and are very
// experimental at this point.  They will most likley change so please use the
// low level functions if that's a problem.

// Package discordgo provides Discord binding for Go
package discordgo

import (
	"fmt"
	"reflect"
)

// VERSION of Discordgo, follows Symantic Versioning. (http://semver.org/)
const VERSION = "0.12.0-alpha"

// New creates a new Discord session and will automate some startup
// tasks if given enough information to do so.  Currently you can pass zero
// arguments and it will return an empty Discord session.
// There are 3 ways to call New:
//     With a single auth token - All requests will use the token blindly,
//         no verification of the token will be done and requests may fail.
//     With an email and password - Discord will sign in with the provided
//         credentials.
//     With an email, password and auth token - Discord will verify the auth
//         token, if it is invalid it will sign in with the provided
//         credentials. This is the Discord recommended way to sign in.
func New(args ...interface{}) (s *Session, err error) {

	// Create an empty Session interface.
	s = &Session{
		State:                  NewState(),
		StateEnabled:           true,
		Compress:               true,
		ShouldReconnectOnError: true,
	}

	// If no arguments are passed return the empty Session interface.
	// Later I will add default values, if appropriate.
	if args == nil {
		return
	}

	// Variables used below when parsing func arguments
	var auth, pass string

	// Parse passed arguments
	for _, arg := range args {

		switch v := arg.(type) {

		case []string:
			if len(v) > 3 {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			// First string is either token or username
			if len(v) > 0 {
				auth = v[0]
			}

			// If second string exists, it must be a password.
			if len(v) > 1 {
				pass = v[1]
			}

			// If third string exists, it must be an auth token.
			if len(v) > 2 {
				s.Token = v[2]
			}

		case string:
			// First string must be either auth token or username.
			// Second string must be a password.
			// Only 2 input strings are supported.

			if auth == "" {
				auth = v
			} else if pass == "" {
				pass = v
			} else if s.Token == "" {
				s.Token = v
			} else {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			//		case Config:
			// TODO: Parse configuration

		default:
			err = fmt.Errorf("Unsupported parameter type provided.")
			return
		}
	}

	// If only one string was provided, assume it is an auth token.
	// Otherwise get auth token from Discord, if a token was specified
	// Discord will verify it for free, or log the user in if it is
	// invalid.
	if pass == "" {
		s.Token = auth
	} else {
		err = s.Login(auth, pass)
		if err != nil || s.Token == "" {
			err = fmt.Errorf("Unable to fetch discord authentication token. %v", err)
			return
		}
	}

	// The Session is now able to have RestAPI methods called on it.
	// It is recommended that you now call Open() so that events will trigger.

	return
}

// validateHandler takes an event handler func, and returns the type of event.
// eg.
//     Session.validateHandler(func (s *discordgo.Session, m *discordgo.MessageCreate))
//     will return the reflect.Type of *discordgo.MessageCreate
func (s *Session) validateHandler(handler interface{}) reflect.Type {
	handlerType := reflect.TypeOf(handler)

	if handlerType.NumIn() != 2 {
		panic("Unable to add event handler, handler must be of the type func(*discordgo.Session, *discordgo.EventType).")
	}

	if handlerType.In(0) != reflect.TypeOf(s) {
		panic("Unable to add event handler, first argument must be of type *discordgo.Session.")
	}

	eventType := handlerType.In(1)

	// Support handlers of type interface{}, this is a special handler, which is triggered on every event.
	if eventType.Kind() == reflect.Interface {
		eventType = nil
	}

	return eventType
}

// AddHandler allows you to add an event handler that will be fired anytime
// the Discord WSAPI event that matches the interface fires.
// eventToInterface in events.go has a list of all the Discord WSAPI events
// and their respective interface.
// eg:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
//     })
//
// or:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.PresenceUpdate) {
//     })
// The return value of this method is a function, that when called will remove the
// event handler.
func (s *Session) AddHandler(handler interface{}) func() {
	s.initialize()

	eventType := s.validateHandler(handler)

	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	h := reflect.ValueOf(handler)

	s.handlers[eventType] = append(s.handlers[eventType], h)

	// This must be done as we need a consistent reference to the
	// reflected value, otherwise a RemoveHandler method would have
	// been nice.
	return func() {
		s.handlersMu.Lock()
		defer s.handlersMu.Unlock()

		handlers := s.handlers[eventType]
		for i, v := range handlers {
			if h == v {
				s.handlers[eventType] = append(handlers[:i], handlers[i+1:]...)
				return
			}
		}
	}
}

// handle calls any handlers that match the event type and any handlers of
// interface{}.
func (s *Session) handle(event interface{}) {
	s.handlersMu.RLock()
	defer s.handlersMu.RUnlock()

	if s.handlers == nil {
		return
	}

	handlerParameters := []reflect.Value{reflect.ValueOf(s), reflect.ValueOf(event)}

	if handlers, ok := s.handlers[reflect.TypeOf(event)]; ok {
		for _, handler := range handlers {
			handler.Call(handlerParameters)
		}
	}

	if handlers, ok := s.handlers[nil]; ok {
		for _, handler := range handlers {
			handler.Call(handlerParameters)
		}
	}
}

// initialize adds all internal handlers and state tracking handlers.
func (s *Session) initialize() {
	s.handlersMu.Lock()
	if s.handlers != nil {
		s.handlersMu.Unlock()
		return
	}

	s.handlers = map[interface{}][]reflect.Value{}
	s.handlersMu.Unlock()

	s.AddHandler(s.onReady)
	s.AddHandler(s.onVoiceServerUpdate)
	s.AddHandler(s.onVoiceStateUpdate)
	s.AddHandler(s.State.onInterface)
}

// onEvent handles events that are unhandled or errored while unmarshalling
func (s *Session) onEvent(se *Session, e *Event) {
	printEvent(e)
}
<commit_msg>Revert "Removed onEvent handler"<commit_after>// Discordgo - Discord bindings for Go
// Available at https://github.com/bwmarrin/discordgo

// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains high level helper functions and easy entry points for the
// entire discordgo package.  These functions are beling developed and are very
// experimental at this point.  They will most likley change so please use the
// low level functions if that's a problem.

// Package discordgo provides Discord binding for Go
package discordgo

import (
	"fmt"
	"reflect"
)

// VERSION of Discordgo, follows Symantic Versioning. (http://semver.org/)
const VERSION = "0.12.0-alpha"

// New creates a new Discord session and will automate some startup
// tasks if given enough information to do so.  Currently you can pass zero
// arguments and it will return an empty Discord session.
// There are 3 ways to call New:
//     With a single auth token - All requests will use the token blindly,
//         no verification of the token will be done and requests may fail.
//     With an email and password - Discord will sign in with the provided
//         credentials.
//     With an email, password and auth token - Discord will verify the auth
//         token, if it is invalid it will sign in with the provided
//         credentials. This is the Discord recommended way to sign in.
func New(args ...interface{}) (s *Session, err error) {

	// Create an empty Session interface.
	s = &Session{
		State:                  NewState(),
		StateEnabled:           true,
		Compress:               true,
		ShouldReconnectOnError: true,
	}

	// If no arguments are passed return the empty Session interface.
	// Later I will add default values, if appropriate.
	if args == nil {
		return
	}

	// Variables used below when parsing func arguments
	var auth, pass string

	// Parse passed arguments
	for _, arg := range args {

		switch v := arg.(type) {

		case []string:
			if len(v) > 3 {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			// First string is either token or username
			if len(v) > 0 {
				auth = v[0]
			}

			// If second string exists, it must be a password.
			if len(v) > 1 {
				pass = v[1]
			}

			// If third string exists, it must be an auth token.
			if len(v) > 2 {
				s.Token = v[2]
			}

		case string:
			// First string must be either auth token or username.
			// Second string must be a password.
			// Only 2 input strings are supported.

			if auth == "" {
				auth = v
			} else if pass == "" {
				pass = v
			} else if s.Token == "" {
				s.Token = v
			} else {
				err = fmt.Errorf("Too many string parameters provided.")
				return
			}

			//		case Config:
			// TODO: Parse configuration

		default:
			err = fmt.Errorf("Unsupported parameter type provided.")
			return
		}
	}

	// If only one string was provided, assume it is an auth token.
	// Otherwise get auth token from Discord, if a token was specified
	// Discord will verify it for free, or log the user in if it is
	// invalid.
	if pass == "" {
		s.Token = auth
	} else {
		err = s.Login(auth, pass)
		if err != nil || s.Token == "" {
			err = fmt.Errorf("Unable to fetch discord authentication token. %v", err)
			return
		}
	}

	// The Session is now able to have RestAPI methods called on it.
	// It is recommended that you now call Open() so that events will trigger.

	return
}

// validateHandler takes an event handler func, and returns the type of event.
// eg.
//     Session.validateHandler(func (s *discordgo.Session, m *discordgo.MessageCreate))
//     will return the reflect.Type of *discordgo.MessageCreate
func (s *Session) validateHandler(handler interface{}) reflect.Type {
	handlerType := reflect.TypeOf(handler)

	if handlerType.NumIn() != 2 {
		panic("Unable to add event handler, handler must be of the type func(*discordgo.Session, *discordgo.EventType).")
	}

	if handlerType.In(0) != reflect.TypeOf(s) {
		panic("Unable to add event handler, first argument must be of type *discordgo.Session.")
	}

	eventType := handlerType.In(1)

	// Support handlers of type interface{}, this is a special handler, which is triggered on every event.
	if eventType.Kind() == reflect.Interface {
		eventType = nil
	}

	return eventType
}

// AddHandler allows you to add an event handler that will be fired anytime
// the Discord WSAPI event that matches the interface fires.
// eventToInterface in events.go has a list of all the Discord WSAPI events
// and their respective interface.
// eg:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
//     })
//
// or:
//     Session.AddHandler(func(s *discordgo.Session, m *discordgo.PresenceUpdate) {
//     })
// The return value of this method is a function, that when called will remove the
// event handler.
func (s *Session) AddHandler(handler interface{}) func() {
	s.initialize()

	eventType := s.validateHandler(handler)

	s.handlersMu.Lock()
	defer s.handlersMu.Unlock()

	h := reflect.ValueOf(handler)

	s.handlers[eventType] = append(s.handlers[eventType], h)

	// This must be done as we need a consistent reference to the
	// reflected value, otherwise a RemoveHandler method would have
	// been nice.
	return func() {
		s.handlersMu.Lock()
		defer s.handlersMu.Unlock()

		handlers := s.handlers[eventType]
		for i, v := range handlers {
			if h == v {
				s.handlers[eventType] = append(handlers[:i], handlers[i+1:]...)
				return
			}
		}
	}
}

// handle calls any handlers that match the event type and any handlers of
// interface{}.
func (s *Session) handle(event interface{}) {
	s.handlersMu.RLock()
	defer s.handlersMu.RUnlock()

	if s.handlers == nil {
		return
	}

	handlerParameters := []reflect.Value{reflect.ValueOf(s), reflect.ValueOf(event)}

	if handlers, ok := s.handlers[reflect.TypeOf(event)]; ok {
		for _, handler := range handlers {
			handler.Call(handlerParameters)
		}
	}

	if handlers, ok := s.handlers[nil]; ok {
		for _, handler := range handlers {
			handler.Call(handlerParameters)
		}
	}
}

// initialize adds all internal handlers and state tracking handlers.
func (s *Session) initialize() {
	s.handlersMu.Lock()
	if s.handlers != nil {
		s.handlersMu.Unlock()
		return
	}

	s.handlers = map[interface{}][]reflect.Value{}
	s.handlersMu.Unlock()

	s.AddHandler(s.onEvent)
	s.AddHandler(s.onReady)
	s.AddHandler(s.onVoiceServerUpdate)
	s.AddHandler(s.onVoiceStateUpdate)
	s.AddHandler(s.State.onInterface)
}

// onEvent handles events that are unhandled or errored while unmarshalling
func (s *Session) onEvent(se *Session, e *Event) {
	printEvent(e)
}

// onReady handles the ready event.
func (s *Session) onReady(se *Session, r *Ready) {
	go s.heartbeat(s.wsConn, s.listening, r.HeartbeatInterval)
}
<|endoftext|>


<commit_before>// mentions everyone in the group so that they get notified about a message
package all

import (
	"gesture/core"
	"strings"
)

func Create(bot *core.Gobot) {
	bot.ListenFor("!all", func(msg core.Message, matches []string) error {
		names := make([]string, 0)
		for _, name := range msg.Names() {
			if name != msg.User && name != bot.Name {
				names = append(names, name)
			}
		}
		if len(names) > 0 {
			msg.Send("cc: " + strings.Join(names, ","))
		}
		return nil
	})
}
<commit_msg>Sort names and separate by spaces<commit_after>// mentions everyone in the group so that they get notified about a message
package all

import (
	"gesture/core"
	"strings"
	"sort"
)

func Create(bot *core.Gobot) {
	bot.ListenFor("!all", func(msg core.Message, matches []string) error {
		names := make([]string, 0)
		for _, name := range msg.Names() {
			if name != msg.User && name != bot.Name {
				names = append(names, name)
			}
		}
		if len(names) > 0 {
			sort.Strings(names)
			msg.Send("cc: " + strings.Join(names, " "))
		}
		return nil
	})
}
<|endoftext|>


<commit_before>// Package typetalk implements the OAuth2 protocol for authenticating users through Typetalk.
// This package can be used as a reference implementation of an OAuth2 provider for Goth.
//
// Typetalk API Docs: https://developer.nulab-inc.com/docs/typetalk/auth/
package typetalk

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"

	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

const (
	authURL         string = "https://typetalk.com/oauth2/authorize"
	tokenURL        string = "https://typetalk.com/oauth2/access_token"
	endpointProfile string = "https://typetalk.com/api/v1/profile"
	endpointUser    string = "https://typetalk.com/api/v1/accounts/profile/"
)

// Provider is the implementation of `goth.Provider` for accessing Typetalk.
type Provider struct {
	ClientKey    string
	Secret       string
	CallbackURL  string
	HTTPClient   *http.Client
	config       *oauth2.Config
	providerName string
}

// New creates a new Typetalk provider and sets up important connection details.
// You should always call `typetalk.New` to get a new provider. Never try to
// create one manually.
func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
	p := &Provider{
		ClientKey:    clientKey,
		Secret:       secret,
		CallbackURL:  callbackURL,
		providerName: "typetalk",
	}
	p.config = newConfig(p, scopes)
	return p
}

// Name is the name used to retrieve this provider later.
func (p *Provider) Name() string {
	return p.providerName
}

// SetName is to update the name of the provider (needed in case of multiple providers os 1 type)
func (p *Provider) SetName(name string) {
	p.providerName = name
}

// Client returns HTTP client.
func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

// Debug is a no-op for the typetalk package.
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Typetalk for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	return &Session{
		AuthURL: p.config.AuthCodeURL(state),
	}, nil
}

// FetchUser will go to Typetalk and access basic information about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
	sess := session.(*Session)
	user := goth.User{
		AccessToken:  sess.AccessToken,
		Provider:     p.Name(),
		RefreshToken: sess.RefreshToken,
		ExpiresAt:    sess.ExpiresAt,
	}

	if user.AccessToken == "" {
		// data is not yet retrieved since accessToken is still empty
		return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
	}

	// Get user name
	response, err := p.Client().Get(endpointProfile + "?access_token=" + url.QueryEscape(sess.AccessToken))
	if err != nil {
		if response != nil {
			response.Body.Close()
		}
		return user, err
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch user name", p.providerName, response.StatusCode)
	}

	bits, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}

	u := struct {
		Account struct {
			Name string `json:"name"`
		} `json:"account"`
	}{}

	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&u)

	// Get user profile info
	response, err = p.Client().Get(endpointUser + u.Account.Name + "?access_token=" + url.QueryEscape(sess.AccessToken))
	if err != nil {
		if response != nil {
			response.Body.Close()
		}
		return user, err
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch profile", p.providerName, response.StatusCode)
	}

	bits, err = ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}

	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData)
	if err != nil {
		return user, err
	}

	err = userFromReader(bytes.NewReader(bits), &user)
	return user, err
}

func newConfig(provider *Provider, scopes []string) *oauth2.Config {
	c := &oauth2.Config{
		ClientID:     provider.ClientKey,
		ClientSecret: provider.Secret,
		RedirectURL:  provider.CallbackURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authURL,
			TokenURL: tokenURL,
		},
		Scopes: []string{},
	}

	if len(scopes) > 0 {
		for _, scope := range scopes {
			c.Scopes = append(c.Scopes, scope)
		}
	} else {
		c.Scopes = append(c.Scopes, "users:read")
	}
	return c
}

func userFromReader(r io.Reader, user *goth.User) error {
	u := struct {
		Account struct {
			ID             int64  `json:"id"`
			Name           string `json:"name"`
			FullName       string `json:"fullName"`
			Suggestion     string `json:"suggestion"`
			MailAddress    string `json:"mailAddress"`
			ImageURL       string `json:"imageUrl"`
			CreatedAt      string `json:"createdAt"`
			UpdatedAt      string `json:"updatedAt"`
			ImageUpdatedAt string `json:"imageUpdatedAt"`
		} `json:"account"`
	}{}
	err := json.NewDecoder(r).Decode(&u)
	if err != nil {
		return err
	}
	user.UserID = strconv.FormatInt(u.Account.ID, 10)
	user.Email = u.Account.MailAddress
	user.Name = u.Account.FullName
	user.NickName = u.Account.Name
	user.AvatarURL = u.Account.ImageURL
	return nil
}

//RefreshTokenAvailable refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() bool {
	return false
}

//RefreshToken get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	return nil, nil
}
<commit_msg>Fix default scope<commit_after>// Package typetalk implements the OAuth2 protocol for authenticating users through Typetalk.
// This package can be used as a reference implementation of an OAuth2 provider for Goth.
//
// Typetalk API Docs: https://developer.nulab-inc.com/docs/typetalk/auth/
package typetalk

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"

	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

const (
	authURL         string = "https://typetalk.com/oauth2/authorize"
	tokenURL        string = "https://typetalk.com/oauth2/access_token"
	endpointProfile string = "https://typetalk.com/api/v1/profile"
	endpointUser    string = "https://typetalk.com/api/v1/accounts/profile/"
)

// Provider is the implementation of `goth.Provider` for accessing Typetalk.
type Provider struct {
	ClientKey    string
	Secret       string
	CallbackURL  string
	HTTPClient   *http.Client
	config       *oauth2.Config
	providerName string
}

// New creates a new Typetalk provider and sets up important connection details.
// You should always call `typetalk.New` to get a new provider. Never try to
// create one manually.
func New(clientKey, secret, callbackURL string, scopes ...string) *Provider {
	p := &Provider{
		ClientKey:    clientKey,
		Secret:       secret,
		CallbackURL:  callbackURL,
		providerName: "typetalk",
	}
	p.config = newConfig(p, scopes)
	return p
}

// Name is the name used to retrieve this provider later.
func (p *Provider) Name() string {
	return p.providerName
}

// SetName is to update the name of the provider (needed in case of multiple providers os 1 type)
func (p *Provider) SetName(name string) {
	p.providerName = name
}

// Client returns HTTP client.
func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

// Debug is a no-op for the typetalk package.
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Typetalk for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	return &Session{
		AuthURL: p.config.AuthCodeURL(state),
	}, nil
}

// FetchUser will go to Typetalk and access basic information about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {
	sess := session.(*Session)
	user := goth.User{
		AccessToken:  sess.AccessToken,
		Provider:     p.Name(),
		RefreshToken: sess.RefreshToken,
		ExpiresAt:    sess.ExpiresAt,
	}

	if user.AccessToken == "" {
		// data is not yet retrieved since accessToken is still empty
		return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
	}

	// Get user name
	response, err := p.Client().Get(endpointProfile + "?access_token=" + url.QueryEscape(sess.AccessToken))
	if err != nil {
		if response != nil {
			response.Body.Close()
		}
		return user, err
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch user name", p.providerName, response.StatusCode)
	}

	bits, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}

	u := struct {
		Account struct {
			Name string `json:"name"`
		} `json:"account"`
	}{}

	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&u)

	// Get user profile info
	response, err = p.Client().Get(endpointUser + u.Account.Name + "?access_token=" + url.QueryEscape(sess.AccessToken))
	if err != nil {
		if response != nil {
			response.Body.Close()
		}
		return user, err
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch profile", p.providerName, response.StatusCode)
	}

	bits, err = ioutil.ReadAll(response.Body)
	if err != nil {
		return user, err
	}

	err = json.NewDecoder(bytes.NewReader(bits)).Decode(&user.RawData)
	if err != nil {
		return user, err
	}

	err = userFromReader(bytes.NewReader(bits), &user)
	return user, err
}

func newConfig(provider *Provider, scopes []string) *oauth2.Config {
	c := &oauth2.Config{
		ClientID:     provider.ClientKey,
		ClientSecret: provider.Secret,
		RedirectURL:  provider.CallbackURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authURL,
			TokenURL: tokenURL,
		},
		Scopes: []string{},
	}

	if len(scopes) > 0 {
		for _, scope := range scopes {
			c.Scopes = append(c.Scopes, scope)
		}
	} else {
		c.Scopes = append(c.Scopes, "my")
	}
	return c
}

func userFromReader(r io.Reader, user *goth.User) error {
	u := struct {
		Account struct {
			ID             int64  `json:"id"`
			Name           string `json:"name"`
			FullName       string `json:"fullName"`
			Suggestion     string `json:"suggestion"`
			MailAddress    string `json:"mailAddress"`
			ImageURL       string `json:"imageUrl"`
			CreatedAt      string `json:"createdAt"`
			UpdatedAt      string `json:"updatedAt"`
			ImageUpdatedAt string `json:"imageUpdatedAt"`
		} `json:"account"`
	}{}
	err := json.NewDecoder(r).Decode(&u)
	if err != nil {
		return err
	}
	user.UserID = strconv.FormatInt(u.Account.ID, 10)
	user.Email = u.Account.MailAddress
	user.Name = u.Account.FullName
	user.NickName = u.Account.Name
	user.AvatarURL = u.Account.ImageURL
	return nil
}

//RefreshTokenAvailable refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() bool {
	return false
}

//RefreshToken get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	return nil, nil
}
<|endoftext|>


<commit_before>// Copyright 2013 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	dtesting "github.com/fsouza/go-dockerclient/testing"
	"github.com/globocom/config"
	"github.com/globocom/docker-cluster/cluster"
	"github.com/globocom/tsuru/db"
	ftesting "github.com/globocom/tsuru/fs/testing"
	"github.com/globocom/tsuru/provision"
	_ "github.com/globocom/tsuru/testing"
	"launchpad.net/gocheck"
	"os"
	"sort"
	"testing"
)

func Test(t *testing.T) { gocheck.TestingT(t) }

type S struct {
	collName      string
	imageCollName string
	conn          *db.Storage
	gitHost       string
	repoNamespace string
	deployCmd     string
	runBin        string
	runArgs       string
	port          string
	hostAddr      string
	sshUser       string
	server        *dtesting.DockerServer
}

var _ = gocheck.Suite(&S{})

func (s *S) SetUpSuite(c *gocheck.C) {
	s.collName = "docker_unit"
	s.imageCollName = "docker_image"
	s.gitHost = "my.gandalf.com"
	s.repoNamespace = "tsuru"
	s.hostAddr = "10.0.0.4"
	s.sshUser = "root"
	config.Set("git:ro-host", s.gitHost)
	config.Set("database:url", "127.0.0.1:27017")
	config.Set("database:name", "docker_provision_tests_s")
	config.Set("docker:repository-namespace", s.repoNamespace)
	config.Set("docker:router", "fake")
	config.Set("docker:collection", s.collName)
	config.Set("docker:host-address", s.hostAddr)
	config.Set("docker:deploy-cmd", "/var/lib/tsuru/deploy")
	config.Set("docker:run-cmd:bin", "/usr/local/bin/circusd /etc/circus/circus.ini")
	config.Set("docker:run-cmd:port", "8888")
	config.Set("docker:ssh:add-key-cmd", "/var/lib/tsuru/add-key")
	config.Set("docker:ssh:user", s.sshUser)
	config.Set("queue", "fake")
	s.deployCmd = "/var/lib/tsuru/deploy"
	s.runBin = "/usr/local/bin/circusd"
	s.runArgs = "/etc/circus/circus.ini"
	s.port = "8888"
	var err error
	s.conn, err = db.Conn()
	c.Assert(err, gocheck.IsNil)
	fsystem = &ftesting.RecordingFs{}
	f, err := fsystem.Create(os.ExpandEnv("${HOME}/.ssh/id_rsa.pub"))
	c.Assert(err, gocheck.IsNil)
	f.Write([]byte("key-content"))
	f.Close()
	s.server, err = dtesting.NewServer(nil)
	c.Assert(err, gocheck.IsNil)
	dCluster, _ = cluster.New(nil,
		cluster.Node{ID: "server", Address: s.server.URL()},
	)
}

func (s *S) TearDownSuite(c *gocheck.C) {
	s.conn.Collection(s.collName).Database.DropDatabase()
	fsystem = nil
}

func (s *S) TestSetUp(c *gocheck.C) {
	clusterNodes = map[string]string{"server": s.server.URL()}
}

type unitSlice []provision.Unit

func (s unitSlice) Len() int {
	return len(s)
}

func (s unitSlice) Less(i, j int) bool {
	return s[i].Name < s[j].Name
}

func (s unitSlice) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func sortUnits(units []provision.Unit) {
	sort.Sort(unitSlice(units))
}
<commit_msg>provision/docker: remove host-address config<commit_after>// Copyright 2013 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	dtesting "github.com/fsouza/go-dockerclient/testing"
	"github.com/globocom/config"
	"github.com/globocom/docker-cluster/cluster"
	"github.com/globocom/tsuru/db"
	ftesting "github.com/globocom/tsuru/fs/testing"
	"github.com/globocom/tsuru/provision"
	_ "github.com/globocom/tsuru/testing"
	"launchpad.net/gocheck"
	"os"
	"sort"
	"testing"
)

func Test(t *testing.T) { gocheck.TestingT(t) }

type S struct {
	collName      string
	imageCollName string
	conn          *db.Storage
	gitHost       string
	repoNamespace string
	deployCmd     string
	runBin        string
	runArgs       string
	port          string
	sshUser       string
	server        *dtesting.DockerServer
}

var _ = gocheck.Suite(&S{})

func (s *S) SetUpSuite(c *gocheck.C) {
	s.collName = "docker_unit"
	s.imageCollName = "docker_image"
	s.gitHost = "my.gandalf.com"
	s.repoNamespace = "tsuru"
	s.sshUser = "root"
	config.Set("git:ro-host", s.gitHost)
	config.Set("database:url", "127.0.0.1:27017")
	config.Set("database:name", "docker_provision_tests_s")
	config.Set("docker:repository-namespace", s.repoNamespace)
	config.Set("docker:router", "fake")
	config.Set("docker:collection", s.collName)
	config.Set("docker:deploy-cmd", "/var/lib/tsuru/deploy")
	config.Set("docker:run-cmd:bin", "/usr/local/bin/circusd /etc/circus/circus.ini")
	config.Set("docker:run-cmd:port", "8888")
	config.Set("docker:ssh:add-key-cmd", "/var/lib/tsuru/add-key")
	config.Set("docker:ssh:user", s.sshUser)
	config.Set("queue", "fake")
	s.deployCmd = "/var/lib/tsuru/deploy"
	s.runBin = "/usr/local/bin/circusd"
	s.runArgs = "/etc/circus/circus.ini"
	s.port = "8888"
	var err error
	s.conn, err = db.Conn()
	c.Assert(err, gocheck.IsNil)
	fsystem = &ftesting.RecordingFs{}
	f, err := fsystem.Create(os.ExpandEnv("${HOME}/.ssh/id_rsa.pub"))
	c.Assert(err, gocheck.IsNil)
	f.Write([]byte("key-content"))
	f.Close()
	s.server, err = dtesting.NewServer(nil)
	c.Assert(err, gocheck.IsNil)
	dCluster, _ = cluster.New(nil,
		cluster.Node{ID: "server", Address: s.server.URL()},
	)
}

func (s *S) TearDownSuite(c *gocheck.C) {
	s.conn.Collection(s.collName).Database.DropDatabase()
	fsystem = nil
}

func (s *S) TestSetUp(c *gocheck.C) {
	clusterNodes = map[string]string{"server": s.server.URL()}
}

type unitSlice []provision.Unit

func (s unitSlice) Len() int {
	return len(s)
}

func (s unitSlice) Less(i, j int) bool {
	return s[i].Name < s[j].Name
}

func (s unitSlice) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func sortUnits(units []provision.Unit) {
	sort.Sort(unitSlice(units))
}
<|endoftext|>


<commit_before>package metric

import (
	"time"

	"github.com/cloudfoundry/dropsonde/metrics"
)

type Counter string

func (c Counter) Increment() {
	metrics.IncrementCounter(string(c))
}

func (c Counter) Add(i uint64) {
	metrics.AddToCounter(string(c), i)
}

type Duration string

func (name Duration) Send(duration time.Duration) error {
	return metrics.SendValue(string(name), float64(duration), "nanos")
}

type Mebibytes string

func (name Mebibytes) Send(mebibytes int) error {
	return metrics.SendValue(string(name), float64(mebibytes), "MiB")
}

type Metric string

func (name Metric) Send(value int) error {
	return metrics.SendValue(string(name), float64(value), "Metric")
}

type Requests string

func (name Requests) Send(value int) error {
	return metrics.SendValue(string(name), float64(value), "Req")
}

type BytesPerSecond string

func (name BytesPerSecond) Send(value float64) error {
	return metrics.SendValue(string(name), value, "B/s")
}

type RequestsPerSecond string

func (name RequestsPerSecond) Send(value float64) error {
	return metrics.SendValue(string(name), value, "Req/s")
}
<commit_msg>Remove 'Requests' type from metrics.<commit_after>package metric

import (
	"time"

	"github.com/cloudfoundry/dropsonde/metrics"
)

type Counter string

func (c Counter) Increment() {
	metrics.IncrementCounter(string(c))
}

func (c Counter) Add(i uint64) {
	metrics.AddToCounter(string(c), i)
}

type Duration string

func (name Duration) Send(duration time.Duration) error {
	return metrics.SendValue(string(name), float64(duration), "nanos")
}

type Mebibytes string

func (name Mebibytes) Send(mebibytes int) error {
	return metrics.SendValue(string(name), float64(mebibytes), "MiB")
}

type Metric string

func (name Metric) Send(value int) error {
	return metrics.SendValue(string(name), float64(value), "Metric")
}

type BytesPerSecond string

func (name BytesPerSecond) Send(value float64) error {
	return metrics.SendValue(string(name), value, "B/s")
}

type RequestsPerSecond string

func (name RequestsPerSecond) Send(value float64) error {
	return metrics.SendValue(string(name), value, "Req/s")
}
<|endoftext|>


<commit_before>// Copyright 2012 Samuel Stauffer. All rights reserved.
// Use of this source code is governed by a 3-clause BSD
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/binary"
	"expvar"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	_ "net/http/pprof"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/samuel/go-librato"
	"github.com/samuel/go-metrics/metrics"
	"github.com/stathat/stathatgo"
)

const (
	REPORT_INTERVAL = 60e9 // nanoseconds
)

var (
	f_httpaddr = flag.String("h", "0.0.0.0:5251", "address of HTTP server")
	f_laddr    = flag.String("l", "0.0.0.0:5252", "the address to listen on")
	f_perc     = flag.String("p", "0.90,0.99,0.999", "comma separated list of percentiles to record")
	f_graphite = flag.String("g", "", "host:port for Graphite's Carbon")
	f_username = flag.String("u", "", "librato metrics username")
	f_token    = flag.String("t", "", "librato metrics token")
	f_stathat  = flag.String("s", "", "StatHat email")
)

var (
	mu              sync.Mutex
	counters        = make(map[string]int64)
	histograms      = make(map[string]metrics.Histogram)
	percentiles     = []float64{}
	percentileNames = []string{}

	statRequestCount    = metrics.NewCounter()
	statRequestRate     = metrics.NewMeter()
	statGraphiteLatency = metrics.NewBiasedHistogram()
	statLibratoLatency  = metrics.NewBiasedHistogram()
	statStatHatLatency  = metrics.NewBiasedHistogram()
)

func init() {
	m := expvar.NewMap("metricsd")
	m.Set("requests", statRequestCount)
	m.Set("requests_per_sec", statRequestRate)
	m.Set("graphite_latency_us", &metrics.HistogramExport{statGraphiteLatency,
		[]float64{0.5, 0.9, 0.99, 0.999}, []string{"p50", "p90", "p99", "p999"}})
	m.Set("librato_latency_us", &metrics.HistogramExport{statLibratoLatency,
		[]float64{0.5, 0.9, 0.99, 0.999}, []string{"p50", "p90", "p99", "p999"}})
	m.Set("stathat_latency_us", &metrics.HistogramExport{statStatHatLatency,
		[]float64{0.5, 0.9, 0.99, 0.999}, []string{"p50", "p90", "p99", "p999"}})
}

func main() {
	parseFlags()

	if *f_httpaddr != "" {
		go func() {
			log.Fatal(http.ListenAndServe(*f_httpaddr, nil))
		}()
	}

	go reporter()
	packetLoop(listen())
}

func parseFlags() {
	flag.Parse()
	if *f_stathat == "" && (*f_username == "" || *f_token == "") && *f_graphite == "" {
		log.Fatal("Either StatHat email, Librato username & token, or Graphite/Carbon required")
	}
	for _, s := range strings.Split(*f_perc, ",") {
		p, err := strconv.ParseFloat(s, 64)
		switch {
		case err != nil:
			log.Fatal("Couldn't parse percentile flag: " + err.Error())
		case p < 0 || p > 1:
			log.Fatalf("Invalid percentile: %f", p)
		}
		percentiles = append(percentiles, p)
		percentileNames = append(percentileNames, strings.Replace(s, "0.", "p", 1))
	}
}

func listen() *net.UDPConn {
	addr, err := net.ResolveUDPAddr("udp", *f_laddr)
	l, err := net.ListenUDP("udp", addr)
	if err != nil {
		log.Fatal(err)
	}
	return l
}

func packetLoop(l net.PacketConn) {
	buf := make([]byte, 4096)
	for {
		n, _, err := l.ReadFrom(buf)
		statRequestCount.Inc(1)
		statRequestRate.Update(1)
		if err != nil {
			log.Println(err.Error())
		}
		if n > 9 {
			mtype := buf[0]
			var value int64
			binary.Read(bytes.NewBuffer(buf[1:9]), binary.BigEndian, &value)
			name := string(buf[9:n])

			switch mtype {
			case 'c':
				updateCounter(name, value)
			case 't':
				updateHistogram(name, value)
			}
		}
	}
}

func updateCounter(name string, value int64) {
	mu.Lock()
	defer mu.Unlock()
	counters[name] += value
}

func updateHistogram(name string, value int64) {
	mu.Lock()
	defer mu.Unlock()
	hist := histograms[name]
	if hist == nil {
		hist = metrics.NewUnbiasedHistogram()
		histograms[name] = hist
	}
	hist.Update(value)
}

func reporter() {
	var met *librato.Metrics = nil
	if *f_username != "" && *f_token != "" {
		met = &librato.Metrics{*f_username, *f_token}
	}
	tc := time.Tick(REPORT_INTERVAL)
	for {
		ts := <-tc
		counters, histograms := swapMetrics()

		if len(counters) > 0 || len(histograms) > 0 {
			if *f_graphite != "" {
				startTime := time.Now()
				if err := sendMetricsGraphite(ts, counters, histograms); err != nil {
					log.Printf(err.Error())
				}
				statGraphiteLatency.Update(time.Now().Sub(startTime).Nanoseconds() / 1e3)
			}

			if met != nil {
				startTime := time.Now()
				if err := sendMetricsLibrato(met, ts, counters, histograms); err != nil {
					log.Printf(err.Error())
				}
				statLibratoLatency.Update(time.Now().Sub(startTime).Nanoseconds() / 1e3)
			}

			if *f_stathat != "" {
				startTime := time.Now()
				if err := sendMetricsStatHat(ts, counters, histograms); err != nil {
					log.Printf(err.Error())
				}
				statStatHatLatency.Update(time.Now().Sub(startTime).Nanoseconds() / 1e3)
			}
		}
	}
}

func swapMetrics() (oldcounters map[string]int64, oldhistograms map[string]metrics.Histogram) {
	mu.Lock()
	defer mu.Unlock()

	oldcounters = counters
	oldhistograms = histograms

	counters = make(map[string]int64)
	histograms = make(map[string]metrics.Histogram)

	return
}

func sendMetricsGraphite(ts time.Time, counters map[string]int64, histograms map[string]metrics.Histogram) error {
	conn, err := net.Dial("tcp", *f_graphite)
	if err != nil {
		return err
	}
	defer conn.Close()
	for name, value := range counters {
		if _, err := fmt.Fprintf(conn, "%s %d %d\n", name, value, ts.Unix()); err != nil {
			return err
		}
	}
	for name, hist := range histograms {
		for i, p := range hist.Percentiles(percentiles) {
			if _, err := fmt.Fprintf(conn, "%s.%s %d %d\n", name, percentileNames[i], p, ts.Unix()); err != nil {
				return err
			}
		}
	}

	return nil
}

func sendMetricsLibrato(met *librato.Metrics, ts time.Time, counters map[string]int64, histograms map[string]metrics.Histogram) error {
	metrics := librato.MetricsFormat{}
	for name, value := range counters {
		metrics.Counters = append(metrics.Counters, librato.Metric{Name: name, Value: float64(value)})
	}
	for name, hist := range histograms {
		metrics.Gauges = append(metrics.Gauges, librato.Metric{Name: name, Value: hist.Mean()})
		for i, p := range hist.Percentiles(percentiles) {
			metrics.Gauges = append(metrics.Gauges,
				librato.Metric{Name: fmt.Sprintf("%s.%s", name, percentileNames[i]), Value: float64(p)})
		}
	}

	return met.SendMetrics(&metrics)
}

func sendMetricsStatHat(ts time.Time, counters map[string]int64, histograms map[string]metrics.Histogram) error {
	for name, value := range counters {
		if err := stathat.PostEZCount(name, *f_stathat, int(value)); err != nil {
			return err
		}
	}
	for name, hist := range histograms {
		if err := stathat.PostEZValue(name, *f_stathat, hist.Mean()); err != nil {
			return err
		}
		for i, p := range hist.Percentiles(percentiles) {
			if err := stathat.PostEZValue(fmt.Sprintf("%s.%s", name, percentileNames[i]), *f_stathat, float64(p)); err != nil {
				return err
			}
		}
	}
	return nil
}
<commit_msg>Fix a couple of issues raised by go vet<commit_after>// Copyright 2012 Samuel Stauffer. All rights reserved.
// Use of this source code is governed by a 3-clause BSD
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/binary"
	"expvar"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	_ "net/http/pprof"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/samuel/go-librato/librato"
	"github.com/samuel/go-metrics/metrics"
	"github.com/stathat/stathatgo"
)

const (
	REPORT_INTERVAL = 60e9 // nanoseconds
)

var (
	f_httpaddr = flag.String("h", "0.0.0.0:5251", "address of HTTP server")
	f_laddr    = flag.String("l", "0.0.0.0:5252", "the address to listen on")
	f_perc     = flag.String("p", "0.90,0.99,0.999", "comma separated list of percentiles to record")
	f_graphite = flag.String("g", "", "host:port for Graphite's Carbon")
	f_username = flag.String("u", "", "librato metrics username")
	f_token    = flag.String("t", "", "librato metrics token")
	f_stathat  = flag.String("s", "", "StatHat email")
)

var (
	mu              sync.Mutex
	counters        = make(map[string]int64)
	histograms      = make(map[string]metrics.Histogram)
	percentiles     = []float64{}
	percentileNames = []string{}

	statRequestCount    = metrics.NewCounter()
	statRequestRate     = metrics.NewMeter()
	statGraphiteLatency = metrics.NewBiasedHistogram()
	statLibratoLatency  = metrics.NewBiasedHistogram()
	statStatHatLatency  = metrics.NewBiasedHistogram()
)

func init() {
	m := expvar.NewMap("metricsd")
	m.Set("requests", statRequestCount)
	m.Set("requests_per_sec", statRequestRate)
	m.Set("graphite_latency_us", &metrics.HistogramExport{Histogram: statGraphiteLatency,
		Percentiles: []float64{0.5, 0.9, 0.99, 0.999}, PercentileNames: []string{"p50", "p90", "p99", "p999"}})
	m.Set("librato_latency_us", &metrics.HistogramExport{Histogram: statLibratoLatency,
		Percentiles: []float64{0.5, 0.9, 0.99, 0.999}, PercentileNames: []string{"p50", "p90", "p99", "p999"}})
	m.Set("stathat_latency_us", &metrics.HistogramExport{Histogram: statStatHatLatency,
		Percentiles: []float64{0.5, 0.9, 0.99, 0.999}, PercentileNames: []string{"p50", "p90", "p99", "p999"}})
}

func main() {
	parseFlags()

	if *f_httpaddr != "" {
		go func() {
			log.Fatal(http.ListenAndServe(*f_httpaddr, nil))
		}()
	}

	go reporter()
	packetLoop(listen())
}

func parseFlags() {
	flag.Parse()
	if *f_stathat == "" && (*f_username == "" || *f_token == "") && *f_graphite == "" {
		log.Fatal("Either StatHat email, Librato username & token, or Graphite/Carbon required")
	}
	for _, s := range strings.Split(*f_perc, ",") {
		p, err := strconv.ParseFloat(s, 64)
		switch {
		case err != nil:
			log.Fatal("Couldn't parse percentile flag: " + err.Error())
		case p < 0 || p > 1:
			log.Fatalf("Invalid percentile: %f", p)
		}
		percentiles = append(percentiles, p)
		percentileNames = append(percentileNames, strings.Replace(s, "0.", "p", 1))
	}
}

func listen() *net.UDPConn {
	addr, err := net.ResolveUDPAddr("udp", *f_laddr)
	l, err := net.ListenUDP("udp", addr)
	if err != nil {
		log.Fatal(err)
	}
	return l
}

func packetLoop(l net.PacketConn) {
	buf := make([]byte, 4096)
	for {
		n, _, err := l.ReadFrom(buf)
		statRequestCount.Inc(1)
		statRequestRate.Update(1)
		if err != nil {
			log.Println(err.Error())
		}
		if n > 9 {
			mtype := buf[0]
			var value int64
			binary.Read(bytes.NewBuffer(buf[1:9]), binary.BigEndian, &value)
			name := string(buf[9:n])

			switch mtype {
			case 'c':
				updateCounter(name, value)
			case 't':
				updateHistogram(name, value)
			}
		}
	}
}

func updateCounter(name string, value int64) {
	mu.Lock()
	defer mu.Unlock()
	counters[name] += value
}

func updateHistogram(name string, value int64) {
	mu.Lock()
	defer mu.Unlock()
	hist := histograms[name]
	if hist == nil {
		hist = metrics.NewUnbiasedHistogram()
		histograms[name] = hist
	}
	hist.Update(value)
}

func reporter() {
	var met *librato.Metrics = nil
	if *f_username != "" && *f_token != "" {
		met = &librato.Metrics{Username: *f_username, Token: *f_token}
	}
	tc := time.Tick(REPORT_INTERVAL)
	for {
		ts := <-tc
		counters, histograms := swapMetrics()

		if len(counters) > 0 || len(histograms) > 0 {
			if *f_graphite != "" {
				startTime := time.Now()
				if err := sendMetricsGraphite(ts, counters, histograms); err != nil {
					log.Printf(err.Error())
				}
				statGraphiteLatency.Update(time.Now().Sub(startTime).Nanoseconds() / 1e3)
			}

			if met != nil {
				startTime := time.Now()
				if err := sendMetricsLibrato(met, ts, counters, histograms); err != nil {
					log.Printf(err.Error())
				}
				statLibratoLatency.Update(time.Now().Sub(startTime).Nanoseconds() / 1e3)
			}

			if *f_stathat != "" {
				startTime := time.Now()
				if err := sendMetricsStatHat(ts, counters, histograms); err != nil {
					log.Printf(err.Error())
				}
				statStatHatLatency.Update(time.Now().Sub(startTime).Nanoseconds() / 1e3)
			}
		}
	}
}

func swapMetrics() (oldcounters map[string]int64, oldhistograms map[string]metrics.Histogram) {
	mu.Lock()
	defer mu.Unlock()

	oldcounters = counters
	oldhistograms = histograms

	counters = make(map[string]int64)
	histograms = make(map[string]metrics.Histogram)

	return
}

func sendMetricsGraphite(ts time.Time, counters map[string]int64, histograms map[string]metrics.Histogram) error {
	conn, err := net.Dial("tcp", *f_graphite)
	if err != nil {
		return err
	}
	defer conn.Close()
	for name, value := range counters {
		if _, err := fmt.Fprintf(conn, "%s %d %d\n", name, value, ts.Unix()); err != nil {
			return err
		}
	}
	for name, hist := range histograms {
		for i, p := range hist.Percentiles(percentiles) {
			if _, err := fmt.Fprintf(conn, "%s.%s %d %d\n", name, percentileNames[i], p, ts.Unix()); err != nil {
				return err
			}
		}
	}

	return nil
}

func sendMetricsLibrato(met *librato.Metrics, ts time.Time, counters map[string]int64, histograms map[string]metrics.Histogram) error {
	metrics := librato.MetricsFormat{}
	for name, value := range counters {
		metrics.Counters = append(metrics.Counters, librato.Metric{Name: name, Value: float64(value)})
	}
	for name, hist := range histograms {
		metrics.Gauges = append(metrics.Gauges, librato.Metric{Name: name, Value: hist.Mean()})
		for i, p := range hist.Percentiles(percentiles) {
			metrics.Gauges = append(metrics.Gauges,
				librato.Metric{Name: fmt.Sprintf("%s.%s", name, percentileNames[i]), Value: float64(p)})
		}
	}

	return met.SendMetrics(&metrics)
}

func sendMetricsStatHat(ts time.Time, counters map[string]int64, histograms map[string]metrics.Histogram) error {
	for name, value := range counters {
		if err := stathat.PostEZCount(name, *f_stathat, int(value)); err != nil {
			return err
		}
	}
	for name, hist := range histograms {
		if err := stathat.PostEZValue(name, *f_stathat, hist.Mean()); err != nil {
			return err
		}
		for i, p := range hist.Percentiles(percentiles) {
			if err := stathat.PostEZValue(fmt.Sprintf("%s.%s", name, percentileNames[i]), *f_stathat, float64(p)); err != nil {
				return err
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package reverseproxy

import (
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
	"github.com/koding/kite"
	"github.com/koding/kite/config"
	"github.com/koding/websocketproxy"
)

const (
	Version = "0.0.1"
	Name    = "proxy"
)

type Proxy struct {
	Kite *kite.Kite

	listener  net.Listener
	TLSConfig *tls.Config

	readyC chan bool // To signal when kite is ready to accept connections
	closeC chan bool // To signal when kite is closed with Close()

	// Holds registered kites. Keys are kite IDs.
	kites   map[string]*url.URL
	kitesMu sync.Mutex

	// muxer for proxy
	mux            *http.ServeMux
	websocketProxy http.Handler
	httpProxy      http.Handler

	// Proxy properties used to give urls and bind the listener
	Scheme     string
	PublicHost string // If given it must match the domain in certificate.
	Port       int
}

func New(conf *config.Config) *Proxy {
	k := kite.New(Name, Version)
	k.Config = conf

	// Listen on 3999 by default

	p := &Proxy{
		Kite:   k,
		kites:  make(map[string]*url.URL),
		readyC: make(chan bool),
		closeC: make(chan bool),
		mux:    http.NewServeMux(),
		Port:   k.Config.Port,
	}

	// third part kites are going to use this to register themself to
	// proxy-kite and get a proxy url, which they use for register to kontrol.
	p.Kite.HandleFunc("register", p.handleRegister)

	// create our websocketproxy http.handler

	p.websocketProxy = &websocketproxy.WebsocketProxy{
		Backend: p.backend,
		Upgrader: &websocket.Upgrader{
			ReadBufferSize:  4096,
			WriteBufferSize: 4096,
			CheckOrigin: func(r *http.Request) bool {
				// TODO: change this to publicdomain and also kites should add them to
				return true
			},
		},
	}

	p.httpProxy = &httputil.ReverseProxy{
		Director: p.director,
	}

	p.mux.Handle("/", k)
	p.mux.Handle("/proxy/", p)

	// OnDisconnect is called whenever a kite is disconnected from us.
	k.OnDisconnect(func(r *kite.Client) {
		k.Log.Info("Removing kite Id '%s' from proxy. It's disconnected", r.Kite.ID)
		delete(p.kites, r.Kite.ID)
	})

	return p
}

// ServeHTTP implements the http.Handler interface.
func (p *Proxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if isWebsocket(req) {
		p.websocketProxy.ServeHTTP(rw, req)
		return
	}

	p.httpProxy.ServeHTTP(rw, req)
}

// isWebsocket checks wether the incoming request is a part of websocket
// handshake
func isWebsocket(req *http.Request) bool {
	if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" ||
		!strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
		return false
	}
	return true
}

func (p *Proxy) CloseNotify() chan bool {
	return p.closeC
}

func (p *Proxy) ReadyNotify() chan bool {
	return p.readyC
}

func (p *Proxy) handleRegister(r *kite.Request) (interface{}, error) {
	kiteUrl, err := url.Parse(r.Args.One().MustString())
	if err != nil {
		return nil, err
	}

	p.kites[r.Client.ID] = kiteUrl

	proxyURL := url.URL{
		Scheme:   p.Scheme,
		Host:     p.PublicHost + ":" + strconv.Itoa(p.Port),
		Path:     "proxy",
		RawQuery: "kiteId=" + r.Client.ID,
	}

	s := proxyURL.String()
	p.Kite.Log.Info("Registering kite with url: '%s'. Can be reached now with: '%s'", kiteUrl, s)

	return s, nil
}

func (p *Proxy) director(req *http.Request) {
	u := p.backend(req)
	if u == nil {
		return
	}

	req.URL.Scheme = u.Scheme
	req.URL.Host = u.Host
	req.URL.Path = u.Path
}

func (p *Proxy) backend(req *http.Request) *url.URL {
	kiteId := req.URL.Query().Get("kiteId")

	p.kitesMu.Lock()
	defer p.kitesMu.Unlock()

	backendURL, ok := p.kites[kiteId]
	if !ok {
		p.Kite.Log.Error("kite for id '%s' is not found: %s", kiteId, req.URL.String())
		return nil
	}

	// change "http" with "ws" because websocket procol expects a ws or wss as
	// scheme
	if err := replaceSchemeWithWS(backendURL); err != nil {
		return nil
	}

	// change now the path for the backend kite. Kite register itself with
	// something like "localhost:7777/kite" however we are going to
	// dial/connect to a sockjs server and there is no sessionId/serverId in
	// the path. This causes problem because the SockJS serve can't parse it.
	// Therefore we as an intermediate client are getting the path as (ommited the query):
	// "/proxy/795/kite-fba0954a-07c7-4d34-4215-6a88733cf65c-OjLnvABL/websocket"
	// which will be converted to
	// "localhost:7777/kite/795/kite-fba0954a-07c7-4d34-4215-6a88733cf65c-OjLnvABL/websocket"
	backendURL.Path += strings.TrimPrefix(req.URL.Path, "/proxy")

	// also change the Origin to the client's host name, like as if someone
	// with the same backendUrl is trying to connect to the kite. Otherwise
	// will get an "Origin not allowed"
	req.Header.Set("Origin", "http://"+backendURL.Host)

	p.Kite.Log.Info("Returning backend url: '%s' for kiteId: %s", backendURL.String(), kiteId)
	return backendURL
}

// TODO: put this into a util package, is used by others too
func replaceSchemeWithWS(u *url.URL) error {
	switch u.Scheme {
	case "http":
		u.Scheme = "ws"
	case "https":
		u.Scheme = "wss"
	default:
		return fmt.Errorf("invalid scheme in url: %s", u.Scheme)
	}
	return nil
}

// ListenAndServe listens on the TCP network address addr and then calls Serve
// with handler to handle requests on incoming connections.
func (p *Proxy) ListenAndServe() error {
	var err error
	p.listener, err = net.Listen("tcp4",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		return err
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	close(p.readyC)

	server := http.Server{
		Handler: p.mux,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) ListenAndServeTLS(certFile, keyFile string) error {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		p.Kite.Log.Fatal("Could not load cert/key files: %s", err.Error())
	}

	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

	p.listener, err = net.Listen("tcp",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		p.Kite.Log.Fatal(err.Error())
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	// now we are ready
	close(p.readyC)

	p.listener = tls.NewListener(p.listener, tlsConfig)

	server := &http.Server{
		Handler:   p.mux,
		TLSConfig: tlsConfig,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) Run() {
	p.ListenAndServe()
}
<commit_msg>reverseproxy: make clear what we do while proxying<commit_after>package reverseproxy

import (
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
	"github.com/koding/kite"
	"github.com/koding/kite/config"
	"github.com/koding/websocketproxy"
)

const (
	Version = "0.0.1"
	Name    = "proxy"
)

type Proxy struct {
	Kite *kite.Kite

	listener  net.Listener
	TLSConfig *tls.Config

	readyC chan bool // To signal when kite is ready to accept connections
	closeC chan bool // To signal when kite is closed with Close()

	// Holds registered kites. Keys are kite IDs.
	kites   map[string]*url.URL
	kitesMu sync.Mutex

	// muxer for proxy
	mux            *http.ServeMux
	websocketProxy http.Handler
	httpProxy      http.Handler

	// Proxy properties used to give urls and bind the listener
	Scheme     string
	PublicHost string // If given it must match the domain in certificate.
	Port       int
}

func New(conf *config.Config) *Proxy {
	k := kite.New(Name, Version)
	k.Config = conf

	// Listen on 3999 by default

	p := &Proxy{
		Kite:   k,
		kites:  make(map[string]*url.URL),
		readyC: make(chan bool),
		closeC: make(chan bool),
		mux:    http.NewServeMux(),
		Port:   k.Config.Port,
	}

	// third part kites are going to use this to register themself to
	// proxy-kite and get a proxy url, which they use for register to kontrol.
	p.Kite.HandleFunc("register", p.handleRegister)

	// create our websocketproxy http.handler

	p.websocketProxy = &websocketproxy.WebsocketProxy{
		Backend: p.backend,
		Upgrader: &websocket.Upgrader{
			ReadBufferSize:  4096,
			WriteBufferSize: 4096,
			CheckOrigin: func(r *http.Request) bool {
				// TODO: change this to publicdomain and also kites should add them to
				return true
			},
		},
	}

	p.httpProxy = &httputil.ReverseProxy{
		Director: p.director,
	}

	p.mux.Handle("/", k)
	p.mux.Handle("/proxy/", p)

	// OnDisconnect is called whenever a kite is disconnected from us.
	k.OnDisconnect(func(r *kite.Client) {
		k.Log.Info("Removing kite Id '%s' from proxy. It's disconnected", r.Kite.ID)
		delete(p.kites, r.Kite.ID)
	})

	return p
}

// ServeHTTP implements the http.Handler interface.
func (p *Proxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
	if isWebsocket(req) {
		p.websocketProxy.ServeHTTP(rw, req)
		return
	}

	p.httpProxy.ServeHTTP(rw, req)
}

// isWebsocket checks wether the incoming request is a part of websocket
// handshake
func isWebsocket(req *http.Request) bool {
	if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" ||
		!strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") {
		return false
	}
	return true
}

func (p *Proxy) CloseNotify() chan bool {
	return p.closeC
}

func (p *Proxy) ReadyNotify() chan bool {
	return p.readyC
}

func (p *Proxy) handleRegister(r *kite.Request) (interface{}, error) {
	kiteUrl, err := url.Parse(r.Args.One().MustString())
	if err != nil {
		return nil, err
	}

	p.kites[r.Client.ID] = kiteUrl

	proxyURL := url.URL{
		Scheme:   p.Scheme,
		Host:     p.PublicHost + ":" + strconv.Itoa(p.Port),
		Path:     "proxy",
		RawQuery: "kiteId=" + r.Client.ID,
	}

	s := proxyURL.String()
	p.Kite.Log.Info("Registering kite with url: '%s'. Can be reached now with: '%s'", kiteUrl, s)

	return s, nil
}

func (p *Proxy) director(req *http.Request) {
	u := p.backend(req)
	if u == nil {
		return
	}

	req.URL.Scheme = u.Scheme
	req.URL.Host = u.Host
	req.URL.Path = u.Path
}

func (p *Proxy) backend(req *http.Request) *url.URL {
	kiteId := req.URL.Query().Get("kiteId")
	p.Kite.Log.Info("[%s] Incoming proxy request", kiteId)

	p.kitesMu.Lock()
	defer p.kitesMu.Unlock()

	backendURL, ok := p.kites[kiteId]
	if !ok {
		p.Kite.Log.Error("kite for id '%s' is not found: %s", kiteId, req.URL.String())
		return nil
	}

	oldScheme := backendURL.Scheme // for logging

	// change "http" with "ws" because websocket procol expects a ws or wss as
	// scheme.
	if err := replaceSchemeWithWS(backendURL); err != nil {
		return nil
	}

	p.Kite.Log.Info("[%s] Changing scheme from '%s' to '%s' to make Websocket connection.", kiteId, oldScheme, backendURL.Scheme)

	// change now the path for the backend kite. Kite register itself with
	// something like "localhost:7777/kite" however we are going to
	// dial/connect to a sockjs server and there is no sessionId/serverId in
	// the path. This causes problem because the SockJS serve can't parse it.
	// Therefore we as an intermediate client are getting the path as (ommited the query):
	// "/proxy/795/kite-fba0954a-07c7-4d34-4215-6a88733cf65c-OjLnvABL/websocket"
	// which will be converted to
	// "localhost:7777/kite/795/kite-fba0954a-07c7-4d34-4215-6a88733cf65c-OjLnvABL/websocket"
	backendURL.Path += strings.TrimPrefix(req.URL.Path, "/proxy")

	// also change the Origin to the client's host name, like as if someone
	// with the same backendUrl is trying to connect to the kite. Otherwise
	// will get an "Origin not allowed"
	req.Header.Set("Origin", "http://"+backendURL.Host)

	p.Kite.Log.Info("[%s] Proxying to backend url: '%s'.", kiteId, backendURL.String())
	return backendURL
}

// TODO: put this into a util package, is used by others too
func replaceSchemeWithWS(u *url.URL) error {
	switch u.Scheme {
	case "http":
		u.Scheme = "ws"
	case "https":
		u.Scheme = "wss"
	default:
		return fmt.Errorf("invalid scheme in url: %s", u.Scheme)
	}
	return nil
}

// ListenAndServe listens on the TCP network address addr and then calls Serve
// with handler to handle requests on incoming connections.
func (p *Proxy) ListenAndServe() error {
	var err error
	p.listener, err = net.Listen("tcp4",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		return err
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	close(p.readyC)

	server := http.Server{
		Handler: p.mux,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) ListenAndServeTLS(certFile, keyFile string) error {
	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
	if err != nil {
		p.Kite.Log.Fatal("Could not load cert/key files: %s", err.Error())
	}

	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

	p.listener, err = net.Listen("tcp",
		net.JoinHostPort(p.Kite.Config.IP, strconv.Itoa(p.Kite.Config.Port)))
	if err != nil {
		p.Kite.Log.Fatal(err.Error())
	}
	p.Kite.Log.Info("Listening on: %s", p.listener.Addr().String())

	// now we are ready
	close(p.readyC)

	p.listener = tls.NewListener(p.listener, tlsConfig)

	server := &http.Server{
		Handler:   p.mux,
		TLSConfig: tlsConfig,
	}

	defer close(p.closeC)
	return server.Serve(p.listener)
}

func (p *Proxy) Run() {
	p.ListenAndServe()
}
<|endoftext|>


<commit_before>package terraform

import (
	"log"

	"github.com/hashicorp/terraform/dag"
)

// GraphNodeAttachResourceState is an interface that can be implemented
// to request that a ResourceState is attached to the node.
type GraphNodeAttachResourceState interface {
	// The address to the resource for the state
	ResourceAddr() *ResourceAddress

	// Sets the state
	AttachResourceState(*ResourceState)
}

// AttachStateTransformer goes through the graph and attaches
// state to nodes that implement the interfaces above.
type AttachStateTransformer struct {
	State *State // State is the root state
}

func (t *AttachStateTransformer) Transform(g *Graph) error {
	// If no state, then nothing to do
	if t.State == nil {
		log.Printf("[DEBUG] Not attaching any state: state is nil")
		return nil
	}

	filter := &StateFilter{State: t.State}
	for _, v := range g.Vertices() {
		// Only care about nodes requesting we're adding state
		an, ok := v.(GraphNodeAttachResourceState)
		if !ok {
			continue
		}
		addr := an.ResourceAddr()

		// Get the module state
		results, err := filter.Filter(addr.String())
		if err != nil {
			return err
		}

		// Attach the first resource state we get
		log.Printf("SEARCH: %s", addr)
		found := false
		for _, result := range results {
			log.Printf("WTF: %s %#v", addr, result)
			if rs, ok := result.Value.(*ResourceState); ok {
				log.Printf(
					"[DEBUG] Attaching resource state to %q: %s",
					dag.VertexName(v), rs)
				an.AttachResourceState(rs)
				found = true
				break
			}
		}

		if !found {
			log.Printf(
				"[DEBUG] Resource state not found for %q: %s",
				dag.VertexName(v), addr)
		}
	}

	return nil
}
<commit_msg>terraform: remove old logging line<commit_after>package terraform

import (
	"log"

	"github.com/hashicorp/terraform/dag"
)

// GraphNodeAttachResourceState is an interface that can be implemented
// to request that a ResourceState is attached to the node.
type GraphNodeAttachResourceState interface {
	// The address to the resource for the state
	ResourceAddr() *ResourceAddress

	// Sets the state
	AttachResourceState(*ResourceState)
}

// AttachStateTransformer goes through the graph and attaches
// state to nodes that implement the interfaces above.
type AttachStateTransformer struct {
	State *State // State is the root state
}

func (t *AttachStateTransformer) Transform(g *Graph) error {
	// If no state, then nothing to do
	if t.State == nil {
		log.Printf("[DEBUG] Not attaching any state: state is nil")
		return nil
	}

	filter := &StateFilter{State: t.State}
	for _, v := range g.Vertices() {
		// Only care about nodes requesting we're adding state
		an, ok := v.(GraphNodeAttachResourceState)
		if !ok {
			continue
		}
		addr := an.ResourceAddr()

		// Get the module state
		results, err := filter.Filter(addr.String())
		if err != nil {
			return err
		}

		// Attach the first resource state we get
		log.Printf("SEARCH: %s", addr)
		found := false
		for _, result := range results {
			if rs, ok := result.Value.(*ResourceState); ok {
				log.Printf(
					"[DEBUG] Attaching resource state to %q: %s",
					dag.VertexName(v), rs)
				an.AttachResourceState(rs)
				found = true
				break
			}
		}

		if !found {
			log.Printf(
				"[DEBUG] Resource state not found for %q: %s",
				dag.VertexName(v), addr)
		}
	}

	return nil
}
<|endoftext|>