<commit_before>// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package httpmitm

import (
	"bytes"
	"io"
	"io/ioutil"
	"net/http"
)

// Origin is an enumeration used to annotate which type of data is being
// fed to the callback.
type Origin uint

// Log transport types.
const (
	Request Origin = iota
	Response
)

// String converts a Origin to a user-friendly string.
func (t Origin) String() string {
	switch t {
	case Request:
		return "Request"
	case Response:
		return "Response"
	default:
		return "Unknown"
	}
}

// Callback is a callback method that is invoked during HTTP communications to
// forward captured data.
type Callback func(Origin, []byte, error)

// Transport is an implementation of http.RoundTripper that logs outgoing
// requests and incoming responses.
type Transport struct {
	// Underlying RoundTripper; uses http.DefaultTransport if nil.
	http.RoundTripper

	Callback Callback // Output callback.
}

// RoundTrip implements the http.RoundTripper interface.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	var buf, bodyBuf bytes.Buffer

	req = &(*req) // Shallow copy of req, since we modify it.

	// Since "Body" is an io.Reader, it can only be read once. However, we need
	// to read it twice, once for the request capture and once for the actual
	// request.
	//
	// To that end, we will tee Body into a Buffer when we perform the initial
	// read, then replace "req.Body" with that Buffer for RoundTrip to read from.
	origBody := req.Body
	if origBody != nil {
		req.Body = ioutil.NopCloser(io.TeeReader(origBody, &bodyBuf))
	}
	req.Write(&buf)
	if origBody != nil {
		if err := origBody.Close(); err != nil {
			t.callback(Request, nil, err)
		}
		req.Body = ioutil.NopCloser(&bodyBuf)
	}
	t.callback(Request, buf.Bytes(), nil)

	rt := t.RoundTripper
	if rt == nil {
		rt = http.DefaultTransport
	}
	res, err := rt.RoundTrip(req)

	if err != nil {
		t.callback(Response, nil, err)
		return res, err
	}

	body := res.Body
	if body != nil {
		bodyBuf.Reset()
		res.Body = ioutil.NopCloser(io.TeeReader(body, &bodyBuf))
		defer body.Close()
	}

	buf.Reset()
	res.Write(&buf)
	t.callback(Response, buf.Bytes(), nil)
	if body != nil {
		res.Body = ioutil.NopCloser(&bodyBuf)
	}
	return res, nil
}

func (t *Transport) callback(o Origin, data []byte, err error) {
	if t.Callback != nil {
		t.Callback(o, data, err)
	}
}
<commit_msg>[httpmitm] fix shallow copy bug<commit_after>// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package httpmitm

import (
	"bytes"
	"io"
	"io/ioutil"
	"net/http"
)

// Origin is an enumeration used to annotate which type of data is being
// fed to the callback.
type Origin uint

// Log transport types.
const (
	Request Origin = iota
	Response
)

// String converts a Origin to a user-friendly string.
func (t Origin) String() string {
	switch t {
	case Request:
		return "Request"
	case Response:
		return "Response"
	default:
		return "Unknown"
	}
}

// Callback is a callback method that is invoked during HTTP communications to
// forward captured data.
type Callback func(Origin, []byte, error)

// Transport is an implementation of http.RoundTripper that logs outgoing
// requests and incoming responses.
type Transport struct {
	// Underlying RoundTripper; uses http.DefaultTransport if nil.
	http.RoundTripper

	Callback Callback // Output callback.
}

// RoundTrip implements the http.RoundTripper interface.
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	var buf, bodyBuf bytes.Buffer

	reqCopy := *req // Shallow copy of req, since we modify it.

	// Since "Body" is an io.Reader, it can only be read once. However, we need
	// to read it twice, once for the request capture and once for the actual
	// request.
	//
	// To that end, we will tee Body into a Buffer when we perform the initial
	// read, then replace "reqCopy.Body" with that Buffer for RoundTrip to read
	// from.
	origBody := reqCopy.Body
	if origBody != nil {
		reqCopy.Body = ioutil.NopCloser(io.TeeReader(origBody, &bodyBuf))
	}
	reqCopy.Write(&buf)
	if origBody != nil {
		if err := origBody.Close(); err != nil {
			t.callback(Request, nil, err)
		}
		reqCopy.Body = ioutil.NopCloser(&bodyBuf)
	}
	t.callback(Request, buf.Bytes(), nil)

	rt := t.RoundTripper
	if rt == nil {
		rt = http.DefaultTransport
	}
	res, err := rt.RoundTrip(&reqCopy)

	if err != nil {
		t.callback(Response, nil, err)
		return res, err
	}

	body := res.Body
	if body != nil {
		bodyBuf.Reset()
		res.Body = ioutil.NopCloser(io.TeeReader(body, &bodyBuf))
		defer body.Close()
	}

	buf.Reset()
	res.Write(&buf)
	t.callback(Response, buf.Bytes(), nil)
	if body != nil {
		res.Body = ioutil.NopCloser(&bodyBuf)
	}
	return res, nil
}

func (t *Transport) callback(o Origin, data []byte, err error) {
	if t.Callback != nil {
		t.Callback(o, data, err)
	}
}
<|endoftext|>


<commit_before>package prometheus

import (
	"net/url"
	"sort"
	"strings"

	"github.com/prometheus/prometheus/pkg/labels"
)

func urlParse(rawurl string) (*url.URL, error) {
	p := strings.IndexByte(rawurl, '?')
	if p < 0 {
		return url.Parse(rawurl)
	}
	m, err := url.Parse(rawurl[p:])
	if m != nil {
		m.Path = rawurl[:p]
	}
	return m, err
}

func Labels(path string) labels.Labels {
	u, err := urlParse(path)
	if err != nil {
		return labels.Labels{labels.Label{Name: "__name__", Value: path}}
	}

	q := u.Query()
	lb := make(labels.Labels, len(q)+1)
	lb[0].Name = "__name__"
	lb[0].Value = u.Path

	i := 0
	for k, v := range q {
		i++
		lb[i].Name = k
		lb[i].Value = v[0]
	}

	if len(lb) > 2 {
		sort.Slice(lb[1:], func(i, j int) bool { return lb[i+1].Name < lb[j+1].Name })
	}

	return lb
}
<commit_msg>sort labels with __name__<commit_after>package prometheus

import (
	"net/url"
	"sort"
	"strings"

	"github.com/prometheus/prometheus/pkg/labels"
)

func urlParse(rawurl string) (*url.URL, error) {
	p := strings.IndexByte(rawurl, '?')
	if p < 0 {
		return url.Parse(rawurl)
	}
	m, err := url.Parse(rawurl[p:])
	if m != nil {
		m.Path = rawurl[:p]
	}
	return m, err
}

func Labels(path string) labels.Labels {
	u, err := urlParse(path)
	if err != nil {
		return labels.Labels{labels.Label{Name: "__name__", Value: path}}
	}

	q := u.Query()
	lb := make(labels.Labels, len(q)+1)
	lb[0].Name = "__name__"
	lb[0].Value = u.Path

	i := 0
	for k, v := range q {
		i++
		lb[i].Name = k
		lb[i].Value = v[0]
	}

	if len(lb) > 1 {
		sort.Slice(lb, func(i, j int) bool { return lb[i].Name < lb[j].Name })
	}

	return lb
}
<|endoftext|>


<commit_before>package mongo

import (
	"context"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"

	"github.com/tidepool-org/platform/page"

	"github.com/tidepool-org/platform/data/types/blood/glucose/summary"
	"github.com/tidepool-org/platform/errors"
	storeStructuredMongo "github.com/tidepool-org/platform/store/structured/mongo"
)

type SummaryRepository struct {
	*storeStructuredMongo.Repository
}

func (d *SummaryRepository) EnsureIndexes() error {
	return d.CreateAllIndexes(context.Background(), []mongo.IndexModel{
		{
			Keys: bson.D{
				{Key: "userId", Value: 1},
			},
			Options: options.Index().
				SetBackground(true).
				SetUnique(true).
				SetName("UserID"),
		},
		{
			Keys: bson.D{
				{Key: "lastUpdated", Value: 1},
			},
			Options: options.Index().
				SetBackground(true).
				SetName("LastUpdated"),
		},
		{
			Keys: bson.D{
				{Key: "outdatedSince", Value: 1},
			},
			Options: options.Index().
				SetBackground(true).
				SetName("OutdatedSince"),
		},
	})
}

func (d *SummaryRepository) GetSummary(ctx context.Context, id string) (*summary.Summary, error) {
	if ctx == nil {
		return nil, errors.New("context is missing")
	}
	if id == "" {
		return nil, errors.New("summary UserID is missing")
	}

	var summary summary.Summary
	selector := bson.M{
		"userId": id,
	}

	err := d.FindOne(ctx, selector).Decode(&summary)

	if err == mongo.ErrNoDocuments {
		return nil, errors.New("summary not found")
	} else if err != nil {
		return nil, errors.Wrap(err, "unable to get summary")
	}

	return &summary, nil
}

func (d *SummaryRepository) GetOutdatedUserIDs(ctx context.Context, page *page.Pagination) ([]string, error) {
	var userIDs []string
	var summaries []*summary.Summary

	if ctx == nil {
		return nil, errors.New("context is missing")
	}

	if page == nil {
		return nil, errors.New("pagination is missing")
	}

	timestamp := time.Now().UTC().Truncate(time.Millisecond)

	selector := bson.M{
		"outdatedSince": bson.M{"$lte": timestamp},
	}

	projection := bson.D{
		{"userId", 1},
		{"_id", 0},
	}
	opts := options.Find().SetProjection(projection)
	opts.SetSort(bson.D{{Key: "outdatedSince", Value: 1}})
	opts.SetLimit(int64(page.Size))

	cursor, err := d.Find(ctx, selector, opts)

	if err == mongo.ErrNoDocuments {
		return nil, nil
	} else if err != nil {
		return nil, errors.Wrap(err, "unable to get outdated summaries")
	}

	if err = cursor.All(ctx, &summaries); err != nil {
		return nil, errors.Wrap(err, "unable to decode outdated summaries")
	}

	for _, v := range summaries {
		userIDs = append(userIDs, v.UserID)
	}

	return userIDs, nil
}

func (d *SummaryRepository) UpdateSummary(ctx context.Context, summary *summary.Summary) (*summary.Summary, error) {
	if ctx == nil {
		return nil, errors.New("context is missing")
	}
	if summary == nil {
		return nil, errors.New("summary object is missing")
	}

	if summary.UserID == "" {
		return nil, errors.New("summary missing UserID")
	}

	opts := options.Replace().SetUpsert(true)
	selector := bson.M{"userId": summary.UserID}

	_, err := d.ReplaceOne(ctx, selector, summary, opts)

	return summary, err
}

func (d *SummaryRepository) SetOutdated(ctx context.Context, id string) (*time.Time, error) {
	if ctx == nil {
		return nil, errors.New("context is missing")
	}

	if id == "" {
		return nil, errors.New("user id is missing")
	}

	// we need to get the summary first, as there is multiple possible operations, and we do not want to replace
	// the existing field, but also want to upsert if no summary exists.
	var summary summary.Summary
	opts := options.Update().SetUpsert(true)
	timestamp := time.Now().UTC().Truncate(time.Millisecond)

	update := bson.M{
		"$set": bson.M{
			"outdatedSince": &timestamp,
		},
	}

	selector := bson.M{
		"userId": id,
	}

	err := d.FindOne(ctx, selector).Decode(&summary)

    if err != nil && err != mongo.ErrNoDocuments {
		return nil, errors.Wrap(err, "unable to get summary")
	}

	if summary.OutdatedSince != nil {
		return summary.OutdatedSince, nil
	}

	_, err = d.UpdateOne(ctx, selector, update, opts)
	if err != nil {
		return nil, errors.Wrap(err, "unable to update outdatedSince date")
	}

	return &timestamp, nil
}

func (d *SummaryRepository) DistinctSummaryIDs(ctx context.Context) ([]string, error) {
	var userIDs []string

	if ctx == nil {
		return userIDs, errors.New("context is missing")
	}

	selector := bson.M{}

	result, err := d.Distinct(ctx, "userId", selector)
	if err != nil {
		return userIDs, errors.New("error fetching distinct userIDs")
	}

	for _, v := range result {
		userIDs = append(userIDs, v.(string))
	}

	return userIDs, nil
}

func (d *SummaryRepository) CreateSummaries(ctx context.Context, summaries []*summary.Summary) (int64, error) {
	if ctx == nil {
		return 0, errors.New("context is missing")
	}
	if len(summaries) == 0 {
		return 0, errors.New("summaries for create missing")
	}

	var insertData []mongo.WriteModel

	for _, userSummary := range summaries {
		insertData = append(insertData, mongo.NewInsertOneModel().SetDocument(userSummary))
	}

	opts := options.BulkWrite().SetOrdered(false)

	writeResult, err := d.BulkWrite(ctx, insertData, opts)
	count := writeResult.InsertedCount

	if err != nil {
		if count > 0 {
			return count, errors.Wrap(err, "failed to create some summaries")
		}
		return count, errors.Wrap(err, "unable to create summaries")
	}
	return count, nil
}
<commit_msg>fix build<commit_after>package mongo

import (
	"context"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"

	"github.com/tidepool-org/platform/page"

	"github.com/tidepool-org/platform/data/types/blood/glucose/summary"
	"github.com/tidepool-org/platform/errors"
	storeStructuredMongo "github.com/tidepool-org/platform/store/structured/mongo"
)

type SummaryRepository struct {
	*storeStructuredMongo.Repository
}

func (d *SummaryRepository) EnsureIndexes() error {
	return d.CreateAllIndexes(context.Background(), []mongo.IndexModel{
		{
			Keys: bson.D{
				{Key: "userId", Value: 1},
			},
			Options: options.Index().
				SetBackground(true).
				SetUnique(true).
				SetName("UserID"),
		},
		{
			Keys: bson.D{
				{Key: "lastUpdated", Value: 1},
			},
			Options: options.Index().
				SetBackground(true).
				SetName("LastUpdated"),
		},
		{
			Keys: bson.D{
				{Key: "outdatedSince", Value: 1},
			},
			Options: options.Index().
				SetBackground(true).
				SetName("OutdatedSince"),
		},
	})
}

func (d *SummaryRepository) GetSummary(ctx context.Context, id string) (*summary.Summary, error) {
	if ctx == nil {
		return nil, errors.New("context is missing")
	}
	if id == "" {
		return nil, errors.New("summary UserID is missing")
	}

	var summary summary.Summary
	selector := bson.M{
		"userId": id,
	}

	err := d.FindOne(ctx, selector).Decode(&summary)

	if err == mongo.ErrNoDocuments {
		return nil, errors.New("summary not found")
	} else if err != nil {
		return nil, errors.Wrap(err, "unable to get summary")
	}

	return &summary, nil
}

func (d *SummaryRepository) GetOutdatedUserIDs(ctx context.Context, page *page.Pagination) ([]string, error) {
	var userIDs []string
	var summaries []*summary.Summary

	if ctx == nil {
		return nil, errors.New("context is missing")
	}

	if page == nil {
		return nil, errors.New("pagination is missing")
	}

	timestamp := time.Now().UTC().Truncate(time.Millisecond)

	selector := bson.M{
		"outdatedSince": bson.M{"$lte": timestamp},
	}

	projection := bson.D{
		{Key: "userId", Value: 1},
		{Key: "_id", Value: 0},
	}
	opts := options.Find().SetProjection(projection)
	opts.SetSort(bson.D{{Key: "outdatedSince", Value: 1}})
	opts.SetLimit(int64(page.Size))

	cursor, err := d.Find(ctx, selector, opts)

	if err == mongo.ErrNoDocuments {
		return nil, nil
	} else if err != nil {
		return nil, errors.Wrap(err, "unable to get outdated summaries")
	}

	if err = cursor.All(ctx, &summaries); err != nil {
		return nil, errors.Wrap(err, "unable to decode outdated summaries")
	}

	for _, v := range summaries {
		userIDs = append(userIDs, v.UserID)
	}

	return userIDs, nil
}

func (d *SummaryRepository) UpdateSummary(ctx context.Context, summary *summary.Summary) (*summary.Summary, error) {
	if ctx == nil {
		return nil, errors.New("context is missing")
	}
	if summary == nil {
		return nil, errors.New("summary object is missing")
	}

	if summary.UserID == "" {
		return nil, errors.New("summary missing UserID")
	}

	opts := options.Replace().SetUpsert(true)
	selector := bson.M{"userId": summary.UserID}

	_, err := d.ReplaceOne(ctx, selector, summary, opts)

	return summary, err
}

func (d *SummaryRepository) SetOutdated(ctx context.Context, id string) (*time.Time, error) {
	if ctx == nil {
		return nil, errors.New("context is missing")
	}

	if id == "" {
		return nil, errors.New("user id is missing")
	}

	// we need to get the summary first, as there is multiple possible operations, and we do not want to replace
	// the existing field, but also want to upsert if no summary exists.
	var summary summary.Summary
	opts := options.Update().SetUpsert(true)
	timestamp := time.Now().UTC().Truncate(time.Millisecond)

	update := bson.M{
		"$set": bson.M{
			"outdatedSince": &timestamp,
		},
	}

	selector := bson.M{
		"userId": id,
	}

	err := d.FindOne(ctx, selector).Decode(&summary)

	if err != nil && err != mongo.ErrNoDocuments {
		return nil, errors.Wrap(err, "unable to get summary")
	}

	if summary.OutdatedSince != nil {
		return summary.OutdatedSince, nil
	}

	_, err = d.UpdateOne(ctx, selector, update, opts)
	if err != nil {
		return nil, errors.Wrap(err, "unable to update outdatedSince date")
	}

	return &timestamp, nil
}

func (d *SummaryRepository) DistinctSummaryIDs(ctx context.Context) ([]string, error) {
	var userIDs []string

	if ctx == nil {
		return userIDs, errors.New("context is missing")
	}

	selector := bson.M{}

	result, err := d.Distinct(ctx, "userId", selector)
	if err != nil {
		return userIDs, errors.New("error fetching distinct userIDs")
	}

	for _, v := range result {
		userIDs = append(userIDs, v.(string))
	}

	return userIDs, nil
}

func (d *SummaryRepository) CreateSummaries(ctx context.Context, summaries []*summary.Summary) (int64, error) {
	if ctx == nil {
		return 0, errors.New("context is missing")
	}
	if len(summaries) == 0 {
		return 0, errors.New("summaries for create missing")
	}

	var insertData []mongo.WriteModel

	for _, userSummary := range summaries {
		insertData = append(insertData, mongo.NewInsertOneModel().SetDocument(userSummary))
	}

	opts := options.BulkWrite().SetOrdered(false)

	writeResult, err := d.BulkWrite(ctx, insertData, opts)
	count := writeResult.InsertedCount

	if err != nil {
		if count > 0 {
			return count, errors.Wrap(err, "failed to create some summaries")
		}
		return count, errors.Wrap(err, "unable to create summaries")
	}
	return count, nil
}
<|endoftext|>


<commit_before>package main

// This is a simple quick script to take a goship config file and put into ETCD. Note: It does not wipe out your
// existing etcd setup.

import (
	"flag"
	"fmt"
	"github.com/coreos/go-etcd/etcd"
	"github.com/kylelemons/go-gypsy/yaml"
	"log"
	"strings"
)

var (
	ConfigFile = flag.String("c", "config.yml", "Path to data directory (default config.yml)")
	ETCDServer = flag.String("e", "http://127.0.0.1:4001", "Etcd Server (default http://127.0.0.1:4001")
)

// Host stores information on a host, such as URI and the latest commit revision.
type Host struct {
	URI             string
	LatestCommit    string
	GitHubCommitURL string
	GitHubDiffURL   string
	ShortCommitHash string
}

// Environment stores information about an individual environment, such as its name and whether it is deployable.
type Environment struct {
	Name               string
	Deploy             string
	RepoPath           string
	Hosts              []Host
	Branch             string
	LatestGitHubCommit string
	IsDeployable       bool
}

// Project stores information about a GitHub project, such as its GitHub URL and repo name.
type Project struct {
	Name         string
	GitHubURL    string
	RepoName     string
	RepoOwner    string
	Environments []Environment
}

type PivotalConfiguration struct {
	project string
	token   string
}

// config contains the information from config.yml.
type config struct {
	Projects   []Project
	DeployUser string
	Notify     string
	Pivotal    *PivotalConfiguration
}

// getYAMLString is a helper function for extracting strings from a yaml.Node.
func getYAMLString(n yaml.Node, key string) string {
	s, ok := n.(yaml.Map)[key].(yaml.Scalar)
	if !ok {
		return ""
	}
	return strings.TrimSpace(s.String())
}

// Send etcd Data and output.
func setETCD(client *etcd.Client, full_key, value string) {
	log.Printf("Setting %s => %s \n", full_key, value)
	client.Create(full_key, value, 0)
}

// parseYAMLEnvironment populates an Environment given a yaml.Node and returns the Environment.
func YAMLtoETCDEnvironment(m yaml.Node, client *etcd.Client, projPath string) {

	for k, v := range m.(yaml.Map) {
		projPath = projPath + "environments/" + k + "/"

		log.Printf("Setting env name=> %s \n", projPath)
		client.CreateDir(projPath, 0)

		branch := getYAMLString(v, "branch")
		setETCD(client, projPath+"branch", branch)

		repoPath := getYAMLString(v, "repo_path")
		setETCD(client, projPath+"repo_path", repoPath)

		deploy := getYAMLString(v, "deploy")
		setETCD(client, projPath+"deploy", deploy)

		log.Printf("Creating Host Directory => %s \n", projPath+"hosts/")
		client.CreateDir(projPath+"hosts/", 0)

		for _, host := range v.(yaml.Map)["hosts"].(yaml.List) {
			h := Host{URI: host.(yaml.Scalar).String()}
			projPath = projPath + "/hosts"
			log.Printf("Setting Hosts => %s \n", projPath+h.URI)
			client.CreateDir(projPath+h.URI, 0)
		}
	}
}

// parseYAML parses the config.yml file and returns the appropriate structs and strings.
func YAMLtoETCD(client *etcd.Client) (c config, err error) {
	config, err := yaml.ReadFile(*ConfigFile)
	if err != nil {
		return c, err
	}
	log.Printf("Setting project root => /projects")
	client.CreateDir("/projects", 0)
	configRoot, _ := config.Root.(yaml.Map)
	projects, _ := configRoot["projects"].(yaml.List)
	for _, p := range projects {
		for k, v := range p.(yaml.Map) {

			log.Printf("Setting project => %s \n", k)
			client.CreateDir(k, 0)

			projectPath := "/projects/" + k + "/"

			name := getYAMLString(v, "project_name")
			setETCD(client, projectPath+"project_name", name)

			repoOwner := getYAMLString(v, "repo_owner")
			setETCD(client, projectPath+"repo_owner", repoOwner)

			repoName := getYAMLString(v, "repo_name")
			setETCD(client, projectPath+"repo_name", repoName)

			for _, v := range v.(yaml.Map)["environments"].(yaml.List) {
				YAMLtoETCDEnvironment(v, client, projectPath)
			}

		}
	}

	piv_project, _ := config.Get("pivotal_project")
	setETCD(client, "pivotal_project", piv_project)

	piv_token, _ := config.Get("pivotal_token")
	setETCD(client, "piv_token", pivotal_token)

	notify, _ := config.Get("notify")
	setETCD(client, "notify", notify)

	return c, err
}

func main() {
	flag.Parse()
	log.Printf("Reading Config file: %s Connecting to ETCD server: %s", *ConfigFile, *ETCDServer)
	// Note the ETCD client library swallows errors connecting to etcd (worry)
	a := etcd.NewClient([]string{*ETCDServer})
	_, err := YAMLtoETCD(a)
	if err != nil {
		fmt.Printf("Failed to Parse Yaml and Add to ETCD [%s]\n", err)
	}
}
<commit_msg>Small fix<commit_after>package main

// This is a simple quick script to take a goship config file and put into ETCD. Note: It does not wipe out your
// existing etcd setup.

import (
	"flag"
	"fmt"
	"github.com/coreos/go-etcd/etcd"
	"github.com/kylelemons/go-gypsy/yaml"
	"log"
	"strings"
)

var (
	ConfigFile = flag.String("c", "config.yml", "Path to data directory (default config.yml)")
	ETCDServer = flag.String("e", "http://127.0.0.1:4001", "Etcd Server (default http://127.0.0.1:4001")
)

// Host stores information on a host, such as URI and the latest commit revision.
type Host struct {
	URI             string
	LatestCommit    string
	GitHubCommitURL string
	GitHubDiffURL   string
	ShortCommitHash string
}

// Environment stores information about an individual environment, such as its name and whether it is deployable.
type Environment struct {
	Name               string
	Deploy             string
	RepoPath           string
	Hosts              []Host
	Branch             string
	LatestGitHubCommit string
	IsDeployable       bool
}

// Project stores information about a GitHub project, such as its GitHub URL and repo name.
type Project struct {
	Name         string
	GitHubURL    string
	RepoName     string
	RepoOwner    string
	Environments []Environment
}

type PivotalConfiguration struct {
	project string
	token   string
}

// config contains the information from config.yml.
type config struct {
	Projects   []Project
	DeployUser string
	Notify     string
	Pivotal    *PivotalConfiguration
}

// getYAMLString is a helper function for extracting strings from a yaml.Node.
func getYAMLString(n yaml.Node, key string) string {
	s, ok := n.(yaml.Map)[key].(yaml.Scalar)
	if !ok {
		return ""
	}
	return strings.TrimSpace(s.String())
}

// Send etcd Data and output.
func setETCD(client *etcd.Client, full_key, value string) {
	log.Printf("Setting %s => %s \n", full_key, value)
	client.Create(full_key, value, 0)
}

// parseYAMLEnvironment populates an Environment given a yaml.Node and returns the Environment.
func YAMLtoETCDEnvironment(m yaml.Node, client *etcd.Client, projPath string) {

	for k, v := range m.(yaml.Map) {
		projPath = projPath + "environments/" + k + "/"

		log.Printf("Setting env name=> %s \n", projPath)
		client.CreateDir(projPath, 0)

		branch := getYAMLString(v, "branch")
		setETCD(client, projPath+"branch", branch)

		repoPath := getYAMLString(v, "repo_path")
		setETCD(client, projPath+"repo_path", repoPath)

		deploy := getYAMLString(v, "deploy")
		setETCD(client, projPath+"deploy", deploy)

		log.Printf("Creating Host Directory => %s \n", projPath+"hosts/")
		client.CreateDir(projPath+"hosts/", 0)

		for _, host := range v.(yaml.Map)["hosts"].(yaml.List) {
			h := Host{URI: host.(yaml.Scalar).String()}
			projPath = projPath + "/hosts"
			log.Printf("Setting Hosts => %s \n", projPath+h.URI)
			client.CreateDir(projPath+h.URI, 0)
		}
	}
}

// parseYAML parses the config.yml file and returns the appropriate structs and strings.
func YAMLtoETCD(client *etcd.Client) (c config, err error) {
	config, err := yaml.ReadFile(*ConfigFile)
	if err != nil {
		return c, err
	}
	log.Printf("Setting project root => /projects")
	client.CreateDir("/projects", 0)
	configRoot, _ := config.Root.(yaml.Map)
	projects, _ := configRoot["projects"].(yaml.List)
	for _, p := range projects {
		for k, v := range p.(yaml.Map) {

			log.Printf("Setting project => %s \n", k)
			client.CreateDir(k, 0)

			projectPath := "/projects/" + k + "/"

			name := getYAMLString(v, "project_name")
			setETCD(client, projectPath+"project_name", name)

			repoOwner := getYAMLString(v, "repo_owner")
			setETCD(client, projectPath+"repo_owner", repoOwner)

			repoName := getYAMLString(v, "repo_name")
			setETCD(client, projectPath+"repo_name", repoName)

			for _, v := range v.(yaml.Map)["environments"].(yaml.List) {
				YAMLtoETCDEnvironment(v, client, projectPath)
			}

		}
	}

	piv_project, _ := config.Get("pivotal_project")
	setETCD(client, "pivotal_project", piv_project)

	piv_token, _ := config.Get("pivotal_token")
	setETCD(client, "pivotal_token", piv_token)

	notify, _ := config.Get("notify")
	setETCD(client, "notify", notify)

	return c, err
}

func main() {
	flag.Parse()
	log.Printf("Reading Config file: %s Connecting to ETCD server: %s", *ConfigFile, *ETCDServer)
	// Note the ETCD client library swallows errors connecting to etcd (worry)
	a := etcd.NewClient([]string{*ETCDServer})
	_, err := YAMLtoETCD(a)
	if err != nil {
		fmt.Printf("Failed to Parse Yaml and Add to ETCD [%s]\n", err)
	}
}
<|endoftext|>


<commit_before>package ecc

import (
	"errors"
	"fmt"
	"github.com/bfix/gospel/math"
)

// Curve is the elliptic curve used for Bitcoin (Secp256k1)
type Curve struct {
	// P is the generator of the underlying field "F_p"
	// = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
	P *math.Int
	// Gx is the x-coord of the base point
	Gx *math.Int
	// Gy is the y-coord of the base point
	Gy *math.Int
	// N is the order of G
	N *math.Int
	// curve parameter (=7)
	B *math.Int
}

var (
	// Curve is the reference to a curve instance (meant as singleton)
	c = &Curve{
		P:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"),
		Gx: math.NewIntFromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"),
		Gy: math.NewIntFromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"),
		N:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),
		B:  math.SEVEN,
	}
)

// GetCurve returns the singleton curve instance
func GetCurve() *Curve {
	return c
}

// GetBasePoint returns the base Point of the curve
func GetBasePoint() *Point {
	return NewPoint(c.Gx, c.Gy)
}

// GetBasePointNeg returns the negative base point of the curve
func GetBasePointNeg() *Point {
	return NewPoint(c.Gx, c.Gy.Neg())
}

// MultBase multiplies the base Point of the curve with a scalar value k
func MultBase(k *math.Int) *Point {
	return GetBasePoint().Mult(k)
}

// Inf is the point at "infinity"
var Inf = NewPoint(math.ZERO, math.ZERO)

// Point (x,y) on the curve
type Point struct { // exported Point type
	x, y *math.Int // coordinate values
}

// NewPoint instaniates a new Point
func NewPoint(a, b *math.Int) *Point {
	return &Point{x: a, y: b}
}

// NewPointFromBytes reconstructs a Point from binary representation.
func NewPointFromBytes(b []byte) (p *Point, compr bool, err error) {
	p = NewPoint(math.ZERO, math.ZERO)
	err = nil
	compr = true
	switch b[0] {
	case 0:
	case 4:
		p.x = math.NewIntFromBytes(b[1:33])
		p.y = math.NewIntFromBytes(b[33:])
		compr = false
	case 3:
		p.x = math.NewIntFromBytes(b[1:])
		p.y, err = computeY(p.x, 1)
		if err != nil {
			return
		}
	case 2:
		p.x = math.NewIntFromBytes(b[1:])
		p.y, err = computeY(p.x, 0)
		if err != nil {
			return
		}
	default:
		err = errors.New("Invalid binary Point representation")
	}
	return
}

func (p *Point) String() string {
	return fmt.Sprintf("(%v,%v)", p.x, p.y)
}

// Equals checks if two Points are equal
func (p *Point) Equals(q *Point) bool {
	return p.x.Cmp(q.x) == 0 && p.y.Cmp(q.y) == 0
}

// IsInf checks if a Point is at infinity
func (p *Point) IsInf() bool {
	return p.x.Cmp(math.ZERO) == 0 && p.y.Cmp(math.ZERO) == 0
}

// IsOnCurve checks if a Point (x,y) is on the curve
func (p *Point) IsOnCurve() bool {
	// y² = x³ + 7
	y2 := pSqr(p.y)
	x3 := pCub(p.x)
	return y2.Cmp(pAdd(x3, c.B)) == 0
}

// Add two Points on the curve
func (p *Point) Add(q *Point) *Point {
	if p.Equals(q) {
		return p.Double()
	}
	if p.Equals(Inf) {
		return q
	}
	if q.Equals(Inf) {
		return p
	}
	_p1 := newJacPoint(p.x, p.y, math.ONE)
	_p2 := newJacPoint(q.x, q.y, math.ONE)
	return _p1.add(_p2).conv()
}

// Double a Point on the curve
func (p *Point) Double() *Point {
	if p.Equals(Inf) {
		return Inf
	}
	return newJacPoint(p.x, p.y, math.ONE).double().conv()
}

// Mult multiplies a Point on the curve with a scalar value k using
// a Montgomery multiplication approach
func (p *Point) Mult(k *math.Int) *Point {
	return newJacPoint(p.x, p.y, math.ONE).mult(k).conv()
}

// Bytes returns a byte representation of Point (compressed or uncompressed).
func (p *Point) Bytes(compressed bool) []byte {
	if p.Equals(Inf) {
		return []byte{0}
	}
	var res []byte
	if compressed {
		rc := byte(2)
		if p.y.Bit(0) == 1 {
			rc = 3
		}
		res = append(res, rc)
		res = append(res, coordAsBytes(p.x)...)
	} else {
		res = append(res, 4)
		res = append(res, coordAsBytes(p.x)...)
		res = append(res, coordAsBytes(p.y)...)
	}
	return res
}

// JacPoint is a point on the curve that is represented internally in
// Jacobian coordinates (X,Y,Z) with "x = X/Z^2" and "y = Y/Z^3". See:
// [http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html]
type jacPoint struct { // internal Point type
	x, y, z *math.Int // using Jacobian coordinates
}

// NewJacPoint instaniates a new Point
func newJacPoint(a, b, c *math.Int) *jacPoint {
	return &jacPoint{x: a, y: b, z: c}
}

// Point at infinity
var jacInf = newJacPoint(Inf.x, Inf.y, math.ONE)

// check if a Point is at infinity
func (p *jacPoint) isInf() bool {
	return p.x.Equals(math.ZERO) && p.y.Equals(math.ZERO)
}

// convert internal Point to external representation
func (p *jacPoint) conv() *Point {
	zi := pInv(p.z)
	x := pMul(p.x, pSqr(zi))
	y := pMul(p.y, pCub(zi))
	return NewPoint(x, y)
}

// add two jacPoints on the curve
// [http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian-0/addJacition/addJac-2007-bl]
func (p *jacPoint) add(q *jacPoint) *jacPoint {
	if p.isInf() {
		return q
	}
	if q.isInf() {
		return p
	}
	z1z1 := pSqr(p.z)
	z2z2 := pSqr(q.z)
	u1 := pMul(p.x, z2z2)
	u2 := pMul(q.x, z1z1)
	s1 := pMul(pMul(p.y, q.z), z2z2)
	s2 := pMul(pMul(q.y, p.z), z1z1)
	h := pSub(u2, u1)
	i := pSqr(pMul(math.TWO, h))
	j := pMul(h, i)
	r := pMul(math.TWO, pSub(s2, s1))
	v := pMul(u1, i)
	w := pAdd(p.z, q.z)
	x := pSub(pSub(pSqr(r), j), pMul(math.TWO, v))
	y := pSub(pMul(r, pSub(v, x)), pMul(math.TWO, pMul(s1, j)))
	z := pMul(pSub(pSub(pSqr(w), z1z1), z2z2), h)
	return newJacPoint(x, y, z)
}

// double a Point on the curve
// [http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian-0/doubling/dbl-2009-alnr]
func (p *jacPoint) double() *jacPoint {
	if p.isInf() {
		return p
	}
	a := pSqr(p.x)
	b := pSqr(p.y)
	zz := pSqr(p.z)
	c := pSqr(b)
	d := pMul(math.TWO, pSub(pSub(pSqr(p.x.Add(b)), a), c))
	e := pMul(math.THREE, a)
	f := pSqr(e)
	x := pSub(f, pMul(math.TWO, d))
	y := pSub(pMul(e, pSub(d, x)), pMul(math.EIGHT, c))
	z := pSub(pSub(pSqr(pAdd(p.y, p.z)), b), zz)
	return newJacPoint(x, y, z)
}

// Multiply a Point on the curve with a scalar value k using
// a Montgomery multiplication algorithm
func (p *jacPoint) mult(k *math.Int) *jacPoint {
	if p.isInf() {
		return p
	}
	if k.Cmp(math.ZERO) == 0 {
		return jacInf
	}
	r := jacInf
	for _, val := range k.Bytes() {
		for pos := 0; pos < 8; pos++ {
			r = r.double()
			if val&0x80 == 0x80 {
				r = p.add(r)
			}
			val <<= 1
		}
	}
	return r
}

// helper: convert coordinate to byte array of correct length
func coordAsBytes(v *math.Int) []byte {
	bv := v.Bytes()
	plen := 32 - len(bv)
	if plen == 0 {
		return bv
	}
	b := make([]byte, plen)
	return append(b, bv...)
}

// helper: reconstruct y-coordinate of Point
func computeY(x *math.Int, m uint) (y *math.Int, err error) {
	y = math.ZERO
	err = nil
	y2 := pAdd(pCub(x), c.B)
	y, err = math.SqrtModP(y2, c.P)
	if err == nil {
		if y.Bit(0) != m {
			y = c.P.Sub(y)
		}
	}
	return
}

// modulus
func nMod(a *math.Int) *math.Int {
	return a.Mod(c.N)
}

func pInv(a *math.Int) *math.Int {
	return a.ModInverse(c.P)
}

func pMul(a, b *math.Int) *math.Int {
	return a.Mul(b).Mod(c.P)
}

func pSqr(a *math.Int) *math.Int {
	return pMul(a, a)
}

func pCub(a *math.Int) *math.Int {
	return pMul(pSqr(a), a)
}

func pSub(a, b *math.Int) *math.Int {
	x := a.Sub(b)
	if x.Sign() == -1 {
		x = x.Add(c.P)
	}
	return x
}

func pAdd(a, b *math.Int) *math.Int {
	return a.Add(b).Mod(c.P)
}

func nInv(a *math.Int) *math.Int {
	return a.ModInverse(c.N)
}

func nMul(a, b *math.Int) *math.Int {
	return a.Mul(b).Mod(c.N)
}

func nRnd(a *math.Int) *math.Int {
	return math.NewIntRndRange(a, c.N)
}
<commit_msg>Added function for negative curve point.<commit_after>package ecc

import (
	"errors"
	"fmt"
	"github.com/bfix/gospel/math"
)

// Curve is the elliptic curve used for Bitcoin (Secp256k1)
type Curve struct {
	// P is the generator of the underlying field "F_p"
	// = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
	P *math.Int
	// Gx is the x-coord of the base point
	Gx *math.Int
	// Gy is the y-coord of the base point
	Gy *math.Int
	// N is the order of G
	N *math.Int
	// curve parameter (=7)
	B *math.Int
}

var (
	// Curve is the reference to a curve instance (meant as singleton)
	c = &Curve{
		P:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"),
		Gx: math.NewIntFromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"),
		Gy: math.NewIntFromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"),
		N:  math.NewIntFromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),
		B:  math.SEVEN,
	}
)

// GetCurve returns the singleton curve instance
func GetCurve() *Curve {
	return c
}

// GetBasePoint returns the base Point of the curve
func GetBasePoint() *Point {
	return NewPoint(c.Gx, c.Gy)
}

// MultBase multiplies the base Point of the curve with a scalar value k
func MultBase(k *math.Int) *Point {
	return GetBasePoint().Mult(k)
}

// Inf is the point at "infinity"
var Inf = NewPoint(math.ZERO, math.ZERO)

// Point (x,y) on the curve
type Point struct { // exported Point type
	x, y *math.Int // coordinate values
}

// NewPoint instaniates a new Point
func NewPoint(a, b *math.Int) *Point {
	return &Point{x: a, y: b}
}

// NewPointFromBytes reconstructs a Point from binary representation.
func NewPointFromBytes(b []byte) (p *Point, compr bool, err error) {
	p = NewPoint(math.ZERO, math.ZERO)
	err = nil
	compr = true
	switch b[0] {
	case 0:
	case 4:
		p.x = math.NewIntFromBytes(b[1:33])
		p.y = math.NewIntFromBytes(b[33:])
		compr = false
	case 3:
		p.x = math.NewIntFromBytes(b[1:])
		p.y, err = computeY(p.x, 1)
		if err != nil {
			return
		}
	case 2:
		p.x = math.NewIntFromBytes(b[1:])
		p.y, err = computeY(p.x, 0)
		if err != nil {
			return
		}
	default:
		err = errors.New("Invalid binary Point representation")
	}
	return
}

// Neg returns -P for the point P.
func (p *Point) Neg() *Point {
	return NewPoint(p.x, p.y.Neg())
}

// String returns a human-readable representation of a point.
func (p *Point) String() string {
	return fmt.Sprintf("(%v,%v)", p.x, p.y)
}

// Equals checks if two Points are equal
func (p *Point) Equals(q *Point) bool {
	return p.x.Cmp(q.x) == 0 && p.y.Cmp(q.y) == 0
}

// IsInf checks if a Point is at infinity
func (p *Point) IsInf() bool {
	return p.x.Cmp(math.ZERO) == 0 && p.y.Cmp(math.ZERO) == 0
}

// IsOnCurve checks if a Point (x,y) is on the curve
func (p *Point) IsOnCurve() bool {
	// y² = x³ + 7
	y2 := pSqr(p.y)
	x3 := pCub(p.x)
	return y2.Cmp(pAdd(x3, c.B)) == 0
}

// Add two Points on the curve
func (p *Point) Add(q *Point) *Point {
	if p.Equals(q) {
		return p.Double()
	}
	if p.Equals(Inf) {
		return q
	}
	if q.Equals(Inf) {
		return p
	}
	_p1 := newJacPoint(p.x, p.y, math.ONE)
	_p2 := newJacPoint(q.x, q.y, math.ONE)
	return _p1.add(_p2).conv()
}

// Double a Point on the curve
func (p *Point) Double() *Point {
	if p.Equals(Inf) {
		return Inf
	}
	return newJacPoint(p.x, p.y, math.ONE).double().conv()
}

// Mult multiplies a Point on the curve with a scalar value k using
// a Montgomery multiplication approach
func (p *Point) Mult(k *math.Int) *Point {
	return newJacPoint(p.x, p.y, math.ONE).mult(k).conv()
}

// Bytes returns a byte representation of Point (compressed or uncompressed).
func (p *Point) Bytes(compressed bool) []byte {
	if p.Equals(Inf) {
		return []byte{0}
	}
	var res []byte
	if compressed {
		rc := byte(2)
		if p.y.Bit(0) == 1 {
			rc = 3
		}
		res = append(res, rc)
		res = append(res, coordAsBytes(p.x)...)
	} else {
		res = append(res, 4)
		res = append(res, coordAsBytes(p.x)...)
		res = append(res, coordAsBytes(p.y)...)
	}
	return res
}

// JacPoint is a point on the curve that is represented internally in
// Jacobian coordinates (X,Y,Z) with "x = X/Z^2" and "y = Y/Z^3". See:
// [http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html]
type jacPoint struct { // internal Point type
	x, y, z *math.Int // using Jacobian coordinates
}

// NewJacPoint instaniates a new Point
func newJacPoint(a, b, c *math.Int) *jacPoint {
	return &jacPoint{x: a, y: b, z: c}
}

// Point at infinity
var jacInf = newJacPoint(Inf.x, Inf.y, math.ONE)

// check if a Point is at infinity
func (p *jacPoint) isInf() bool {
	return p.x.Equals(math.ZERO) && p.y.Equals(math.ZERO)
}

// convert internal Point to external representation
func (p *jacPoint) conv() *Point {
	zi := pInv(p.z)
	x := pMul(p.x, pSqr(zi))
	y := pMul(p.y, pCub(zi))
	return NewPoint(x, y)
}

// add two jacPoints on the curve
// [http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian-0/addJacition/addJac-2007-bl]
func (p *jacPoint) add(q *jacPoint) *jacPoint {
	if p.isInf() {
		return q
	}
	if q.isInf() {
		return p
	}
	z1z1 := pSqr(p.z)
	z2z2 := pSqr(q.z)
	u1 := pMul(p.x, z2z2)
	u2 := pMul(q.x, z1z1)
	s1 := pMul(pMul(p.y, q.z), z2z2)
	s2 := pMul(pMul(q.y, p.z), z1z1)
	h := pSub(u2, u1)
	i := pSqr(pMul(math.TWO, h))
	j := pMul(h, i)
	r := pMul(math.TWO, pSub(s2, s1))
	v := pMul(u1, i)
	w := pAdd(p.z, q.z)
	x := pSub(pSub(pSqr(r), j), pMul(math.TWO, v))
	y := pSub(pMul(r, pSub(v, x)), pMul(math.TWO, pMul(s1, j)))
	z := pMul(pSub(pSub(pSqr(w), z1z1), z2z2), h)
	return newJacPoint(x, y, z)
}

// double a Point on the curve
// [http://www.hyperelliptic.org/EFD/g1p/data/shortw/jacobian-0/doubling/dbl-2009-alnr]
func (p *jacPoint) double() *jacPoint {
	if p.isInf() {
		return p
	}
	a := pSqr(p.x)
	b := pSqr(p.y)
	zz := pSqr(p.z)
	c := pSqr(b)
	d := pMul(math.TWO, pSub(pSub(pSqr(p.x.Add(b)), a), c))
	e := pMul(math.THREE, a)
	f := pSqr(e)
	x := pSub(f, pMul(math.TWO, d))
	y := pSub(pMul(e, pSub(d, x)), pMul(math.EIGHT, c))
	z := pSub(pSub(pSqr(pAdd(p.y, p.z)), b), zz)
	return newJacPoint(x, y, z)
}

// Multiply a Point on the curve with a scalar value k using
// a Montgomery multiplication algorithm
func (p *jacPoint) mult(k *math.Int) *jacPoint {
	if p.isInf() {
		return p
	}
	if k.Cmp(math.ZERO) == 0 {
		return jacInf
	}
	r := jacInf
	for _, val := range k.Bytes() {
		for pos := 0; pos < 8; pos++ {
			r = r.double()
			if val&0x80 == 0x80 {
				r = p.add(r)
			}
			val <<= 1
		}
	}
	return r
}

// helper: convert coordinate to byte array of correct length
func coordAsBytes(v *math.Int) []byte {
	bv := v.Bytes()
	plen := 32 - len(bv)
	if plen == 0 {
		return bv
	}
	b := make([]byte, plen)
	return append(b, bv...)
}

// helper: reconstruct y-coordinate of Point
func computeY(x *math.Int, m uint) (y *math.Int, err error) {
	y = math.ZERO
	err = nil
	y2 := pAdd(pCub(x), c.B)
	y, err = math.SqrtModP(y2, c.P)
	if err == nil {
		if y.Bit(0) != m {
			y = c.P.Sub(y)
		}
	}
	return
}

// modulus
func nMod(a *math.Int) *math.Int {
	return a.Mod(c.N)
}

func pInv(a *math.Int) *math.Int {
	return a.ModInverse(c.P)
}

func pMul(a, b *math.Int) *math.Int {
	return a.Mul(b).Mod(c.P)
}

func pSqr(a *math.Int) *math.Int {
	return pMul(a, a)
}

func pCub(a *math.Int) *math.Int {
	return pMul(pSqr(a), a)
}

func pSub(a, b *math.Int) *math.Int {
	x := a.Sub(b)
	if x.Sign() == -1 {
		x = x.Add(c.P)
	}
	return x
}

func pAdd(a, b *math.Int) *math.Int {
	return a.Add(b).Mod(c.P)
}

func nInv(a *math.Int) *math.Int {
	return a.ModInverse(c.N)
}

func nMul(a, b *math.Int) *math.Int {
	return a.Mul(b).Mod(c.N)
}

func nRnd(a *math.Int) *math.Int {
	return math.NewIntRndRange(a, c.N)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/directconnect"

	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsDirectConnectVirtualInterface() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsDirectConnectVirtualInterfaceCreate,
		Read:   resourceAwsDirectConnectVirtualInterfaceRead,
		Delete: resourceAwsDirectConnectVirtualInterfaceDelete,

		Schema: map[string]*schema.Schema{
			"connection_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"asn": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"virtual_interface_name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"virtual_gateway_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"vlan": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"amazon_address": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"customer_address": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"auth_key": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"interface_type": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},

			"route_filter_prefixes": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				ForceNew: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},
		},
	}
}

func resourceAwsDirectConnectVirtualInterfaceCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).dcconn

	var err error
	var resp *directconnect.VirtualInterface

	if v, ok := d.GetOk("interface_type"); ok && v == "public" {

		createOpts := &directconnect.CreatePublicVirtualInterfaceInput{
			ConnectionId: aws.String(d.Get("connection_id").(string)),
			NewPublicVirtualInterface: &directconnect.NewPublicVirtualInterface{
				Asn:                  aws.Int64(int64(d.Get("asn").(int))),
				VirtualInterfaceName: aws.String(d.Get("virtual_interface_name").(string)),
				Vlan:                 aws.Int64(int64(d.Get("vlan").(int))),
				RouteFilterPrefixes:  []*directconnect.RouteFilterPrefix{},
			},
		}

		if v, ok := d.GetOk("amazon_address"); ok {
			createOpts.NewPublicVirtualInterface.AmazonAddress = aws.String(v.(string))
		}

		if v, ok := d.GetOk("auth_key"); ok {
			createOpts.NewPublicVirtualInterface.AuthKey = aws.String(v.(string))
		}

		if v, ok := d.GetOk("customer_address"); ok {
			createOpts.NewPublicVirtualInterface.CustomerAddress = aws.String(v.(string))
		}

		if prefixesSet, ok := d.Get("route_filter_prefixes").(*schema.Set); ok {

			for _, cidr := range prefixesSet.List() {
				createOpts.NewPublicVirtualInterface.RouteFilterPrefixes = append(createOpts.NewPublicVirtualInterface.RouteFilterPrefixes, &directconnect.RouteFilterPrefix{Cidr: aws.String(cidr.(string))})
			}

		}

		log.Println("[DEBUG] request structure: ", createOpts)
		// Create the DirectConnect Connection
		log.Printf("[DEBUG] Creating DirectConnect public virtual interface")
		resp, err = conn.CreatePublicVirtualInterface(createOpts)
		if err != nil {
			return fmt.Errorf("Error creating DirectConnect public virtual interface: %s", err)
		}

	} else {

		createOpts := &directconnect.CreatePrivateVirtualInterfaceInput{
			ConnectionId: aws.String(d.Get("connection_id").(string)),
			NewPrivateVirtualInterface: &directconnect.NewPrivateVirtualInterface{
				Asn:                  aws.Int64(int64(d.Get("asn").(int))),
				VirtualGatewayId:     aws.String(d.Get("virtual_gateway_id").(string)),
				VirtualInterfaceName: aws.String(d.Get("virtual_interface_name").(string)),
				Vlan:                 aws.Int64(int64(d.Get("vlan").(int))),
			},
		}

		if v, ok := d.GetOk("amazon_address"); ok {
			createOpts.NewPrivateVirtualInterface.AmazonAddress = aws.String(v.(string))
		}

		if v, ok := d.GetOk("auth_key"); ok {
			createOpts.NewPrivateVirtualInterface.AuthKey = aws.String(v.(string))
		}

		if v, ok := d.GetOk("customer_address"); ok {
			createOpts.NewPrivateVirtualInterface.CustomerAddress = aws.String(v.(string))
		}

		log.Println("[DEBUG] request structure: ", createOpts)
		// Create the DirectConnect Connection
		log.Printf("[DEBUG] Creating DirectConnect private virtual interface")
		resp, err = conn.CreatePrivateVirtualInterface(createOpts)
		if err != nil {
			return fmt.Errorf("Error creating DirectConnect connection: %s", err)
		}

	}

	// Store the ID
	VirtualInterface := resp
	d.SetId(*VirtualInterface.VirtualInterfaceId)
	log.Printf("[INFO] PrivateVirtualInterface ID: %s", *VirtualInterface.VirtualInterfaceId)

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"pending", "down"},
		Target:     []string{"available", "confirming", "verifying"},
		Refresh:    DirectConnectVirtualInterfaceRefreshFunc(conn, *VirtualInterface.VirtualInterfaceId),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 10 * time.Second,
	}

	_, stateErr := stateConf.WaitForState()
	if stateErr != nil {
		return fmt.Errorf(
			"Error waiting for DirectConnect PrivateVirtualInterface (%s) to become ready: %s",
			*VirtualInterface.VirtualInterfaceId, err)
	}

	// Read off the API to populate our RO fields.
	return resourceAwsDirectConnectVirtualInterfaceRead(d, meta)
}

func DirectConnectVirtualInterfaceRefreshFunc(conn *directconnect.DirectConnect, virtualinterfaceId string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {

		resp, err := conn.DescribeVirtualInterfaces(&directconnect.DescribeVirtualInterfacesInput{
			VirtualInterfaceId: aws.String(virtualinterfaceId),
		})

		if err != nil {

			log.Printf("Error on DirectConnectPrivateVirtualInterfaceRefresh: %s", err)
			return nil, "", err

		}

		if resp == nil || len(resp.VirtualInterfaces) == 0 {
			return nil, "", nil
		}

		virtualInterface := resp.VirtualInterfaces[0]
		return virtualInterface, *virtualInterface.VirtualInterfaceState, nil
	}
}

func resourceAwsDirectConnectVirtualInterfaceRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).dcconn

	resp, err := conn.DescribeVirtualInterfaces(&directconnect.DescribeVirtualInterfacesInput{
		VirtualInterfaceId: aws.String(d.Id()),
	})

	if err != nil {

		log.Printf("[ERROR] Error finding DirectConnect VirtualInterface: %s", err)
		return err

	}

	if len(resp.VirtualInterfaces) != 1 {
		return fmt.Errorf("[ERROR] Error finding DirectConnect VirtualInterface: %s", d.Id())
	}

	virtualInterface := resp.VirtualInterfaces[0]

	// Set attributes under the user's control.
	d.Set("connection_id", *virtualInterface.ConnectionId)
	d.Set("asn", *virtualInterface.Asn)
	d.Set("virtual_interface_name", *virtualInterface.VirtualInterfaceName)

	if v, ok := d.GetOk("interface_type"); !ok || (ok && v.(string) == "private") {
		d.Set("virtual_gateway_id", *virtualInterface.VirtualGatewayId)
	}

	d.Set("vlan", *virtualInterface.Vlan)
	d.Set("amazon_address", *virtualInterface.AmazonAddress)
	d.Set("customer_address", *virtualInterface.CustomerAddress)

	// Set read only attributes.
	d.SetId(*virtualInterface.VirtualInterfaceId)

	return nil
}

func resourceAwsDirectConnectVirtualInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).dcconn

	_, err := conn.DeleteVirtualInterface(&directconnect.DeleteVirtualInterfaceInput{
		VirtualInterfaceId: aws.String(d.Id()),
	})

	if err != nil {

		log.Printf("[ERROR] Error deleting DirectConnect VirtualInterface connection: %s", err)
		return err

	}

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"deleting"},
		Target:     []string{"deleted"},
		Refresh:    DirectConnectVirtualInterfaceRefreshFunc(conn, d.Id()),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 10 * time.Second,
	}

	_, stateErr := stateConf.WaitForState()
	if stateErr != nil {
		return fmt.Errorf(
			"Error waiting for DirectConnect VirtualInterface (%s) to delete: %s", d.Id(), err)
	}

	return nil
}
<commit_msg>Make virtual_gateway_id optional as it is not required for interface type public.<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/directconnect"

	"github.com/hashicorp/terraform/helper/hashcode"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsDirectConnectVirtualInterface() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsDirectConnectVirtualInterfaceCreate,
		Read:   resourceAwsDirectConnectVirtualInterfaceRead,
		Delete: resourceAwsDirectConnectVirtualInterfaceDelete,

		Schema: map[string]*schema.Schema{
			"connection_id": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"asn": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"virtual_interface_name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"virtual_gateway_id": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},

			"vlan": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"amazon_address": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"customer_address": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"auth_key": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},

			"interface_type": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
			},

			"route_filter_prefixes": &schema.Schema{
				Type:     schema.TypeSet,
				Optional: true,
				ForceNew: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set: func(v interface{}) int {
					return hashcode.String(v.(string))
				},
			},
		},
	}
}

func resourceAwsDirectConnectVirtualInterfaceCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).dcconn

	var err error
	var resp *directconnect.VirtualInterface

	if v, ok := d.GetOk("interface_type"); ok && v == "public" {

		createOpts := &directconnect.CreatePublicVirtualInterfaceInput{
			ConnectionId: aws.String(d.Get("connection_id").(string)),
			NewPublicVirtualInterface: &directconnect.NewPublicVirtualInterface{
				Asn:                  aws.Int64(int64(d.Get("asn").(int))),
				VirtualInterfaceName: aws.String(d.Get("virtual_interface_name").(string)),
				Vlan:                 aws.Int64(int64(d.Get("vlan").(int))),
				RouteFilterPrefixes:  []*directconnect.RouteFilterPrefix{},
			},
		}

		if v, ok := d.GetOk("amazon_address"); ok {
			createOpts.NewPublicVirtualInterface.AmazonAddress = aws.String(v.(string))
		}

		if v, ok := d.GetOk("auth_key"); ok {
			createOpts.NewPublicVirtualInterface.AuthKey = aws.String(v.(string))
		}

		if v, ok := d.GetOk("customer_address"); ok {
			createOpts.NewPublicVirtualInterface.CustomerAddress = aws.String(v.(string))
		}

		if prefixesSet, ok := d.Get("route_filter_prefixes").(*schema.Set); ok {

			for _, cidr := range prefixesSet.List() {
				createOpts.NewPublicVirtualInterface.RouteFilterPrefixes = append(createOpts.NewPublicVirtualInterface.RouteFilterPrefixes, &directconnect.RouteFilterPrefix{Cidr: aws.String(cidr.(string))})
			}

		}

		log.Println("[DEBUG] request structure: ", createOpts)
		// Create the DirectConnect Connection
		log.Printf("[DEBUG] Creating DirectConnect public virtual interface")
		resp, err = conn.CreatePublicVirtualInterface(createOpts)
		if err != nil {
			return fmt.Errorf("Error creating DirectConnect public virtual interface: %s", err)
		}

	} else {

		createOpts := &directconnect.CreatePrivateVirtualInterfaceInput{
			ConnectionId: aws.String(d.Get("connection_id").(string)),
			NewPrivateVirtualInterface: &directconnect.NewPrivateVirtualInterface{
				Asn:                  aws.Int64(int64(d.Get("asn").(int))),
				VirtualGatewayId:     aws.String(d.Get("virtual_gateway_id").(string)),
				VirtualInterfaceName: aws.String(d.Get("virtual_interface_name").(string)),
				Vlan:                 aws.Int64(int64(d.Get("vlan").(int))),
			},
		}

		if v, ok := d.GetOk("amazon_address"); ok {
			createOpts.NewPrivateVirtualInterface.AmazonAddress = aws.String(v.(string))
		}

		if v, ok := d.GetOk("auth_key"); ok {
			createOpts.NewPrivateVirtualInterface.AuthKey = aws.String(v.(string))
		}

		if v, ok := d.GetOk("customer_address"); ok {
			createOpts.NewPrivateVirtualInterface.CustomerAddress = aws.String(v.(string))
		}

		log.Println("[DEBUG] request structure: ", createOpts)
		// Create the DirectConnect Connection
		log.Printf("[DEBUG] Creating DirectConnect private virtual interface")
		resp, err = conn.CreatePrivateVirtualInterface(createOpts)
		if err != nil {
			return fmt.Errorf("Error creating DirectConnect connection: %s", err)
		}

	}

	// Store the ID
	VirtualInterface := resp
	d.SetId(*VirtualInterface.VirtualInterfaceId)
	log.Printf("[INFO] PrivateVirtualInterface ID: %s", *VirtualInterface.VirtualInterfaceId)

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"pending", "down"},
		Target:     []string{"available", "confirming", "verifying"},
		Refresh:    DirectConnectVirtualInterfaceRefreshFunc(conn, *VirtualInterface.VirtualInterfaceId),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 10 * time.Second,
	}

	_, stateErr := stateConf.WaitForState()
	if stateErr != nil {
		return fmt.Errorf(
			"Error waiting for DirectConnect PrivateVirtualInterface (%s) to become ready: %s",
			*VirtualInterface.VirtualInterfaceId, err)
	}

	// Read off the API to populate our RO fields.
	return resourceAwsDirectConnectVirtualInterfaceRead(d, meta)
}

func DirectConnectVirtualInterfaceRefreshFunc(conn *directconnect.DirectConnect, virtualinterfaceId string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {

		resp, err := conn.DescribeVirtualInterfaces(&directconnect.DescribeVirtualInterfacesInput{
			VirtualInterfaceId: aws.String(virtualinterfaceId),
		})

		if err != nil {

			log.Printf("Error on DirectConnectPrivateVirtualInterfaceRefresh: %s", err)
			return nil, "", err

		}

		if resp == nil || len(resp.VirtualInterfaces) == 0 {
			return nil, "", nil
		}

		virtualInterface := resp.VirtualInterfaces[0]
		return virtualInterface, *virtualInterface.VirtualInterfaceState, nil
	}
}

func resourceAwsDirectConnectVirtualInterfaceRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).dcconn

	resp, err := conn.DescribeVirtualInterfaces(&directconnect.DescribeVirtualInterfacesInput{
		VirtualInterfaceId: aws.String(d.Id()),
	})

	if err != nil {

		log.Printf("[ERROR] Error finding DirectConnect VirtualInterface: %s", err)
		return err

	}

	if len(resp.VirtualInterfaces) != 1 {
		return fmt.Errorf("[ERROR] Error finding DirectConnect VirtualInterface: %s", d.Id())
	}

	virtualInterface := resp.VirtualInterfaces[0]

	// Set attributes under the user's control.
	d.Set("connection_id", *virtualInterface.ConnectionId)
	d.Set("asn", *virtualInterface.Asn)
	d.Set("virtual_interface_name", *virtualInterface.VirtualInterfaceName)

	if v, ok := d.GetOk("interface_type"); !ok || (ok && v.(string) == "private") {
		d.Set("virtual_gateway_id", *virtualInterface.VirtualGatewayId)
	}

	d.Set("vlan", *virtualInterface.Vlan)
	d.Set("amazon_address", *virtualInterface.AmazonAddress)
	d.Set("customer_address", *virtualInterface.CustomerAddress)

	// Set read only attributes.
	d.SetId(*virtualInterface.VirtualInterfaceId)

	return nil
}

func resourceAwsDirectConnectVirtualInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).dcconn

	_, err := conn.DeleteVirtualInterface(&directconnect.DeleteVirtualInterfaceInput{
		VirtualInterfaceId: aws.String(d.Id()),
	})

	if err != nil {

		log.Printf("[ERROR] Error deleting DirectConnect VirtualInterface connection: %s", err)
		return err

	}

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"deleting"},
		Target:     []string{"deleted"},
		Refresh:    DirectConnectVirtualInterfaceRefreshFunc(conn, d.Id()),
		Timeout:    10 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 10 * time.Second,
	}

	_, stateErr := stateConf.WaitForState()
	if stateErr != nil {
		return fmt.Errorf(
			"Error waiting for DirectConnect VirtualInterface (%s) to delete: %s", d.Id(), err)
	}

	return nil
}
<|endoftext|>


<commit_before>package store

import (
	"encoding/json"
	"appengine"
	"appengine/blobstore"
	"appengine/datastore"
	"time"
	"sysutils"
	"models"
	"timeutils"
	"datautils"
)

func StoreUserProfile(context appengine.Context, updatedAt time.Time, userProfile models.GlukitUser) (key *datastore.Key, err error) {
	key, error := datastore.Put(context, GetUserKey(context, userProfile.Email), &userProfile)
	if error != nil {
		sysutils.Propagate(error)
	}

	return key, nil
}

func StoreReads(context appengine.Context, userProfileKey *datastore.Key, reads []models.MeterRead) (key *datastore.Key, err error) {
//	if int64(reads[0].TimeValue) > 1364792882 {
//		context.Infof("Skipping set of reads: [%s]", reads)
//	} else {

		elementKey := datastore.NewKey(context, "DayOfReads", "", int64(reads[0].TimeValue), userProfileKey)
		context.Debugf("Emitting a Put with %s key with all %d reads", elementKey, len(reads))
		context.Debugf("Putting [%s]", reads)
		key, error := datastore.Put(context, elementKey, &models.DayOfReads{reads})
		if error != nil {
			context.Criticalf("Error emitting put with key [%s] for user profile [%s]: %v", elementKey, userProfileKey, error)
			return nil, err
		}

		// Get the time of the batch's last read and update the most recent read timestamp if necessary
		userProfile, err := GetUserProfile(context, userProfileKey)
		if err != nil {
			context.Criticalf("Error reading user profile [%s] for its most recent read value: %v", userProfileKey, err)
			return nil, err
		}

		lastRead := reads[len(reads) - 1]
		if userProfile.MostRecentRead.Before(lastRead.GetTime()) {
			context.Infof("Updating most recent read date to %s", lastRead.GetTime())
			userProfile.MostRecentRead = lastRead.GetTime()
			_, err := StoreUserProfile(context, time.Now(), *userProfile)
			if err != nil {
				context.Criticalf("Error storing updated user profile [%s] with most recent read value of %s: %v", userProfileKey, userProfile.MostRecentRead, err)
				return nil, err
			}
		}

		return key, nil
//	}
//	return nil, nil
}

func StoreInjections(context appengine.Context, userProfileKey *datastore.Key, injections []models.Injection) (key[] *datastore.Key, err error) {
	elementKeys := make([] *datastore.Key, len(injections))
	for i := range injections {
		elementKeys[i] = datastore.NewKey(context, "Injection", "", int64(injections[i].TimeValue), userProfileKey)
	}

	context.Infof("Emitting a PutMulti with %d keys for all %d injections", len(elementKeys), len(injections))
	key, error := datastore.PutMulti(context, elementKeys, injections)
	if error != nil {
		context.Criticalf("Error writing %d injections with keys [%s]", len(elementKeys), elementKeys)
		return nil, error
	}

	return key, nil
}

func StoreCarbs(context appengine.Context, userProfileKey *datastore.Key, carbs []models.CarbIntake) (key[] *datastore.Key, err error) {
	elementKeys := make([] *datastore.Key, len(carbs))
	for i := range carbs {
		elementKeys[i] = datastore.NewKey(context, "CarbIntake", "", int64(carbs[i].TimeValue), userProfileKey)
	}

	context.Infof("Emitting a PutMulti with %d keys for all %d carbs", len(elementKeys), len(carbs))
	key, error := datastore.PutMulti(context, elementKeys, carbs)
	if error != nil {
		context.Criticalf("Error writing %d carbs with keys [%s]", len(elementKeys), elementKeys)
		return nil, error
	}

	return key, nil
}

func StoreExerciseData(context appengine.Context, userProfileKey *datastore.Key, exercises []models.Exercise) (key[] *datastore.Key, err error) {
	elementKeys := make([] *datastore.Key, len(exercises))
	for i := range exercises {
		elementKeys[i] = datastore.NewKey(context, "Exercise", "", int64(exercises[i].TimeValue), userProfileKey)
	}

	context.Infof("Emitting a PutMulti with %d keys for all %d exercises", len(elementKeys), len(exercises))
	key, error := datastore.PutMulti(context, elementKeys, exercises)
	if error != nil {
		context.Criticalf("Error writing %d exercises with keys [%s]", len(elementKeys), elementKeys)
		return nil, error
	}

	return key, nil
}

func FetchReadsBlob(context appengine.Context, blobKey appengine.BlobKey) (reads []models.MeterRead, err error) {
	reader := blobstore.NewReader(context, blobKey)

	decoder := json.NewDecoder(reader)
	if err := decoder.Decode(&reads); err != nil {
		return nil, err
	}

	return reads, nil
}

func FetchInjectionsBlob(context appengine.Context, blobKey appengine.BlobKey) (injections []models.Injection, err error) {
	reader := blobstore.NewReader(context, blobKey)

	decoder := json.NewDecoder(reader)
	if err := decoder.Decode(&injections); err != nil {
		return nil, err
	}

	return injections, nil
}

func FetchCarbIntakesBlob(context appengine.Context, blobKey appengine.BlobKey) (carbIntakes []models.CarbIntake, err error) {
	reader := blobstore.NewReader(context, blobKey)

	decoder := json.NewDecoder(reader)
	if err := decoder.Decode(&carbIntakes); err != nil {
		return nil, err
	}

	return carbIntakes, nil
}

func GetUserKey(context appengine.Context, email string) (key *datastore.Key) {
	return datastore.NewKey(context, "GlukitUser", email, 0, nil)
}

func GetUserProfile(context appengine.Context, key *datastore.Key) (userProfile *models.GlukitUser, err error) {
	userProfile = new(models.GlukitUser)
	context.Infof("Fetching user profile for key: %s", key.String())
	error := datastore.Get(context, key, userProfile)
	if error != nil {
		return nil, error
	}

	return userProfile, nil
}
func GetUserData(context appengine.Context, email string) (userProfile *models.GlukitUser, key *datastore.Key, reads []models.MeterRead, injections []models.Injection, carbIntakes []models.CarbIntake, err error) {
	key = GetUserKey(context, email)
	userProfile, err = GetUserProfile(context, key)
	if err != nil {
		return nil, nil, nil, nil, nil, err
	}

	var upperBound time.Time;
	if (userProfile.MostRecentRead.Hour() < 6) {
		// Rewind by one more day
		previousDay := userProfile.MostRecentRead.Add(time.Duration(-24*time.Hour))
		upperBound = time.Date(previousDay.Year(), previousDay.Month(), previousDay.Day(), 6, 0, 0, 0, timeutils.TIMEZONE_LOCATION)
	} else {
		upperBound = time.Date(userProfile.MostRecentRead.Year(), userProfile.MostRecentRead.Month(), userProfile.MostRecentRead.Day(), 6, 0, 0, 0, timeutils.TIMEZONE_LOCATION)
	}
	lowerBound := upperBound.Add(time.Duration(-24*time.Hour))

	// Scan start should be one day prior and scan end should be one day later so that we can capture the day using
	// a single column inequality filter. The scan should actually capture at least one day and a maximum of 3
	scanStart := lowerBound.Add(time.Duration(-24*time.Hour))
	scanEnd := upperBound.Add(time.Duration(24*time.Hour))

	context.Infof("Scanning for reads between %s and %s to get reads between %s and %s", scanStart, scanEnd, lowerBound, upperBound)

	readQuery := datastore.NewQuery("DayOfReads").Ancestor(key).Filter("startTime >=", scanStart).Filter("startTime <=", scanEnd).Order("startTime")
	var dayOfReads models.DayOfReads

	iterator := readQuery.Run(context)
	count := 0
	for _, err := iterator.Next(&dayOfReads); err == nil; _, err = iterator.Next(&dayOfReads) {
		batchSize := len(dayOfReads.Reads) - count
		context.Infof("Loaded batch of %d reads...", batchSize)
		count = len(dayOfReads.Reads)
	}

	filteredReads := datautils.FilterReads(dayOfReads.Reads, lowerBound, upperBound)

	if err != datastore.Done {
		sysutils.Propagate(err)
	}

	carbQuery := datastore.NewQuery("CarbIntake").Ancestor(key).Filter("timestamp >=", lowerBound.Unix()).Filter("timestamp <=", upperBound.Unix()).Order("timestamp")
	_, err = carbQuery.GetAll(context, &carbIntakes)
	if err != nil {
		return nil, nil, nil, nil, nil, err
	}
	context.Infof("Loaded %d carbs...", len(carbIntakes))

	injectionQuery := datastore.NewQuery("Injection").Ancestor(key).Filter("timestamp >=", lowerBound.Unix()).Filter("timestamp <=", upperBound.Unix()).Order("timestamp")
	_, err = injectionQuery.GetAll(context, &injections)
	if err != nil {
		return nil, nil, nil, nil, nil, err
	}
	context.Infof("Loaded %d injections...", len(injections))

	//	exercisesQuery := datastore.NewQuery("Exercise").Ancestor(key).Filter("timestamp >", lowerBound.Unix()).Filter("timestamp <", upperBound.Unix()).Order("-timestamp")
	//	_, err = exercisesQuery.GetAll(context, &exercises)
	//	if err != nil {
	//		return nil, nil, nil, nil, nil, err
	//	}
	//	context.Infof("Loaded %d exercises...", len(exercises))

	return userProfile, key, filteredReads, injections, carbIntakes, nil
}
<commit_msg>Fix minor bug in logging of an error in StoreReads.<commit_after>package store

import (
	"encoding/json"
	"appengine"
	"appengine/blobstore"
	"appengine/datastore"
	"time"
	"sysutils"
	"models"
	"timeutils"
	"datautils"
)

func StoreUserProfile(context appengine.Context, updatedAt time.Time, userProfile models.GlukitUser) (key *datastore.Key, err error) {
	key, error := datastore.Put(context, GetUserKey(context, userProfile.Email), &userProfile)
	if error != nil {
		sysutils.Propagate(error)
	}

	return key, nil
}

func StoreReads(context appengine.Context, userProfileKey *datastore.Key, reads []models.MeterRead) (key *datastore.Key, err error) {
//	if int64(reads[0].TimeValue) > 1364792882 {
//		context.Infof("Skipping set of reads: [%s]", reads)
//	} else {

		elementKey := datastore.NewKey(context, "DayOfReads", "", int64(reads[0].TimeValue), userProfileKey)
		context.Debugf("Emitting a Put with %s key with all %d reads", elementKey, len(reads))
		context.Debugf("Putting [%s]", reads)
		key, err = datastore.Put(context, elementKey, &models.DayOfReads{reads})
		if err != nil {
			context.Criticalf("Error emitting put with key [%s] for user profile [%s]: %v", elementKey, userProfileKey, err)
			return nil, err
		}

		// Get the time of the batch's last read and update the most recent read timestamp if necessary
		userProfile, err := GetUserProfile(context, userProfileKey)
		if err != nil {
			context.Criticalf("Error reading user profile [%s] for its most recent read value: %v", userProfileKey, err)
			return nil, err
		}

		lastRead := reads[len(reads) - 1]
		if userProfile.MostRecentRead.Before(lastRead.GetTime()) {
			context.Infof("Updating most recent read date to %s", lastRead.GetTime())
			userProfile.MostRecentRead = lastRead.GetTime()
			_, err := StoreUserProfile(context, time.Now(), *userProfile)
			if err != nil {
				context.Criticalf("Error storing updated user profile [%s] with most recent read value of %s: %v", userProfileKey, userProfile.MostRecentRead, err)
				return nil, err
			}
		}

		return key, nil
//	}
//	return nil, nil
}

func StoreInjections(context appengine.Context, userProfileKey *datastore.Key, injections []models.Injection) (key[] *datastore.Key, err error) {
	elementKeys := make([] *datastore.Key, len(injections))
	for i := range injections {
		elementKeys[i] = datastore.NewKey(context, "Injection", "", int64(injections[i].TimeValue), userProfileKey)
	}

	context.Infof("Emitting a PutMulti with %d keys for all %d injections", len(elementKeys), len(injections))
	key, error := datastore.PutMulti(context, elementKeys, injections)
	if error != nil {
		context.Criticalf("Error writing %d injections with keys [%s]", len(elementKeys), elementKeys)
		return nil, error
	}

	return key, nil
}

func StoreCarbs(context appengine.Context, userProfileKey *datastore.Key, carbs []models.CarbIntake) (key[] *datastore.Key, err error) {
	elementKeys := make([] *datastore.Key, len(carbs))
	for i := range carbs {
		elementKeys[i] = datastore.NewKey(context, "CarbIntake", "", int64(carbs[i].TimeValue), userProfileKey)
	}

	context.Infof("Emitting a PutMulti with %d keys for all %d carbs", len(elementKeys), len(carbs))
	key, error := datastore.PutMulti(context, elementKeys, carbs)
	if error != nil {
		context.Criticalf("Error writing %d carbs with keys [%s]", len(elementKeys), elementKeys)
		return nil, error
	}

	return key, nil
}

func StoreExerciseData(context appengine.Context, userProfileKey *datastore.Key, exercises []models.Exercise) (key[] *datastore.Key, err error) {
	elementKeys := make([] *datastore.Key, len(exercises))
	for i := range exercises {
		elementKeys[i] = datastore.NewKey(context, "Exercise", "", int64(exercises[i].TimeValue), userProfileKey)
	}

	context.Infof("Emitting a PutMulti with %d keys for all %d exercises", len(elementKeys), len(exercises))
	key, error := datastore.PutMulti(context, elementKeys, exercises)
	if error != nil {
		context.Criticalf("Error writing %d exercises with keys [%s]", len(elementKeys), elementKeys)
		return nil, error
	}

	return key, nil
}

func FetchReadsBlob(context appengine.Context, blobKey appengine.BlobKey) (reads []models.MeterRead, err error) {
	reader := blobstore.NewReader(context, blobKey)

	decoder := json.NewDecoder(reader)
	if err := decoder.Decode(&reads); err != nil {
		return nil, err
	}

	return reads, nil
}

func FetchInjectionsBlob(context appengine.Context, blobKey appengine.BlobKey) (injections []models.Injection, err error) {
	reader := blobstore.NewReader(context, blobKey)

	decoder := json.NewDecoder(reader)
	if err := decoder.Decode(&injections); err != nil {
		return nil, err
	}

	return injections, nil
}

func FetchCarbIntakesBlob(context appengine.Context, blobKey appengine.BlobKey) (carbIntakes []models.CarbIntake, err error) {
	reader := blobstore.NewReader(context, blobKey)

	decoder := json.NewDecoder(reader)
	if err := decoder.Decode(&carbIntakes); err != nil {
		return nil, err
	}

	return carbIntakes, nil
}

func GetUserKey(context appengine.Context, email string) (key *datastore.Key) {
	return datastore.NewKey(context, "GlukitUser", email, 0, nil)
}

func GetUserProfile(context appengine.Context, key *datastore.Key) (userProfile *models.GlukitUser, err error) {
	userProfile = new(models.GlukitUser)
	context.Infof("Fetching user profile for key: %s", key.String())
	error := datastore.Get(context, key, userProfile)
	if error != nil {
		return nil, error
	}

	return userProfile, nil
}
func GetUserData(context appengine.Context, email string) (userProfile *models.GlukitUser, key *datastore.Key, reads []models.MeterRead, injections []models.Injection, carbIntakes []models.CarbIntake, err error) {
	key = GetUserKey(context, email)
	userProfile, err = GetUserProfile(context, key)
	if err != nil {
		return nil, nil, nil, nil, nil, err
	}

	var upperBound time.Time;
	if (userProfile.MostRecentRead.Hour() < 6) {
		// Rewind by one more day
		previousDay := userProfile.MostRecentRead.Add(time.Duration(-24*time.Hour))
		upperBound = time.Date(previousDay.Year(), previousDay.Month(), previousDay.Day(), 6, 0, 0, 0, timeutils.TIMEZONE_LOCATION)
	} else {
		upperBound = time.Date(userProfile.MostRecentRead.Year(), userProfile.MostRecentRead.Month(), userProfile.MostRecentRead.Day(), 6, 0, 0, 0, timeutils.TIMEZONE_LOCATION)
	}
	lowerBound := upperBound.Add(time.Duration(-24*time.Hour))

	// Scan start should be one day prior and scan end should be one day later so that we can capture the day using
	// a single column inequality filter. The scan should actually capture at least one day and a maximum of 3
	scanStart := lowerBound.Add(time.Duration(-24*time.Hour))
	scanEnd := upperBound.Add(time.Duration(24*time.Hour))

	context.Infof("Scanning for reads between %s and %s to get reads between %s and %s", scanStart, scanEnd, lowerBound, upperBound)

	readQuery := datastore.NewQuery("DayOfReads").Ancestor(key).Filter("startTime >=", scanStart).Filter("startTime <=", scanEnd).Order("startTime")
	var dayOfReads models.DayOfReads

	iterator := readQuery.Run(context)
	count := 0
	for _, err := iterator.Next(&dayOfReads); err == nil; _, err = iterator.Next(&dayOfReads) {
		batchSize := len(dayOfReads.Reads) - count
		context.Infof("Loaded batch of %d reads...", batchSize)
		count = len(dayOfReads.Reads)
	}

	filteredReads := datautils.FilterReads(dayOfReads.Reads, lowerBound, upperBound)

	if err != datastore.Done {
		sysutils.Propagate(err)
	}

	carbQuery := datastore.NewQuery("CarbIntake").Ancestor(key).Filter("timestamp >=", lowerBound.Unix()).Filter("timestamp <=", upperBound.Unix()).Order("timestamp")
	_, err = carbQuery.GetAll(context, &carbIntakes)
	if err != nil {
		return nil, nil, nil, nil, nil, err
	}
	context.Infof("Loaded %d carbs...", len(carbIntakes))

	injectionQuery := datastore.NewQuery("Injection").Ancestor(key).Filter("timestamp >=", lowerBound.Unix()).Filter("timestamp <=", upperBound.Unix()).Order("timestamp")
	_, err = injectionQuery.GetAll(context, &injections)
	if err != nil {
		return nil, nil, nil, nil, nil, err
	}
	context.Infof("Loaded %d injections...", len(injections))

	//	exercisesQuery := datastore.NewQuery("Exercise").Ancestor(key).Filter("timestamp >", lowerBound.Unix()).Filter("timestamp <", upperBound.Unix()).Order("-timestamp")
	//	_, err = exercisesQuery.GetAll(context, &exercises)
	//	if err != nil {
	//		return nil, nil, nil, nil, nil, err
	//	}
	//	context.Infof("Loaded %d exercises...", len(exercises))

	return userProfile, key, filteredReads, injections, carbIntakes, nil
}
<|endoftext|>


<commit_before>package store

import (
	"bytes"
	"encoding/base32"
	"encoding/gob"
	"net/http"
	"strings"
	"code.google.com/p/gogoprotobuf/proto"

	"github.com/boltdb/bolt"
	"github.com/gorilla/securecookie"
	"github.com/gorilla/sessions"
	"github.com/yosssi/boltstore/shared"
)

// store represents a session store.
type store struct {
	codecs []securecookie.Codec
	config Config
	db     *bolt.DB
}

// Get returns a session for the given name after adding it to the registry.
//
// See gorilla/sessions FilesystemStore.Get().
func (s *store) Get(r *http.Request, name string) (*sessions.Session, error) {
	return sessions.GetRegistry(r).Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
//
// See gorilla/sessions FilesystemStore.New().
func (s *store) New(r *http.Request, name string) (*sessions.Session, error) {
	var err error
	session := sessions.NewSession(s, name)
	session.Options = &s.config.SessionOptions
	session.IsNew = true
	if c, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.codecs...)
		if err == nil {
			ok, err := s.load(session)
			session.IsNew = !(err == nil && ok) // not new if no error and data available
		}
	}
	return session, err
}

// Save adds a single session to the response.
func (s *store) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
	if session.Options.MaxAge < 0 {
		s.delete(session)
		http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options))
	} else {
		// Build an alphanumeric ID.
		if session.ID == "" {
			session.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=")
		}
		if err := s.save(session); err != nil {
			return err
		}
		encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.codecs...)
		if err != nil {
			return err
		}
		http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options))
	}
	return nil
}

// load loads a session data from the database.
// True is returned if there is a session data in the database.
func (s *store) load(session *sessions.Session) (bool, error) {
	// exists represents whether a session data exists or not.
	var exists bool
	err := s.db.View(func(tx *bolt.Tx) error {
		id := []byte(session.ID)
		bucket := tx.Bucket(s.config.DBOptions.BucketName)
		// Get the session data.
		data := bucket.Get(id)
		if data == nil {
			return nil
		}
		sessionData, err := shared.Session(data)
		if err != nil {
			return err
		}
		// Check the expiration of the session data.
		if shared.Expired(sessionData) {
			err := s.db.Update(func(txu *bolt.Tx) error {
				return txu.Bucket(s.config.DBOptions.BucketName).Delete(id)
			})
			return err
		}
		exists = true
		dec := gob.NewDecoder(bytes.NewBuffer(sessionData.Values))
		return dec.Decode(&session.Values)
	})
	return exists, err
}

// delete removes the key-value from the database.
func (s *store) delete(session *sessions.Session) error {
	err := s.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket(s.config.DBOptions.BucketName).Delete([]byte(session.ID))
	})
	if err != nil {
		return err
	}
	return nil
}

// save stores the session data in the database.
func (s *store) save(session *sessions.Session) error {
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
	err := enc.Encode(session.Values)
	if err != nil {
		return err
	}
	data, err := proto.Marshal(NewSession(buf.Bytes(), session.Options.MaxAge))
	if err != nil {
		return nil
	}
	err = s.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket(s.config.DBOptions.BucketName).Put([]byte(session.ID), data)
	})
	return err
}

// New creates and returns a session store.
func New(db *bolt.DB, config Config, keyPairs ...[]byte) (*store, error) {
	config.setDefault()
	store := &store{
		codecs: securecookie.CodecsFromPairs(keyPairs...),
		config: config,
		db:     db,
	}
	err := db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(config.DBOptions.BucketName)
		return err
	})
	if err != nil {
		return nil, err
	}
	return store, nil
}
<commit_msg>Update store.go<commit_after>package store

import (
	"bytes"
	"encoding/base32"
	"encoding/gob"
	"net/http"
	"strings"
	"code.google.com/p/gogoprotobuf/proto"

	"github.com/boltdb/bolt"
	"github.com/gorilla/securecookie"
	"github.com/gorilla/sessions"
	"github.com/yosssi/boltstore/shared"
)

// Store represents a session store.
type Store struct {
	codecs []securecookie.Codec
	config Config
	db     *bolt.DB
}

// Get returns a session for the given name after adding it to the registry.
//
// See gorilla/sessions FilesystemStore.Get().
func (s *Store) Get(r *http.Request, name string) (*sessions.Session, error) {
	return sessions.GetRegistry(r).Get(s, name)
}

// New returns a session for the given name without adding it to the registry.
//
// See gorilla/sessions FilesystemStore.New().
func (s *Store) New(r *http.Request, name string) (*sessions.Session, error) {
	var err error
	session := sessions.NewSession(s, name)
	session.Options = &s.config.SessionOptions
	session.IsNew = true
	if c, errCookie := r.Cookie(name); errCookie == nil {
		err = securecookie.DecodeMulti(name, c.Value, &session.ID, s.codecs...)
		if err == nil {
			ok, err := s.load(session)
			session.IsNew = !(err == nil && ok) // not new if no error and data available
		}
	}
	return session, err
}

// Save adds a single session to the response.
func (s *Store) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error {
	if session.Options.MaxAge < 0 {
		s.delete(session)
		http.SetCookie(w, sessions.NewCookie(session.Name(), "", session.Options))
	} else {
		// Build an alphanumeric ID.
		if session.ID == "" {
			session.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=")
		}
		if err := s.save(session); err != nil {
			return err
		}
		encoded, err := securecookie.EncodeMulti(session.Name(), session.ID, s.codecs...)
		if err != nil {
			return err
		}
		http.SetCookie(w, sessions.NewCookie(session.Name(), encoded, session.Options))
	}
	return nil
}

// load loads a session data from the database.
// True is returned if there is a session data in the database.
func (s *Store) load(session *sessions.Session) (bool, error) {
	// exists represents whether a session data exists or not.
	var exists bool
	err := s.db.View(func(tx *bolt.Tx) error {
		id := []byte(session.ID)
		bucket := tx.Bucket(s.config.DBOptions.BucketName)
		// Get the session data.
		data := bucket.Get(id)
		if data == nil {
			return nil
		}
		sessionData, err := shared.Session(data)
		if err != nil {
			return err
		}
		// Check the expiration of the session data.
		if shared.Expired(sessionData) {
			err := s.db.Update(func(txu *bolt.Tx) error {
				return txu.Bucket(s.config.DBOptions.BucketName).Delete(id)
			})
			return err
		}
		exists = true
		dec := gob.NewDecoder(bytes.NewBuffer(sessionData.Values))
		return dec.Decode(&session.Values)
	})
	return exists, err
}

// delete removes the key-value from the database.
func (s *Store) delete(session *sessions.Session) error {
	err := s.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket(s.config.DBOptions.BucketName).Delete([]byte(session.ID))
	})
	if err != nil {
		return err
	}
	return nil
}

// save stores the session data in the database.
func (s *Store) save(session *sessions.Session) error {
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
	err := enc.Encode(session.Values)
	if err != nil {
		return err
	}
	data, err := proto.Marshal(NewSession(buf.Bytes(), session.Options.MaxAge))
	if err != nil {
		return nil
	}
	err = s.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket(s.config.DBOptions.BucketName).Put([]byte(session.ID), data)
	})
	return err
}

// New creates and returns a session store.
func New(db *bolt.DB, config Config, keyPairs ...[]byte) (*Store, error) {
	config.setDefault()
	store := &Store{
		codecs: securecookie.CodecsFromPairs(keyPairs...),
		config: config,
		db:     db,
	}
	err := db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(config.DBOptions.BucketName)
		return err
	})
	if err != nil {
		return nil, err
	}
	return store, nil
}
<|endoftext|>


<commit_before>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package syslog_test

import (
	"io/ioutil"
	"path/filepath"
	"testing"

	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/log/syslog"
)

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

type SyslogConfigSuite struct {
	configDir string
}

var _ = gc.Suite(&SyslogConfigSuite{})

func (s *SyslogConfigSuite) SetUpTest(c *gc.C) {
	s.configDir = c.MkDir()
}

func (s *SyslogConfigSuite) assertRsyslogConfigPath(c *gc.C, slConfig *syslog.SyslogConfig) {
	slConfig.ConfigDir = s.configDir
	slConfig.ConfigFileName = "rsyslog.conf"
	c.Assert(slConfig.ConfigFilePath(), gc.Equals, filepath.Join(s.configDir, "rsyslog.conf"))
}

func (s *SyslogConfigSuite) assertRsyslogConfigContents(c *gc.C, slConfig *syslog.SyslogConfig,
	expectedConf string) {
	data, err := slConfig.Render()
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, expectedConf)
}

var expectedAccumulateSyslogConf = `
$ModLoad imfile

$InputFilePersistStateInterval 50
$InputFilePollInterval 5
$InputFileName /var/log/juju/some-machine.log
$InputFileTag juju-some-machine:
$InputFileStateFile some-machine
$InputRunFileMonitor

$ModLoad imudp
$UDPServerRun 8888

# Messages received from remote rsyslog machines have messages prefixed with a space,
# so add one in for local messages too if needed.
$template JujuLogFormat,"%syslogtag:6:$%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"

:syslogtag, startswith, "juju-" /var/log/juju/all-machines.log;JujuLogFormat
& ~
`

func (s *SyslogConfigSuite) TestAccumulateConfigRender(c *gc.C) {
	syslogConfigRenderer := syslog.NewAccumulateConfig("some-machine", 8888, "")
	s.assertRsyslogConfigContents(c, syslogConfigRenderer, expectedAccumulateSyslogConf)
}

func (s *SyslogConfigSuite) TestAccumulateConfigWrite(c *gc.C) {
	syslogConfigRenderer := syslog.NewAccumulateConfig("some-machine", 8888, "")
	syslogConfigRenderer.ConfigDir = s.configDir
	syslogConfigRenderer.ConfigFileName = "rsyslog.conf"
	s.assertRsyslogConfigPath(c, syslogConfigRenderer)
	err := syslogConfigRenderer.Write()
	c.Assert(err, gc.IsNil)
	syslogConfData, err := ioutil.ReadFile(syslogConfigRenderer.ConfigFilePath())
	c.Assert(err, gc.IsNil)
	c.Assert(string(syslogConfData), gc.Equals, expectedAccumulateSyslogConf)
}

var expectedAccumulateNamespaceSyslogConf = `
$ModLoad imfile

$InputFilePersistStateInterval 50
$InputFilePollInterval 5
$InputFileName /var/log/juju/some-machine.log
$InputFileTag juju-namespace-some-machine:
$InputFileStateFile some-machine-namespace
$InputRunFileMonitor

$ModLoad imudp
$UDPServerRun 8888

# Messages received from remote rsyslog machines have messages prefixed with a space,
# so add one in for local messages too if needed.
$template JujuLogFormat-namespace,"%syslogtag:16:$%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"

:syslogtag, startswith, "juju-namespace-" /var/log/juju/all-machines.log;JujuLogFormat-namespace
& ~
`

func (s *SyslogConfigSuite) TestAccumulateConfigRenderWithNamespace(c *gc.C) {
	syslogConfigRenderer := syslog.NewAccumulateConfig("some-machine", 8888, "namespace")
	s.assertRsyslogConfigContents(c, syslogConfigRenderer, expectedAccumulateNamespaceSyslogConf)
}

var expectedForwardSyslogConf = `
$ModLoad imfile

$InputFilePersistStateInterval 50
$InputFilePollInterval 5
$InputFileName /var/log/juju/some-machine.log
$InputFileTag juju-some-machine:
$InputFileStateFile some-machine
$InputRunFileMonitor

$template LongTagForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%"

:syslogtag, startswith, "juju-" @server:999;LongTagForwardFormat
& ~
`

func (s *SyslogConfigSuite) TestForwardConfigRender(c *gc.C) {
	syslogConfigRenderer := syslog.NewForwardConfig("some-machine", 999, "", []string{"server"})
	s.assertRsyslogConfigContents(c, syslogConfigRenderer, expectedForwardSyslogConf)
}

func (s *SyslogConfigSuite) TestForwardConfigWrite(c *gc.C) {
	syslogConfigRenderer := syslog.NewForwardConfig("some-machine", 999, "", []string{"server"})
	syslogConfigRenderer.ConfigDir = s.configDir
	syslogConfigRenderer.ConfigFileName = "rsyslog.conf"
	s.assertRsyslogConfigPath(c, syslogConfigRenderer)
	err := syslogConfigRenderer.Write()
	c.Assert(err, gc.IsNil)
	syslogConfData, err := ioutil.ReadFile(syslogConfigRenderer.ConfigFilePath())
	c.Assert(err, gc.IsNil)
	c.Assert(string(syslogConfData), gc.Equals, expectedForwardSyslogConf)
}
<commit_msg>Update syslog tests.<commit_after>// Copyright 2013 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package syslog_test

import (
	"io/ioutil"
	"path/filepath"
	"testing"

	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/log/syslog"
)

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

type SyslogConfigSuite struct {
	configDir string
}

var _ = gc.Suite(&SyslogConfigSuite{})

func (s *SyslogConfigSuite) SetUpTest(c *gc.C) {
	s.configDir = c.MkDir()
}

func (s *SyslogConfigSuite) assertRsyslogConfigPath(c *gc.C, slConfig *syslog.SyslogConfig) {
	slConfig.ConfigDir = s.configDir
	slConfig.ConfigFileName = "rsyslog.conf"
	c.Assert(slConfig.ConfigFilePath(), gc.Equals, filepath.Join(s.configDir, "rsyslog.conf"))
}

func (s *SyslogConfigSuite) assertRsyslogConfigContents(c *gc.C, slConfig *syslog.SyslogConfig,
	expectedConf string) {
	data, err := slConfig.Render()
	c.Assert(err, gc.IsNil)
	c.Assert(string(data), gc.Equals, expectedConf)
}

var expectedAccumulateSyslogConf = `
$ModLoad imfile

$InputFilePersistStateInterval 50
$InputFilePollInterval 5
$InputFileName /var/log/juju/some-machine.log
$InputFileTag juju-some-machine:
$InputFileStateFile some-machine
$InputRunFileMonitor

$ModLoad imudp
$UDPServerRun 8888

# Messages received from remote rsyslog machines have messages prefixed with a space,
# so add one in for local messages too if needed.
$template JujuLogFormat,"%syslogtag:6:$%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"

if $syslogtag startswith "juju-" then
  action(type="omfile"
         File="/var/log/juju/all-machines.log"
         Template="JujuLogFormat"
         FileCreateMode="0644")
& stop
`

func (s *SyslogConfigSuite) TestAccumulateConfigRender(c *gc.C) {
	syslogConfigRenderer := syslog.NewAccumulateConfig("some-machine", 8888, "")
	s.assertRsyslogConfigContents(c, syslogConfigRenderer, expectedAccumulateSyslogConf)
}

func (s *SyslogConfigSuite) TestAccumulateConfigWrite(c *gc.C) {
	syslogConfigRenderer := syslog.NewAccumulateConfig("some-machine", 8888, "")
	syslogConfigRenderer.ConfigDir = s.configDir
	syslogConfigRenderer.ConfigFileName = "rsyslog.conf"
	s.assertRsyslogConfigPath(c, syslogConfigRenderer)
	err := syslogConfigRenderer.Write()
	c.Assert(err, gc.IsNil)
	syslogConfData, err := ioutil.ReadFile(syslogConfigRenderer.ConfigFilePath())
	c.Assert(err, gc.IsNil)
	c.Assert(string(syslogConfData), gc.Equals, expectedAccumulateSyslogConf)
}

var expectedAccumulateNamespaceSyslogConf = `
$ModLoad imfile

$InputFilePersistStateInterval 50
$InputFilePollInterval 5
$InputFileName /var/log/juju/some-machine.log
$InputFileTag juju-namespace-some-machine:
$InputFileStateFile some-machine-namespace
$InputRunFileMonitor

$ModLoad imudp
$UDPServerRun 8888

# Messages received from remote rsyslog machines have messages prefixed with a space,
# so add one in for local messages too if needed.
$template JujuLogFormat-namespace,"%syslogtag:16:$%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"

if $syslogtag startswith "juju-namespace-" then
  action(type="omfile"
         File="/var/log/juju-namespace/all-machines.log"
         Template="JujuLogFormat-namespace"
         FileCreateMode="0644")
& stop
`

func (s *SyslogConfigSuite) TestAccumulateConfigRenderWithNamespace(c *gc.C) {
	syslogConfigRenderer := syslog.NewAccumulateConfig("some-machine", 8888, "namespace")
	s.assertRsyslogConfigContents(c, syslogConfigRenderer, expectedAccumulateNamespaceSyslogConf)
}

var expectedForwardSyslogConf = `
$ModLoad imfile

$InputFilePersistStateInterval 50
$InputFilePollInterval 5
$InputFileName /var/log/juju/some-machine.log
$InputFileTag juju-some-machine:
$InputFileStateFile some-machine
$InputRunFileMonitor

$template LongTagForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg%"

:syslogtag, startswith, "juju-" @server:999;LongTagForwardFormat
& ~
`

func (s *SyslogConfigSuite) TestForwardConfigRender(c *gc.C) {
	syslogConfigRenderer := syslog.NewForwardConfig("some-machine", 999, "", []string{"server"})
	s.assertRsyslogConfigContents(c, syslogConfigRenderer, expectedForwardSyslogConf)
}

func (s *SyslogConfigSuite) TestForwardConfigWrite(c *gc.C) {
	syslogConfigRenderer := syslog.NewForwardConfig("some-machine", 999, "", []string{"server"})
	syslogConfigRenderer.ConfigDir = s.configDir
	syslogConfigRenderer.ConfigFileName = "rsyslog.conf"
	s.assertRsyslogConfigPath(c, syslogConfigRenderer)
	err := syslogConfigRenderer.Write()
	c.Assert(err, gc.IsNil)
	syslogConfData, err := ioutil.ReadFile(syslogConfigRenderer.ConfigFilePath())
	c.Assert(err, gc.IsNil)
	c.Assert(string(syslogConfData), gc.Equals, expectedForwardSyslogConf)
}
<|endoftext|>


<commit_before>package protocol

// A PacketNumber in QUIC
type PacketNumber uint64

// A ConnectionID in QUIC
type ConnectionID uint64

// A StreamID in QUIC
type StreamID uint32

// An ErrorCode in QUIC
type ErrorCode uint32

// MaxPacketSize is the maximum packet size, including the public header
const MaxPacketSize = 1452

// MaxFrameSize is the maximum size of a QUIC frame
const MaxFrameSize = MaxPacketSize - (1 + 8 + 6) /*public header*/ - 1 /*private header*/ - 12 /*crypto signature*/

// DefaultTCPMSS is the default maximum packet size used in the Linux TCP implementation.
// Used in QUIC for congestion window computations in bytes.
const DefaultTCPMSS = 1460

// InitialCongestionWindow is the initial congestion window in QUIC packets
const InitialCongestionWindow = 32

// MaxCongestionWindow is the maximum size of the CWND, in packets.
const MaxCongestionWindow PacketNumber = 200
<commit_msg>add some protocol constants for congestion<commit_after>package protocol

// A PacketNumber in QUIC
type PacketNumber uint64

// A ConnectionID in QUIC
type ConnectionID uint64

// A StreamID in QUIC
type StreamID uint32

// An ErrorCode in QUIC
type ErrorCode uint32

// MaxPacketSize is the maximum packet size, including the public header
const MaxPacketSize = 1452

// MaxFrameSize is the maximum size of a QUIC frame
const MaxFrameSize = MaxPacketSize - (1 + 8 + 6) /*public header*/ - 1 /*private header*/ - 12 /*crypto signature*/

// DefaultTCPMSS is the default maximum packet size used in the Linux TCP implementation.
// Used in QUIC for congestion window computations in bytes.
const DefaultTCPMSS = 1460

// InitialCongestionWindow is the initial congestion window in QUIC packets
const InitialCongestionWindow PacketNumber = 32

// MaxCongestionWindow is the maximum size of the CWND, in packets.
// TODO: Unused?
const MaxCongestionWindow PacketNumber = 200

// DefaultMaxCongestionWindow is the default for the max congestion window
// Taken from Chrome
const DefaultMaxCongestionWindow PacketNumber = 107
<|endoftext|>