<commit_before>package agent

import (
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"path/filepath"
	"strings"
	"time"

	"github.com/fnproject/fn/api/agent/drivers"
	"github.com/fnproject/fn/api/common"
	"github.com/fnproject/fn/api/id"
	"github.com/fnproject/fn/api/models"
	"github.com/sirupsen/logrus"
	"go.opencensus.io/trace"
)

type Call interface {
	// Model will return the underlying models.Call configuration for this call.
	// TODO we could respond to async correctly from agent but layering, this
	// is only because the front end has different responses based on call type.
	// try to discourage use elsewhere until this gets pushed down more...
	Model() *models.Call

	// Start will be called before this call is executed, it may be used to
	// guarantee mutual exclusion, check docker permissions, update timestamps,
	// etc.
	// TODO Start and End can likely be unexported as they are only used in the agent,
	// and on a type which is constructed in a specific agent. meh.
	Start(ctx context.Context) error

	// End will be called immediately after attempting a call execution,
	// regardless of whether the execution failed or not. An error will be passed
	// to End, which if nil indicates a successful execution. Any error returned
	// from End will be returned as the error from Submit.
	End(ctx context.Context, err error) error
}

// Interceptor in GetCall
type CallOverrider func(*models.Call, map[string]string) (map[string]string, error)

// TODO build w/o closures... lazy
type CallOpt func(c *call) error

// Sets up a call from an http trigger request
func FromHTTPFnRequest(app *models.App, fn *models.Fn, req *http.Request) CallOpt {
	return func(c *call) error {
		id := id.New().String()

		var syslogURL string
		if app.SyslogURL != nil {
			syslogURL = *app.SyslogURL
		}

		c.Call = &models.Call{
			ID:    id,
			Image: fn.Image,
			// Delay: 0,
			Type: models.TypeSync,
			// Payload: TODO,
			Priority:    new(int32), // TODO this is crucial, apparently
			Timeout:     fn.Timeout,
			IdleTimeout: fn.IdleTimeout,
			TmpFsSize:   0, // TODO clean up this
			Memory:      fn.Memory,
			CPUs:        0, // TODO clean up this
			Config:      buildConfig(app, fn),
			// TODO - this wasn't really the intention here (that annotations would naturally cascade
			// but seems to be necessary for some runner behaviour
			Annotations: app.Annotations.MergeChange(fn.Annotations),
			Headers:     req.Header,
			CreatedAt:   common.DateTime(time.Now()),
			URL:         reqURL(req),
			Method:      req.Method,
			AppID:       app.ID,
			AppName:     app.Name,
			FnID:        fn.ID,
			SyslogURL:   syslogURL,
		}

		c.req = req
		return nil
	}
}

func buildConfig(app *models.App, fn *models.Fn) models.Config {
	conf := make(models.Config, 8+len(app.Config)+len(fn.Config))
	for k, v := range app.Config {
		conf[k] = v
	}
	for k, v := range fn.Config {
		conf[k] = v
	}

	// XXX(reed): add trigger id to request headers on call?

	conf["FN_MEMORY"] = fmt.Sprintf("%d", fn.Memory)
	conf["FN_TYPE"] = "sync"
	conf["FN_FN_ID"] = fn.ID
	conf["FN_APP_ID"] = app.ID

	return conf
}

func reqURL(req *http.Request) string {
	if req.URL.Scheme == "" {
		if req.TLS == nil {
			req.URL.Scheme = "http"
		} else {
			req.URL.Scheme = "https"
		}
	}
	if req.URL.Host == "" {
		req.URL.Host = req.Host
	}
	return req.URL.String()
}

// FromModel creates a call object from an existing stored call model object, reading the body from the stored call payload
func FromModel(mCall *models.Call) CallOpt {
	return func(c *call) error {
		c.Call = mCall

		req, err := http.NewRequest(c.Method, c.URL, strings.NewReader(c.Payload))
		if err != nil {
			return err
		}
		req.Header = c.Headers

		c.req = req
		// TODO anything else really?
		return nil
	}
}

// FromModelAndInput creates a call object from an existing stored call model object , reading the body from a provided stream
func FromModelAndInput(mCall *models.Call, in io.ReadCloser) CallOpt {
	return func(c *call) error {
		c.Call = mCall

		req, err := http.NewRequest(c.Method, c.URL, in)
		if err != nil {
			return err
		}
		req.Header = c.Headers

		c.req = req
		// TODO anything else really?
		return nil
	}
}

// WithTrigger adds trigger specific bits to a call.
// TODO consider removal, this is from a shuffle
func WithTrigger(t *models.Trigger) CallOpt {
	return func(c *call) error {
		// right now just set the trigger id
		c.TriggerID = t.ID
		return nil
	}
}

// WithWriter sets the writer that the call uses to send its output message to
// TODO this should be required
func WithWriter(w io.Writer) CallOpt {
	return func(c *call) error {
		c.w = w
		return nil
	}
}

// WithLogger sets stderr to the provided one
func WithLogger(w io.ReadWriteCloser) CallOpt {
	return func(c *call) error {
		c.stderr = w
		return nil
	}
}

// InvokeDetached mark a call to be a detached call
func InvokeDetached() CallOpt {
	return func(c *call) error {
		c.Model().Type = models.TypeDetached
		return nil
	}
}

// WithContext overrides the context on the call
func WithContext(ctx context.Context) CallOpt {
	return func(c *call) error {
		c.req = c.req.WithContext(ctx)
		return nil
	}
}

// WithExtensions adds internal attributes to the call that can be interpreted by extensions in the agent
// Pure runner can use this to pass an extension to the call
func WithExtensions(extensions map[string]string) CallOpt {
	return func(c *call) error {
		c.extensions = extensions
		return nil
	}
}

// GetCall builds a Call that can be used to submit jobs to the agent.
func (a *agent) GetCall(opts ...CallOpt) (Call, error) {
	var c call

	for _, o := range opts {
		err := o(&c)
		if err != nil {
			return nil, err
		}
	}

	// TODO typed errors to test
	if c.req == nil || c.Call == nil {
		return nil, errors.New("no model or request provided for call")
	}

	// If overrider is present, let's allow it to modify models.Call
	// and call extensions
	if a.callOverrider != nil {
		ext, err := a.callOverrider(c.Call, c.extensions)
		if err != nil {
			return nil, err
		}
		c.extensions = ext
	}

	mem := c.Memory + uint64(c.TmpFsSize)
	if !a.resources.IsResourcePossible(mem, c.CPUs) {
		return nil, models.ErrCallResourceTooBig
	}

	if c.Call.Config == nil {
		c.Call.Config = make(models.Config)
	}
	c.Call.Config["FN_LISTENER"] = "unix:" + filepath.Join(iofsDockerMountDest, udsFilename)
	c.Call.Config["FN_FORMAT"] = "http-stream" // TODO: remove this after fdk's forget what it means
	// TODO we could set type here too, for now, or anything else not based in fn/app/trigger config

	setupCtx(&c)

	c.handler = a.da
	c.ct = a
	if c.stderr == nil {
		// TODO(reed): is line writer is vulnerable to attack?
		// XXX(reed): forcing this as default is not great / configuring it isn't great either. reconsider.
		c.stderr = setupLogger(c.req.Context(), a.cfg.MaxLogSize, !a.cfg.DisableDebugUserLogs, c.Call)
	}
	if c.w == nil {
		// send STDOUT to logs if no writer given (async...)
		// TODO we could/should probably make this explicit to GetCall, ala 'WithLogger', but it's dupe code (who cares?)
		c.w = c.stderr
	}

	return &c, nil
}

func setupCtx(c *call) {
	ctx, _ := common.LoggerWithFields(c.req.Context(),
		logrus.Fields{"id": c.ID, "app_id": c.AppID, "fn_id": c.FnID})
	c.req = c.req.WithContext(ctx)
}

type call struct {
	*models.Call

	handler      CallHandler
	w            io.Writer
	req          *http.Request
	stderr       io.ReadWriteCloser
	ct           callTrigger
	slots        *slotQueue
	requestState RequestState
	slotHashId   string

	// LB & Pure Runner Extra Config
	extensions map[string]string
}

// SlotHashId returns a string identity for this call that can be used to uniquely place the call in a given container
// This should correspond to a unique identity (including data changes) of the underlying function
func (c *call) SlotHashId() string {
	return c.slotHashId
}

func (c *call) Extensions() map[string]string {
	return c.extensions
}

func (c *call) RequestBody() io.ReadCloser {
	if c.req.Body != nil && c.req.GetBody != nil {
		rdr, err := c.req.GetBody()
		if err == nil {
			return rdr
		}
	}
	return c.req.Body
}

func (c *call) ResponseWriter() http.ResponseWriter {
	return c.w.(http.ResponseWriter)
}

func (c *call) StdErr() io.ReadWriteCloser {
	return c.stderr
}

func (c *call) Model() *models.Call { return c.Call }

func (c *call) Start(ctx context.Context) error {
	ctx, span := trace.StartSpan(ctx, "agent_call_start")
	defer span.End()

	// Check context timeouts, errors
	if ctx.Err() != nil {
		return ctx.Err()
	}

	c.StartedAt = common.DateTime(time.Now())
	c.Status = "running"

	if c.Type == models.TypeAsync {
		// XXX (reed): make sure MQ reservation is lengthy. to skirt MQ semantics,
		// we could add a new message to MQ w/ delay of call.Timeout and delete the
		// old one (in that order), after marking the call as running in the db
		// (see below)

		// XXX (reed): should we store the updated started_at + status? we could
		// use this so that if we pick up a call from mq and find its status is
		// running to avoid running the call twice and potentially mark it as
		// errored (built in long running task detector, so to speak...)

		err := c.handler.Start(ctx, c.Model())
		if err != nil {
			return err // let another thread try this
		}
	}

	err := c.ct.fireBeforeCall(ctx, c.Model())
	if err != nil {
		return fmt.Errorf("BeforeCall: %v", err)
	}

	return nil
}

func (c *call) End(ctx context.Context, errIn error) error {
	ctx, span := trace.StartSpan(ctx, "agent_call_end")
	defer span.End()

	c.CompletedAt = common.DateTime(time.Now())

	switch errIn {
	case nil:
		c.Status = "success"
	case context.DeadlineExceeded:
		c.Status = "timeout"
	default:
		c.Status = "error"
		c.Error = errIn.Error()
	}

	// ensure stats histogram is reasonably bounded
	c.Call.Stats = drivers.Decimate(240, c.Call.Stats)

	if err := c.handler.Finish(ctx, c.Model(), c.stderr, c.Type == models.TypeAsync); err != nil {
		common.Logger(ctx).WithError(err).Error("error finalizing call on datastore/mq")
		// note: Not returning err here since the job could have already finished successfully.
	}

	// NOTE call this after InsertLog or the buffer will get reset
	c.stderr.Close()

	if err := c.ct.fireAfterCall(ctx, c.Model()); err != nil {
		return fmt.Errorf("AfterCall: %v", err)
	}

	return errIn // original error, important for use in sync call returns
}
<commit_msg>fn: remove error formatting in fireBeforeCall/fireAfterCall (#1317)<commit_after>package agent

import (
	"context"
	"errors"
	"fmt"
	"io"
	"net/http"
	"path/filepath"
	"strings"
	"time"

	"github.com/fnproject/fn/api/agent/drivers"
	"github.com/fnproject/fn/api/common"
	"github.com/fnproject/fn/api/id"
	"github.com/fnproject/fn/api/models"
	"github.com/sirupsen/logrus"
	"go.opencensus.io/trace"
)

type Call interface {
	// Model will return the underlying models.Call configuration for this call.
	// TODO we could respond to async correctly from agent but layering, this
	// is only because the front end has different responses based on call type.
	// try to discourage use elsewhere until this gets pushed down more...
	Model() *models.Call

	// Start will be called before this call is executed, it may be used to
	// guarantee mutual exclusion, check docker permissions, update timestamps,
	// etc.
	// TODO Start and End can likely be unexported as they are only used in the agent,
	// and on a type which is constructed in a specific agent. meh.
	Start(ctx context.Context) error

	// End will be called immediately after attempting a call execution,
	// regardless of whether the execution failed or not. An error will be passed
	// to End, which if nil indicates a successful execution. Any error returned
	// from End will be returned as the error from Submit.
	End(ctx context.Context, err error) error
}

// Interceptor in GetCall
type CallOverrider func(*models.Call, map[string]string) (map[string]string, error)

// TODO build w/o closures... lazy
type CallOpt func(c *call) error

// Sets up a call from an http trigger request
func FromHTTPFnRequest(app *models.App, fn *models.Fn, req *http.Request) CallOpt {
	return func(c *call) error {
		id := id.New().String()

		var syslogURL string
		if app.SyslogURL != nil {
			syslogURL = *app.SyslogURL
		}

		c.Call = &models.Call{
			ID:    id,
			Image: fn.Image,
			// Delay: 0,
			Type: models.TypeSync,
			// Payload: TODO,
			Priority:    new(int32), // TODO this is crucial, apparently
			Timeout:     fn.Timeout,
			IdleTimeout: fn.IdleTimeout,
			TmpFsSize:   0, // TODO clean up this
			Memory:      fn.Memory,
			CPUs:        0, // TODO clean up this
			Config:      buildConfig(app, fn),
			// TODO - this wasn't really the intention here (that annotations would naturally cascade
			// but seems to be necessary for some runner behaviour
			Annotations: app.Annotations.MergeChange(fn.Annotations),
			Headers:     req.Header,
			CreatedAt:   common.DateTime(time.Now()),
			URL:         reqURL(req),
			Method:      req.Method,
			AppID:       app.ID,
			AppName:     app.Name,
			FnID:        fn.ID,
			SyslogURL:   syslogURL,
		}

		c.req = req
		return nil
	}
}

func buildConfig(app *models.App, fn *models.Fn) models.Config {
	conf := make(models.Config, 8+len(app.Config)+len(fn.Config))
	for k, v := range app.Config {
		conf[k] = v
	}
	for k, v := range fn.Config {
		conf[k] = v
	}

	// XXX(reed): add trigger id to request headers on call?

	conf["FN_MEMORY"] = fmt.Sprintf("%d", fn.Memory)
	conf["FN_TYPE"] = "sync"
	conf["FN_FN_ID"] = fn.ID
	conf["FN_APP_ID"] = app.ID

	return conf
}

func reqURL(req *http.Request) string {
	if req.URL.Scheme == "" {
		if req.TLS == nil {
			req.URL.Scheme = "http"
		} else {
			req.URL.Scheme = "https"
		}
	}
	if req.URL.Host == "" {
		req.URL.Host = req.Host
	}
	return req.URL.String()
}

// FromModel creates a call object from an existing stored call model object, reading the body from the stored call payload
func FromModel(mCall *models.Call) CallOpt {
	return func(c *call) error {
		c.Call = mCall

		req, err := http.NewRequest(c.Method, c.URL, strings.NewReader(c.Payload))
		if err != nil {
			return err
		}
		req.Header = c.Headers

		c.req = req
		// TODO anything else really?
		return nil
	}
}

// FromModelAndInput creates a call object from an existing stored call model object , reading the body from a provided stream
func FromModelAndInput(mCall *models.Call, in io.ReadCloser) CallOpt {
	return func(c *call) error {
		c.Call = mCall

		req, err := http.NewRequest(c.Method, c.URL, in)
		if err != nil {
			return err
		}
		req.Header = c.Headers

		c.req = req
		// TODO anything else really?
		return nil
	}
}

// WithTrigger adds trigger specific bits to a call.
// TODO consider removal, this is from a shuffle
func WithTrigger(t *models.Trigger) CallOpt {
	return func(c *call) error {
		// right now just set the trigger id
		c.TriggerID = t.ID
		return nil
	}
}

// WithWriter sets the writer that the call uses to send its output message to
// TODO this should be required
func WithWriter(w io.Writer) CallOpt {
	return func(c *call) error {
		c.w = w
		return nil
	}
}

// WithLogger sets stderr to the provided one
func WithLogger(w io.ReadWriteCloser) CallOpt {
	return func(c *call) error {
		c.stderr = w
		return nil
	}
}

// InvokeDetached mark a call to be a detached call
func InvokeDetached() CallOpt {
	return func(c *call) error {
		c.Model().Type = models.TypeDetached
		return nil
	}
}

// WithContext overrides the context on the call
func WithContext(ctx context.Context) CallOpt {
	return func(c *call) error {
		c.req = c.req.WithContext(ctx)
		return nil
	}
}

// WithExtensions adds internal attributes to the call that can be interpreted by extensions in the agent
// Pure runner can use this to pass an extension to the call
func WithExtensions(extensions map[string]string) CallOpt {
	return func(c *call) error {
		c.extensions = extensions
		return nil
	}
}

// GetCall builds a Call that can be used to submit jobs to the agent.
func (a *agent) GetCall(opts ...CallOpt) (Call, error) {
	var c call

	for _, o := range opts {
		err := o(&c)
		if err != nil {
			return nil, err
		}
	}

	// TODO typed errors to test
	if c.req == nil || c.Call == nil {
		return nil, errors.New("no model or request provided for call")
	}

	// If overrider is present, let's allow it to modify models.Call
	// and call extensions
	if a.callOverrider != nil {
		ext, err := a.callOverrider(c.Call, c.extensions)
		if err != nil {
			return nil, err
		}
		c.extensions = ext
	}

	mem := c.Memory + uint64(c.TmpFsSize)
	if !a.resources.IsResourcePossible(mem, c.CPUs) {
		return nil, models.ErrCallResourceTooBig
	}

	if c.Call.Config == nil {
		c.Call.Config = make(models.Config)
	}
	c.Call.Config["FN_LISTENER"] = "unix:" + filepath.Join(iofsDockerMountDest, udsFilename)
	c.Call.Config["FN_FORMAT"] = "http-stream" // TODO: remove this after fdk's forget what it means
	// TODO we could set type here too, for now, or anything else not based in fn/app/trigger config

	setupCtx(&c)

	c.handler = a.da
	c.ct = a
	if c.stderr == nil {
		// TODO(reed): is line writer is vulnerable to attack?
		// XXX(reed): forcing this as default is not great / configuring it isn't great either. reconsider.
		c.stderr = setupLogger(c.req.Context(), a.cfg.MaxLogSize, !a.cfg.DisableDebugUserLogs, c.Call)
	}
	if c.w == nil {
		// send STDOUT to logs if no writer given (async...)
		// TODO we could/should probably make this explicit to GetCall, ala 'WithLogger', but it's dupe code (who cares?)
		c.w = c.stderr
	}

	return &c, nil
}

func setupCtx(c *call) {
	ctx, _ := common.LoggerWithFields(c.req.Context(),
		logrus.Fields{"id": c.ID, "app_id": c.AppID, "fn_id": c.FnID})
	c.req = c.req.WithContext(ctx)
}

type call struct {
	*models.Call

	handler      CallHandler
	w            io.Writer
	req          *http.Request
	stderr       io.ReadWriteCloser
	ct           callTrigger
	slots        *slotQueue
	requestState RequestState
	slotHashId   string

	// LB & Pure Runner Extra Config
	extensions map[string]string
}

// SlotHashId returns a string identity for this call that can be used to uniquely place the call in a given container
// This should correspond to a unique identity (including data changes) of the underlying function
func (c *call) SlotHashId() string {
	return c.slotHashId
}

func (c *call) Extensions() map[string]string {
	return c.extensions
}

func (c *call) RequestBody() io.ReadCloser {
	if c.req.Body != nil && c.req.GetBody != nil {
		rdr, err := c.req.GetBody()
		if err == nil {
			return rdr
		}
	}
	return c.req.Body
}

func (c *call) ResponseWriter() http.ResponseWriter {
	return c.w.(http.ResponseWriter)
}

func (c *call) StdErr() io.ReadWriteCloser {
	return c.stderr
}

func (c *call) Model() *models.Call { return c.Call }

func (c *call) Start(ctx context.Context) error {
	ctx, span := trace.StartSpan(ctx, "agent_call_start")
	defer span.End()

	// Check context timeouts, errors
	if ctx.Err() != nil {
		return ctx.Err()
	}

	c.StartedAt = common.DateTime(time.Now())
	c.Status = "running"

	if c.Type == models.TypeAsync {
		// XXX (reed): make sure MQ reservation is lengthy. to skirt MQ semantics,
		// we could add a new message to MQ w/ delay of call.Timeout and delete the
		// old one (in that order), after marking the call as running in the db
		// (see below)

		// XXX (reed): should we store the updated started_at + status? we could
		// use this so that if we pick up a call from mq and find its status is
		// running to avoid running the call twice and potentially mark it as
		// errored (built in long running task detector, so to speak...)

		err := c.handler.Start(ctx, c.Model())
		if err != nil {
			return err // let another thread try this
		}
	}

	return c.ct.fireBeforeCall(ctx, c.Model())
}

func (c *call) End(ctx context.Context, errIn error) error {
	ctx, span := trace.StartSpan(ctx, "agent_call_end")
	defer span.End()

	c.CompletedAt = common.DateTime(time.Now())

	switch errIn {
	case nil:
		c.Status = "success"
	case context.DeadlineExceeded:
		c.Status = "timeout"
	default:
		c.Status = "error"
		c.Error = errIn.Error()
	}

	// ensure stats histogram is reasonably bounded
	c.Call.Stats = drivers.Decimate(240, c.Call.Stats)

	if err := c.handler.Finish(ctx, c.Model(), c.stderr, c.Type == models.TypeAsync); err != nil {
		common.Logger(ctx).WithError(err).Error("error finalizing call on datastore/mq")
		// note: Not returning err here since the job could have already finished successfully.
	}

	// NOTE call this after InsertLog or the buffer will get reset
	c.stderr.Close()

	if err := c.ct.fireAfterCall(ctx, c.Model()); err != nil {
		return err
	}
	return errIn // original error, important for use in sync call returns
}
<|endoftext|>


<commit_before>package asset

import (
	"bytes"
	"sort"
	"time"

	"golang.org/x/net/context"

	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcutil"

	"chain/api/appdb"
	"chain/errors"
	"chain/fedchain-sandbox/hdkey"
	"chain/log"
	"chain/metrics"
)

// ErrPastExpires is returned by CreateAddress
// if the expiration time is in the past.
var ErrPastExpires = errors.New("expires in the past")

// CreateAddress uses appdb to allocate an address index for addr
// and insert it into the database.
// Fields BucketID, Amount, Expires, and IsChange must be set;
// all other fields will be initialized by CreateAddress.
// If Expires is not the zero time, but in the past,
// it returns ErrPastExpires.
func CreateAddress(ctx context.Context, addr *appdb.Address) error {
	defer metrics.RecordElapsed(time.Now())
	log.Write(ctx, "step", "create address", "in", addr.BucketID)

	if !addr.Expires.IsZero() && addr.Expires.Before(time.Now()) {
		return errors.WithDetailf(ErrPastExpires, "%s ago", time.Since(addr.Expires))
	}

	err := addr.LoadNextIndex(ctx) // get most fields from the db given BucketID
	if err != nil {
		return errors.Wrap(err, "load")
	}
	signers := Signers(addr.Keys, ReceiverPath(addr))
	addr.RedeemScript, err = redeemScript(signers, addr.SigsRequired)
	if err != nil {
		return errors.Wrap(err, "compute redeem script")
	}
	bcAddr, err := btcutil.NewAddressScriptHash(addr.RedeemScript, &chaincfg.MainNetParams)
	if err != nil {
		return errors.Wrap(err, "compute address")
	}
	addr.PKScript, err = txscript.PayToAddrScript(bcAddr)
	if err != nil {
		return errors.Wrap(err, "compute pk script")
	}
	addr.Address = bcAddr.String()
	err = addr.Insert(ctx) // sets ID and Created
	return errors.Wrap(err, "save")
}

// Signers derives a key for each item in keys, according to path.
// The returned keys will be sorted by address.
func Signers(keys []*hdkey.XKey, path []uint32) []*DerivedKey {
	var a []*DerivedKey
	for _, k := range keys {
		a = append(a, &DerivedKey{k, path, addrPubKey(k, path)})
	}
	sort.Sort(byPubKey(a))
	return a
}

// Address returns the redeem script for the given signer set
// and number of required signatures.
func redeemScript(signers []*DerivedKey, nSigReq int) ([]byte, error) {
	var addrs []*btcutil.AddressPubKey
	for _, dk := range signers {
		addrs = append(addrs, dk.Address)
	}
	return txscript.MultiSigScript(addrs, nSigReq)
}

// DerivedKey represents an EC key derived from an xpub
// and derivation path.
// TODO(kr): rename hdkey.XKey to appdb.XKey and DerivedKey to Key.
type DerivedKey struct {
	Root    *hdkey.XKey
	Path    []uint32
	Address *btcutil.AddressPubKey
}

func addrPubKey(xkey *hdkey.XKey, path []uint32) *btcutil.AddressPubKey {
	// The only error has a uniformly distributed probability of 1/2^127
	// We've decided to ignore this chance.
	key := &xkey.ExtendedKey
	for _, p := range path {
		key, _ = key.Child(p)
	}
	eckey, _ := key.ECPubKey()
	addr, _ := btcutil.NewAddressPubKey(eckey.SerializeCompressed(), &chaincfg.MainNetParams)
	return addr
}

type byPubKey []*DerivedKey

func (a byPubKey) Len() int      { return len(a) }
func (a byPubKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byPubKey) Less(i, j int) bool {
	ai := a[i].Address.ScriptAddress()
	aj := a[j].Address.ScriptAddress()
	return bytes.Compare(ai, aj) < 0
}
<commit_msg>api/asset: remove noisy log line<commit_after>package asset

import (
	"bytes"
	"sort"
	"time"

	"golang.org/x/net/context"

	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcutil"

	"chain/api/appdb"
	"chain/errors"
	"chain/fedchain-sandbox/hdkey"
	"chain/metrics"
)

// ErrPastExpires is returned by CreateAddress
// if the expiration time is in the past.
var ErrPastExpires = errors.New("expires in the past")

// CreateAddress uses appdb to allocate an address index for addr
// and insert it into the database.
// Fields BucketID, Amount, Expires, and IsChange must be set;
// all other fields will be initialized by CreateAddress.
// If Expires is not the zero time, but in the past,
// it returns ErrPastExpires.
func CreateAddress(ctx context.Context, addr *appdb.Address) error {
	defer metrics.RecordElapsed(time.Now())

	if !addr.Expires.IsZero() && addr.Expires.Before(time.Now()) {
		return errors.WithDetailf(ErrPastExpires, "%s ago", time.Since(addr.Expires))
	}

	err := addr.LoadNextIndex(ctx) // get most fields from the db given BucketID
	if err != nil {
		return errors.Wrap(err, "load")
	}
	signers := Signers(addr.Keys, ReceiverPath(addr))
	addr.RedeemScript, err = redeemScript(signers, addr.SigsRequired)
	if err != nil {
		return errors.Wrap(err, "compute redeem script")
	}
	bcAddr, err := btcutil.NewAddressScriptHash(addr.RedeemScript, &chaincfg.MainNetParams)
	if err != nil {
		return errors.Wrap(err, "compute address")
	}
	addr.PKScript, err = txscript.PayToAddrScript(bcAddr)
	if err != nil {
		return errors.Wrap(err, "compute pk script")
	}
	addr.Address = bcAddr.String()
	err = addr.Insert(ctx) // sets ID and Created
	return errors.Wrap(err, "save")
}

// Signers derives a key for each item in keys, according to path.
// The returned keys will be sorted by address.
func Signers(keys []*hdkey.XKey, path []uint32) []*DerivedKey {
	var a []*DerivedKey
	for _, k := range keys {
		a = append(a, &DerivedKey{k, path, addrPubKey(k, path)})
	}
	sort.Sort(byPubKey(a))
	return a
}

// Address returns the redeem script for the given signer set
// and number of required signatures.
func redeemScript(signers []*DerivedKey, nSigReq int) ([]byte, error) {
	var addrs []*btcutil.AddressPubKey
	for _, dk := range signers {
		addrs = append(addrs, dk.Address)
	}
	return txscript.MultiSigScript(addrs, nSigReq)
}

// DerivedKey represents an EC key derived from an xpub
// and derivation path.
// TODO(kr): rename hdkey.XKey to appdb.XKey and DerivedKey to Key.
type DerivedKey struct {
	Root    *hdkey.XKey
	Path    []uint32
	Address *btcutil.AddressPubKey
}

func addrPubKey(xkey *hdkey.XKey, path []uint32) *btcutil.AddressPubKey {
	// The only error has a uniformly distributed probability of 1/2^127
	// We've decided to ignore this chance.
	key := &xkey.ExtendedKey
	for _, p := range path {
		key, _ = key.Child(p)
	}
	eckey, _ := key.ECPubKey()
	addr, _ := btcutil.NewAddressPubKey(eckey.SerializeCompressed(), &chaincfg.MainNetParams)
	return addr
}

type byPubKey []*DerivedKey

func (a byPubKey) Len() int      { return len(a) }
func (a byPubKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byPubKey) Less(i, j int) bool {
	ai := a[i].Address.ScriptAddress()
	aj := a[j].Address.ScriptAddress()
	return bytes.Compare(ai, aj) < 0
}
<|endoftext|>


<commit_before>/*
 * Copyright 2018 Google Inc. All rights reserved.
 *
 * 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 smoke is a basic harness for testing the validity of
// config.ExtractRepo output.
package smoke

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"kythe.io/kythe/go/extractors/config"
	"kythe.io/kythe/go/platform/kindex"
)

// Tester checks the validity of config.ExtractRepo.
//
// It does this in a generic way by simply trying to determine expected output
// automatically. The current implementation is to simply check the fraction of
// files covered by extractor output.
//
// Also optionally supports indexing the extractors output.
type Tester func(ctx context.Context, repo string) (Result, error)

// Fetcher is fetches a given repo and writes it to an output directory.
type Fetcher func(ctx context.Context, repo config.Repo) error

func GitFetch(ctx context.Context, repo config.Repo) error {
	// TODO(danielmoy): strongly consider go-git instead of os.exec
	return exec.CommandContext(ctx, "git", "clone", repo.URI, repo.OutputPath).Run()
}

// Indexer takes .kindex files in a given inputDir, indexes them, and deposits
// in outputDir.
//
// TODO(danielmoy): kzip?  This is generally a thing that needs supporting in
// smoke.go and related files now that I think about it.
type Indexer func(ctx context.Context, inputDir, outputDir string) error

func EmptyIndexer(ctx context.Context, inputDir, outputDir string) error {
	return nil
}

// A Harness contains all the settings necessary to test a repository.
// All fields are optional and use defaults as specified.  Note that a default
// ConfigPath tries to use per-repository configuration files.
type Harness struct {
	Fetcher    Fetcher          // defaults to GitFetch
	Extractor  config.Extractor // defaults to config.ExtractRepo
	Indexer    Indexer          // defaults to EmptyIndexer
	ConfigPath string           // defaults to ""
}

func (o *Harness) fetcher() Fetcher {
	if o == nil || o.Fetcher == nil {
		return GitFetch
	}
	return o.Fetcher
}

func (o *Harness) extractor() config.Extractor {
	if o == nil || o.Extractor == nil {
		return config.ExtractRepo
	}
	return o.Extractor
}

func (o *Harness) indexer() Indexer {
	if o == nil || o.Indexer == nil {
		return EmptyIndexer
	}
	return o.Indexer
}

// Result is a simple container for the results of a single repo test.  It may
// contain useful information about whether or not the repo was accessible,
// extracted at all, or the extent to which we got good file coverage from the
// extraction.
//
// TODO(danielmoy): consider better metrics here. For example consider having
// the smoke test harness try to run a kythe indexer in addition to an
// extraction and see how much symbol coverage we have.  This might be out of
// scope for a simple smoke test harness though.
type Result struct {
	// Whether the repo was successfully downloaded, extracted, or indexed.
	Downloaded, Extracted, Indexed bool
	// The number of downloaded and extracted files, and the number of
	// indexed symbols.
	DownloadCount, ExtractCount, IndexCount int
	// The percentage of files in the repo that are covered by extraction.
	// Should be in range [0.0, 1.0]
	FileCoverage float64
}

func (g Harness) TestRepo(ctx context.Context, repo string) (Result, error) {
	fromRepo, err := g.filenamesFromRepo(ctx, repo)
	if err != nil {
		log.Printf("Failed to read repo from remote: %v", err)
		return Result{
			Downloaded:    false,
			Extracted:     false,
			Indexed:       false,
			DownloadCount: len(fromRepo),
		}, nil
	}

	fromExtraction, err := g.filenamesFromExtraction(ctx, repo)
	if err != nil {
		log.Printf("Failed to extract repo: %v", err)
		// TODO(danielmoy): consider handling errors independently and
		// returning separate false results if either err != nil.
		return Result{
			Downloaded:    true,
			Extracted:     false,
			Indexed:       false,
			DownloadCount: len(fromRepo),
			ExtractCount:  len(fromExtraction),
		}, nil
	}

	var coverageTotal int32
	var coverageCount int32
	for k := range fromRepo {
		coverageTotal = coverageTotal + 1
		if _, ok := fromExtraction[k]; ok {
			coverageCount = coverageCount + 1
		}
	}

	var coverage float64
	if coverageTotal > 0 {
		coverage = float64(coverageCount) / float64(coverageTotal)
	}
	return Result{
		Downloaded:    true,
		Extracted:     true,
		DownloadCount: len(fromRepo),
		ExtractCount:  len(fromExtraction),
		FileCoverage:  coverage,
	}, nil
}

func (g Harness) filenamesFromRepo(ctx context.Context, repoURI string) (map[string]bool, error) {
	repoName := pathTail(repoURI)

	repoDir, err := ioutil.TempDir("", repoName)
	if err != nil {
		return nil, fmt.Errorf("failed to create temp dir for repo %s: %v", repoURI, err)
	}
	defer os.RemoveAll(repoDir)

	if err = g.fetcher()(ctx, config.Repo{
		URI:        repoURI,
		OutputPath: repoDir,
	}); err != nil {
		return nil, err
	}

	ret := map[string]bool{}
	err = filepath.Walk(repoDir, func(path string, info os.FileInfo, err error) error {
		// TODO(danielmoy): make this parameterized based on the
		// extractor, e.g. supporting other languages.
		if err == nil && filepath.Ext(path) == ".java" {
			// We are only interested in the repo-relative path.
			rp, err := filepath.Rel(repoDir, path)
			if err != nil {
				return err
			}
			ret[rp] = true
		}
		return err
	})
	return ret, err
}

func (g Harness) filenamesFromExtraction(ctx context.Context, repoURI string) (map[string]bool, error) {
	repoName := pathTail(repoURI)
	tmpOutDir, err := ioutil.TempDir("", repoName)
	if err != nil {
		return nil, fmt.Errorf("failed to create temp dir for repo %s: %v", repoURI, err)
	}
	defer os.RemoveAll(tmpOutDir)

	if err := g.extractor()(ctx, config.Repo{
		URI:        repoURI,
		OutputPath: tmpOutDir,
		ConfigPath: g.ConfigPath,
	}); err != nil {
		return nil, err
	}
	ret := map[string]bool{}
	err = filepath.Walk(tmpOutDir, func(path string, info os.FileInfo, err error) error {
		if err == nil && filepath.Ext(path) == ".kindex" {
			cu, err := kindex.Open(ctx, path)
			if err != nil {
				return err
			}
			if cu.Proto != nil {
				for _, v := range cu.Proto.SourceFile {
					if strings.HasSuffix(v, ".java") {
						ret[v] = true
					}
				}
			}
		}
		return err
	})

	return ret, err
}

func pathTail(path string) string {
	return path[strings.LastIndex(path, "/")+1:]
}
<commit_msg>Fixing lint errors. (#79)<commit_after>/*
 * Copyright 2018 Google Inc. All rights reserved.
 *
 * 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 smoke is a basic harness for testing the validity of
// config.ExtractRepo output.
package smoke

import (
	"context"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"kythe.io/kythe/go/extractors/config"
	"kythe.io/kythe/go/platform/kindex"
)

// Tester checks the validity of config.ExtractRepo.
//
// It does this in a generic way by simply trying to determine expected output
// automatically. The current implementation is to simply check the fraction of
// files covered by extractor output.
//
// Also optionally supports indexing the extractors output.
type Tester func(ctx context.Context, repo string) (Result, error)

// Fetcher is fetches a given repo and writes it to an output directory.
type Fetcher func(ctx context.Context, repo config.Repo) error

// GitFetch fetches repos using git commandline.
func GitFetch(ctx context.Context, repo config.Repo) error {
	// TODO(danielmoy): strongly consider go-git instead of os.exec
	return exec.CommandContext(ctx, "git", "clone", repo.URI, repo.OutputPath).Run()
}

// Indexer takes .kindex files in a given inputDir, indexes them, and deposits
// in outputDir.
//
// TODO(danielmoy): kzip?  This is generally a thing that needs supporting in
// smoke.go and related files now that I think about it.
type Indexer func(ctx context.Context, inputDir, outputDir string) error

// EmptyIndexer does nothing - it is a placeholder.
func EmptyIndexer(ctx context.Context, inputDir, outputDir string) error {
	return nil
}

// A Harness contains all the settings necessary to test a repository.
// All fields are optional and use defaults as specified.  Note that a default
// ConfigPath tries to use per-repository configuration files.
type Harness struct {
	Fetcher    Fetcher          // defaults to GitFetch
	Extractor  config.Extractor // defaults to config.ExtractRepo
	Indexer    Indexer          // defaults to EmptyIndexer
	ConfigPath string           // defaults to ""
}

func (h Harness) fetcher() Fetcher {
	if h.Fetcher == nil {
		return GitFetch
	}
	return h.Fetcher
}

func (h Harness) extractor() config.Extractor {
	if h.Extractor == nil {
		return config.ExtractRepo
	}
	return h.Extractor
}

func (h Harness) indexer() Indexer {
	if h.Indexer == nil {
		return EmptyIndexer
	}
	return h.Indexer
}

// Result is a simple container for the results of a single repo test.  It may
// contain useful information about whether or not the repo was accessible,
// extracted at all, or the extent to which we got good file coverage from the
// extraction.
//
// TODO(danielmoy): consider better metrics here. For example consider having
// the smoke test harness try to run a kythe indexer in addition to an
// extraction and see how much symbol coverage we have.  This might be out of
// scope for a simple smoke test harness though.
type Result struct {
	// Whether the repo was successfully downloaded, extracted, or indexed.
	Downloaded, Extracted, Indexed bool
	// The number of downloaded and extracted files, and the number of
	// indexed symbols.
	DownloadCount, ExtractCount, IndexCount int
	// The percentage of files in the repo that are covered by extraction.
	// Should be in range [0.0, 1.0]
	FileCoverage float64
}

// TestRepo compares the result of extraction and optional indexing with
// expected output from a given repo.
func (h Harness) TestRepo(ctx context.Context, repo string) (Result, error) {
	fromRepo, err := h.filenamesFromRepo(ctx, repo)
	if err != nil {
		log.Printf("Failed to read repo from remote: %v", err)
		return Result{
			Downloaded:    false,
			Extracted:     false,
			Indexed:       false,
			DownloadCount: len(fromRepo),
		}, nil
	}

	fromExtraction, err := h.filenamesFromExtraction(ctx, repo)
	if err != nil {
		log.Printf("Failed to extract repo: %v", err)
		// TODO(danielmoy): consider handling errors independently and
		// returning separate false results if either err != nil.
		return Result{
			Downloaded:    true,
			Extracted:     false,
			Indexed:       false,
			DownloadCount: len(fromRepo),
			ExtractCount:  len(fromExtraction),
		}, nil
	}

	var coverageTotal int32
	var coverageCount int32
	for k := range fromRepo {
		coverageTotal = coverageTotal + 1
		if _, ok := fromExtraction[k]; ok {
			coverageCount = coverageCount + 1
		}
	}

	var coverage float64
	if coverageTotal > 0 {
		coverage = float64(coverageCount) / float64(coverageTotal)
	}
	return Result{
		Downloaded:    true,
		Extracted:     true,
		DownloadCount: len(fromRepo),
		ExtractCount:  len(fromExtraction),
		FileCoverage:  coverage,
	}, nil
}

func (h Harness) filenamesFromRepo(ctx context.Context, repoURI string) (map[string]bool, error) {
	repoName := pathTail(repoURI)

	repoDir, err := ioutil.TempDir("", repoName)
	if err != nil {
		return nil, fmt.Errorf("failed to create temp dir for repo %s: %v", repoURI, err)
	}
	defer os.RemoveAll(repoDir)

	if err = h.fetcher()(ctx, config.Repo{
		URI:        repoURI,
		OutputPath: repoDir,
	}); err != nil {
		return nil, err
	}

	ret := map[string]bool{}
	err = filepath.Walk(repoDir, func(path string, info os.FileInfo, err error) error {
		// TODO(danielmoy): make this parameterized based on the
		// extractor, e.g. supporting other languages.
		if err == nil && filepath.Ext(path) == ".java" {
			// We are only interested in the repo-relative path.
			rp, err := filepath.Rel(repoDir, path)
			if err != nil {
				return err
			}
			ret[rp] = true
		}
		return err
	})
	return ret, err
}

func (h Harness) filenamesFromExtraction(ctx context.Context, repoURI string) (map[string]bool, error) {
	repoName := pathTail(repoURI)
	tmpOutDir, err := ioutil.TempDir("", repoName)
	if err != nil {
		return nil, fmt.Errorf("failed to create temp dir for repo %s: %v", repoURI, err)
	}
	defer os.RemoveAll(tmpOutDir)

	if err := h.extractor()(ctx, config.Repo{
		URI:        repoURI,
		OutputPath: tmpOutDir,
		ConfigPath: h.ConfigPath,
	}); err != nil {
		return nil, err
	}
	ret := map[string]bool{}
	err = filepath.Walk(tmpOutDir, func(path string, info os.FileInfo, err error) error {
		if err == nil && filepath.Ext(path) == ".kindex" {
			cu, err := kindex.Open(ctx, path)
			if err != nil {
				return err
			}
			if cu.Proto != nil {
				for _, v := range cu.Proto.SourceFile {
					if strings.HasSuffix(v, ".java") {
						ret[v] = true
					}
				}
			}
		}
		return err
	})

	return ret, err
}

func pathTail(path string) string {
	return path[strings.LastIndex(path, "/")+1:]
}
<|endoftext|>


<commit_before>package meow-data-structures

import "sync"<commit_msg>add stack node<commit_after>package meow-data-structures

import "sync"

type meowStackNode struct {
	meowData interface{}
	meowNxt *meowStackNode
}<|endoftext|>


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

// +build darwin freebsd linux netbsd openbsd

package syscall

import (
	"runtime"
	"sync"
	"unsafe"
)

var (
	Stdin  = 0
	Stdout = 1
	Stderr = 2
)

const darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64"

func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)

// Mmap manager, for use by operating system-specific implementations.

type mmapper struct {
	sync.Mutex
	active map[*byte][]byte // active mappings; key is last byte in mapping
	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
	munmap func(addr uintptr, length uintptr) error
}

func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
	if length <= 0 {
		return nil, EINVAL
	}

	// Map the requested memory.
	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
	if errno != nil {
		return nil, errno
	}

	// Slice memory layout
	var sl = struct {
		addr uintptr
		len  int
		cap  int
	}{addr, length, length}

	// Use unsafe to turn sl into a []byte.
	b := *(*[]byte)(unsafe.Pointer(&sl))

	// Register mapping in m and return it.
	p := &b[cap(b)-1]
	m.Lock()
	defer m.Unlock()
	m.active[p] = b
	return b, nil
}

func (m *mmapper) Munmap(data []byte) (err error) {
	if len(data) == 0 || len(data) != cap(data) {
		return EINVAL
	}

	// Find the base of the mapping.
	p := &data[cap(data)-1]
	m.Lock()
	defer m.Unlock()
	b := m.active[p]
	if b == nil || &b[0] != &data[0] {
		return EINVAL
	}

	// Unmap the memory and update m.
	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
		return errno
	}
	delete(m.active, p)
	return nil
}

// An Errno is an unsigned number describing an error condition.
// It implements the error interface.  The zero Errno is by convention
// a non-error, so code to convert from Errno to error should use:
//	err = nil
//	if errno != 0 {
//		err = errno
//	}
type Errno uintptr

func (e Errno) Error() string {
	if 0 <= e && int(e) < len(errors) {
		s := errors[e]
		if s != "" {
			return s
		}
	}
	return "errno " + itoa(int(e))
}

func (e Errno) Temporary() bool {
	return e == EINTR || e == EMFILE || e.Timeout()
}

func (e Errno) Timeout() bool {
	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
}

// A Signal is a number describing a process signal.
// It implements the os.Signal interface.
type Signal int

func (s Signal) Signal() {}

func (s Signal) String() string {
	if 0 <= s && int(s) < len(signals) {
		str := signals[s]
		if str != "" {
			return str
		}
	}
	return "signal " + itoa(int(s))
}
<commit_msg>syscall: fix bounds check in Error<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin freebsd linux netbsd openbsd

package syscall

import (
	"runtime"
	"sync"
	"unsafe"
)

var (
	Stdin  = 0
	Stdout = 1
	Stderr = 2
)

const darwinAMD64 = runtime.GOOS == "darwin" && runtime.GOARCH == "amd64"

func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)

// Mmap manager, for use by operating system-specific implementations.

type mmapper struct {
	sync.Mutex
	active map[*byte][]byte // active mappings; key is last byte in mapping
	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
	munmap func(addr uintptr, length uintptr) error
}

func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
	if length <= 0 {
		return nil, EINVAL
	}

	// Map the requested memory.
	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
	if errno != nil {
		return nil, errno
	}

	// Slice memory layout
	var sl = struct {
		addr uintptr
		len  int
		cap  int
	}{addr, length, length}

	// Use unsafe to turn sl into a []byte.
	b := *(*[]byte)(unsafe.Pointer(&sl))

	// Register mapping in m and return it.
	p := &b[cap(b)-1]
	m.Lock()
	defer m.Unlock()
	m.active[p] = b
	return b, nil
}

func (m *mmapper) Munmap(data []byte) (err error) {
	if len(data) == 0 || len(data) != cap(data) {
		return EINVAL
	}

	// Find the base of the mapping.
	p := &data[cap(data)-1]
	m.Lock()
	defer m.Unlock()
	b := m.active[p]
	if b == nil || &b[0] != &data[0] {
		return EINVAL
	}

	// Unmap the memory and update m.
	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
		return errno
	}
	delete(m.active, p)
	return nil
}

// An Errno is an unsigned number describing an error condition.
// It implements the error interface.  The zero Errno is by convention
// a non-error, so code to convert from Errno to error should use:
//	err = nil
//	if errno != 0 {
//		err = errno
//	}
type Errno uintptr

func (e Errno) Error() string {
	if 0 <= int(e) && int(e) < len(errors) {
		s := errors[e]
		if s != "" {
			return s
		}
	}
	return "errno " + itoa(int(e))
}

func (e Errno) Temporary() bool {
	return e == EINTR || e == EMFILE || e.Timeout()
}

func (e Errno) Timeout() bool {
	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
}

// A Signal is a number describing a process signal.
// It implements the os.Signal interface.
type Signal int

func (s Signal) Signal() {}

func (s Signal) String() string {
	if 0 <= s && int(s) < len(signals) {
		str := signals[s]
		if str != "" {
			return str
		}
	}
	return "signal " + itoa(int(s))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

func main() {
	fmt.Println("new version")
}
<commit_msg>finish go version<commit_after>package main

import (
	"fmt"
)

func countSmaller(nums []int) []int {
	var nums2 []int

	for i, numb := range nums {
		timeCount := 0
		for ii := i; ii < len(nums); ii++ {
			if nums[ii] < numb {
				timeCount = timeCount + 1
			}
		}
		nums2 = append(nums2, timeCount)
	}

	return nums2

}

func main() {
	args := []int{5, 2, 6, 1}
	fmt.Println(countSmaller(args))
}
<|endoftext|>


<commit_before>package db

import (
	"code.cloudfoundry.org/bbs/db/sqldb/helpers"
	"code.cloudfoundry.org/bbs/guidprovider"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/locket/models"
)

//go:generate counterfeiter . LockDB
type LockDB interface {
	Lock(logger lager.Logger, resource *models.Resource, ttl int64) (*Lock, error)
	Release(logger lager.Logger, resource *models.Resource) error
	Fetch(logger lager.Logger, key string) (*Lock, error)
	FetchAndRelease(logger lager.Logger, lock *Lock) (bool, error)
	FetchAll(logger lager.Logger, lockType string) ([]*Lock, error)
	Count(logger lager.Logger, lockType string) (int, error)
}

type Lock struct {
	*models.Resource
	TtlInSeconds  int64
	ModifiedIndex int64
	ModifiedId    string
}

type SQLDB struct {
	helpers.DB
	flavor       string
	helper       helpers.SQLHelper
	guidProvider guidprovider.GUIDProvider
}

func NewSQLDB(
	db helpers.DB,
	flavor string,
	guidProvider guidprovider.GUIDProvider,
) *SQLDB {
	helper := helpers.NewSQLHelper(flavor)
	return &SQLDB{
		DB:           db,
		flavor:       flavor,
		helper:       helper,
		guidProvider: guidProvider,
	}
}
<commit_msg>Update to QueryableDB to match bbs change<commit_after>package db

import (
	"code.cloudfoundry.org/bbs/db/sqldb/helpers"
	"code.cloudfoundry.org/bbs/guidprovider"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/locket/models"
)

//go:generate counterfeiter . LockDB
type LockDB interface {
	Lock(logger lager.Logger, resource *models.Resource, ttl int64) (*Lock, error)
	Release(logger lager.Logger, resource *models.Resource) error
	Fetch(logger lager.Logger, key string) (*Lock, error)
	FetchAndRelease(logger lager.Logger, lock *Lock) (bool, error)
	FetchAll(logger lager.Logger, lockType string) ([]*Lock, error)
	Count(logger lager.Logger, lockType string) (int, error)
}

type Lock struct {
	*models.Resource
	TtlInSeconds  int64
	ModifiedIndex int64
	ModifiedId    string
}

type SQLDB struct {
	helpers.QueryableDB
	flavor       string
	helper       helpers.SQLHelper
	guidProvider guidprovider.GUIDProvider
}

func NewSQLDB(
	db helpers.QueryableDB,
	flavor string,
	guidProvider guidprovider.GUIDProvider,
) *SQLDB {
	helper := helpers.NewSQLHelper(flavor)
	return &SQLDB{
		QueryableDB:  db,
		flavor:       flavor,
		helper:       helper,
		guidProvider: guidProvider,
	}
}
<|endoftext|>


<commit_before>package web

import (
	"log"
	"net/http"
	"regexp"
	"strings"
	"sync"
)

type method int

const (
	mCONNECT method = 1 << iota
	mDELETE
	mGET
	mHEAD
	mOPTIONS
	mPATCH
	mPOST
	mPUT
	mTRACE
	// We only natively support the methods above, but we pass through other
	// methods. This constant pretty much only exists for the sake of mALL.
	mIDK

	mALL method = mCONNECT | mDELETE | mGET | mHEAD | mOPTIONS | mPATCH |
		mPOST | mPUT | mTRACE | mIDK
)

type route struct {
	// Theory: most real world routes have a string prefix which is both
	// cheap(-ish) to test against and pretty selective. And, conveniently,
	// both regexes and string patterns give us this out-of-box.
	prefix  string
	method  method
	pattern Pattern
	handler Handler
}

type router struct {
	lock     sync.Mutex
	routes   []route
	notFound Handler
}

// A pattern determines whether or not a given request matches some criteria.
// They are often used in routes, which are essentially (pattern, methodSet,
// handler) tuples. If the method and pattern match, the given handler is used.
//
// Built-in implementations of this interface are used to implement regular
// expression and string matching.
type Pattern interface {
	// In practice, most real-world routes have a string prefix that can be
	// used to quickly determine if a pattern is an eligible match. The
	// router uses the result of this function to optimize away calls to the
	// full Match function, which is likely much more expensive to compute.
	// If your Pattern does not support prefixes, this function should
	// return the empty string.
	Prefix() string
	// Returns true if the request satisfies the pattern. This function is
	// free to examine both the request and the context to make this
	// decision. After it is certain that the request matches, this function
	// should mutate or create c.UrlParams if necessary.
	Match(r *http.Request, c *C) bool
}

func parsePattern(p interface{}, isPrefix bool) Pattern {
	switch p.(type) {
	case Pattern:
		return p.(Pattern)
	case *regexp.Regexp:
		return parseRegexpPattern(p.(*regexp.Regexp))
	case string:
		return parseStringPattern(p.(string), isPrefix)
	default:
		log.Fatalf("Unknown pattern type %v. Expected a web.Pattern, "+
			"regexp.Regexp, or a string.", p)
	}
	panic("log.Fatalf does not return")
}

type netHttpWrap struct {
	http.Handler
}

func (h netHttpWrap) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.Handler.ServeHTTP(w, r)
}
func (h netHttpWrap) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	h.Handler.ServeHTTP(w, r)
}

func parseHandler(h interface{}) Handler {
	switch h.(type) {
	case Handler:
		return h.(Handler)
	case http.Handler:
		return netHttpWrap{h.(http.Handler)}
	case func(c C, w http.ResponseWriter, r *http.Request):
		f := h.(func(c C, w http.ResponseWriter, r *http.Request))
		return HandlerFunc(f)
	case func(w http.ResponseWriter, r *http.Request):
		f := h.(func(w http.ResponseWriter, r *http.Request))
		return netHttpWrap{http.HandlerFunc(f)}
	default:
		log.Fatalf("Unknown handler type %v. Expected a web.Handler, "+
			"a http.Handler, or a function with signature func(C, "+
			"http.ResponseWriter, *http.Request) or "+
			"func(http.ResponseWriter, http.Request)", h)
	}
	panic("log.Fatalf does not return")
}

func httpMethod(mname string) method {
	switch mname {
	case "CONNECT":
		return mCONNECT
	case "DELETE":
		return mDELETE
	case "GET":
		return mGET
	case "HEAD":
		return mHEAD
	case "OPTIONS":
		return mOPTIONS
	case "PATCH":
		return mPATCH
	case "POST":
		return mPOST
	case "PUT":
		return mPUT
	case "TRACE":
		return mTRACE
	default:
		return mIDK
	}
}

func (rt *router) route(c C, w http.ResponseWriter, r *http.Request) {
	m := httpMethod(r.Method)
	for _, route := range rt.routes {
		if route.method&m == 0 ||
			!strings.HasPrefix(r.URL.Path, route.prefix) ||
			!route.pattern.Match(r, &c) {
			continue
		}
		route.handler.ServeHTTPC(c, w, r)
		return
	}

	rt.notFound.ServeHTTPC(c, w, r)
}

func (rt *router) handleUntyped(p interface{}, m method, h interface{}) {
	pat := parsePattern(p, false)
	rt.handle(pat, m, parseHandler(h))
}

func (rt *router) handle(p Pattern, m method, h Handler) {
	// We're being a little sloppy here: we assume that pointer assignments
	// are atomic, and that there is no way a locked append here can affect
	// another goroutine which looked at rt.routes without a lock.
	rt.lock.Lock()
	defer rt.lock.Unlock()
	rt.routes = append(rt.routes, route{
		prefix:  p.Prefix(),
		method:  m,
		pattern: p,
		handler: h,
	})
}

// This is a bit silly, but I've renamed the method receivers in the public
// functions here "m" instead of the standard "rt", since they will eventually
// be shown on the documentation for the Mux that they are included in.

// Dispatch to the given handler when the pattern matches, regardless of HTTP
// method. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Handle(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mALL, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// CONNECT. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Connect(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mCONNECT, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// DELETE. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Delete(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mDELETE, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// GET. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Get(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mGET, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// HEAD. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Head(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mHEAD, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// OPTIONS. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Options(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mOPTIONS, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// PATCH. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Patch(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mPATCH, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// POST. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Post(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mPOST, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// PUT. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Put(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mPUT, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// TRACE. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Trace(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mTRACE, handler)
}

/*
Dispatch to the given handler when the given (Sinatra-like) pattern matches a
prefix of the path. This function explicitly takes a string parameter since you
can implement this behavior with a regular expression using the standard
Handle() function.

This function is probably most helpful when implementing sub-routing: an admin
application, for instance, can expose a single handler, and can be hooked up all
at once by attaching a sub-route at "/admin".

Notably, this function does not strip the matched prefix from downstream
handlers, so in the above example the handler would recieve requests with path
"/admin/foo/bar", for example, instead of just "/foo/bar". Luckily, this is a
problem easily surmountable by middleware.

See the documentation for type Mux for a description of what types are accepted
for handler.
*/
func (m *router) Sub(pattern string, handler interface{}) {
	pat := parsePattern(pattern, true)
	m.handle(pat, mALL, parseHandler(handler))
}

// Set the fallback (i.e., 404) handler for this mux. See the documentation for
// type Mux for a description of what types are accepted for handler.
func (m *router) NotFound(handler interface{}) {
	m.notFound = parseHandler(handler)
}
<commit_msg>Always uppercase the method<commit_after>package web

import (
	"log"
	"net/http"
	"regexp"
	"strings"
	"sync"
)

type method int

const (
	mCONNECT method = 1 << iota
	mDELETE
	mGET
	mHEAD
	mOPTIONS
	mPATCH
	mPOST
	mPUT
	mTRACE
	// We only natively support the methods above, but we pass through other
	// methods. This constant pretty much only exists for the sake of mALL.
	mIDK

	mALL method = mCONNECT | mDELETE | mGET | mHEAD | mOPTIONS | mPATCH |
		mPOST | mPUT | mTRACE | mIDK
)

type route struct {
	// Theory: most real world routes have a string prefix which is both
	// cheap(-ish) to test against and pretty selective. And, conveniently,
	// both regexes and string patterns give us this out-of-box.
	prefix  string
	method  method
	pattern Pattern
	handler Handler
}

type router struct {
	lock     sync.Mutex
	routes   []route
	notFound Handler
}

// A pattern determines whether or not a given request matches some criteria.
// They are often used in routes, which are essentially (pattern, methodSet,
// handler) tuples. If the method and pattern match, the given handler is used.
//
// Built-in implementations of this interface are used to implement regular
// expression and string matching.
type Pattern interface {
	// In practice, most real-world routes have a string prefix that can be
	// used to quickly determine if a pattern is an eligible match. The
	// router uses the result of this function to optimize away calls to the
	// full Match function, which is likely much more expensive to compute.
	// If your Pattern does not support prefixes, this function should
	// return the empty string.
	Prefix() string
	// Returns true if the request satisfies the pattern. This function is
	// free to examine both the request and the context to make this
	// decision. After it is certain that the request matches, this function
	// should mutate or create c.UrlParams if necessary.
	Match(r *http.Request, c *C) bool
}

func parsePattern(p interface{}, isPrefix bool) Pattern {
	switch p.(type) {
	case Pattern:
		return p.(Pattern)
	case *regexp.Regexp:
		return parseRegexpPattern(p.(*regexp.Regexp))
	case string:
		return parseStringPattern(p.(string), isPrefix)
	default:
		log.Fatalf("Unknown pattern type %v. Expected a web.Pattern, "+
			"regexp.Regexp, or a string.", p)
	}
	panic("log.Fatalf does not return")
}

type netHttpWrap struct {
	http.Handler
}

func (h netHttpWrap) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.Handler.ServeHTTP(w, r)
}
func (h netHttpWrap) ServeHTTPC(c C, w http.ResponseWriter, r *http.Request) {
	h.Handler.ServeHTTP(w, r)
}

func parseHandler(h interface{}) Handler {
	switch h.(type) {
	case Handler:
		return h.(Handler)
	case http.Handler:
		return netHttpWrap{h.(http.Handler)}
	case func(c C, w http.ResponseWriter, r *http.Request):
		f := h.(func(c C, w http.ResponseWriter, r *http.Request))
		return HandlerFunc(f)
	case func(w http.ResponseWriter, r *http.Request):
		f := h.(func(w http.ResponseWriter, r *http.Request))
		return netHttpWrap{http.HandlerFunc(f)}
	default:
		log.Fatalf("Unknown handler type %v. Expected a web.Handler, "+
			"a http.Handler, or a function with signature func(C, "+
			"http.ResponseWriter, *http.Request) or "+
			"func(http.ResponseWriter, http.Request)", h)
	}
	panic("log.Fatalf does not return")
}

func httpMethod(mname string) method {
	switch strings.ToUpper(mname) {
	case "CONNECT":
		return mCONNECT
	case "DELETE":
		return mDELETE
	case "GET":
		return mGET
	case "HEAD":
		return mHEAD
	case "OPTIONS":
		return mOPTIONS
	case "PATCH":
		return mPATCH
	case "POST":
		return mPOST
	case "PUT":
		return mPUT
	case "TRACE":
		return mTRACE
	default:
		return mIDK
	}
}

func (rt *router) route(c C, w http.ResponseWriter, r *http.Request) {
	m := httpMethod(r.Method)
	for _, route := range rt.routes {
		if route.method&m == 0 ||
			!strings.HasPrefix(r.URL.Path, route.prefix) ||
			!route.pattern.Match(r, &c) {
			continue
		}
		route.handler.ServeHTTPC(c, w, r)
		return
	}

	rt.notFound.ServeHTTPC(c, w, r)
}

func (rt *router) handleUntyped(p interface{}, m method, h interface{}) {
	pat := parsePattern(p, false)
	rt.handle(pat, m, parseHandler(h))
}

func (rt *router) handle(p Pattern, m method, h Handler) {
	// We're being a little sloppy here: we assume that pointer assignments
	// are atomic, and that there is no way a locked append here can affect
	// another goroutine which looked at rt.routes without a lock.
	rt.lock.Lock()
	defer rt.lock.Unlock()
	rt.routes = append(rt.routes, route{
		prefix:  p.Prefix(),
		method:  m,
		pattern: p,
		handler: h,
	})
}

// This is a bit silly, but I've renamed the method receivers in the public
// functions here "m" instead of the standard "rt", since they will eventually
// be shown on the documentation for the Mux that they are included in.

// Dispatch to the given handler when the pattern matches, regardless of HTTP
// method. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Handle(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mALL, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// CONNECT. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Connect(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mCONNECT, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// DELETE. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Delete(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mDELETE, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// GET. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Get(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mGET, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// HEAD. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Head(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mHEAD, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// OPTIONS. See the documentation for type Mux for a description of what types
// are accepted for pattern and handler.
func (m *router) Options(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mOPTIONS, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// PATCH. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Patch(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mPATCH, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// POST. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Post(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mPOST, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// PUT. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Put(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mPUT, handler)
}

// Dispatch to the given handler when the pattern matches and the HTTP method is
// TRACE. See the documentation for type Mux for a description of what types are
// accepted for pattern and handler.
func (m *router) Trace(pattern interface{}, handler interface{}) {
	m.handleUntyped(pattern, mTRACE, handler)
}

/*
Dispatch to the given handler when the given (Sinatra-like) pattern matches a
prefix of the path. This function explicitly takes a string parameter since you
can implement this behavior with a regular expression using the standard
Handle() function.

This function is probably most helpful when implementing sub-routing: an admin
application, for instance, can expose a single handler, and can be hooked up all
at once by attaching a sub-route at "/admin".

Notably, this function does not strip the matched prefix from downstream
handlers, so in the above example the handler would recieve requests with path
"/admin/foo/bar", for example, instead of just "/foo/bar". Luckily, this is a
problem easily surmountable by middleware.

See the documentation for type Mux for a description of what types are accepted
for handler.
*/
func (m *router) Sub(pattern string, handler interface{}) {
	pat := parsePattern(pattern, true)
	m.handle(pat, mALL, parseHandler(handler))
}

// Set the fallback (i.e., 404) handler for this mux. See the documentation for
// type Mux for a description of what types are accepted for handler.
func (m *router) NotFound(handler interface{}) {
	m.notFound = parseHandler(handler)
}
<|endoftext|>


<commit_before>package web

import (
	"github.com/asteris-llc/gestalt/store"
	"github.com/asteris-llc/gestalt/web/app"
	"github.com/raphael/goa"
)

// TODO: more realistic error handling

// SchemaController implements the schema resource.
type SchemaController struct {
	goa.Controller

	store *store.Store
}

// NewSchemaController creates a schema controller.
func NewSchemaController(service goa.Service, store *store.Store) app.SchemaController {
	return &SchemaController{
		Controller: service.NewController("SchemaController"),
		store:      store,
	}
}

// Create runs the create action.
func (c *SchemaController) Create(ctx *app.CreateSchemaContext) error {
	schema := app.Schema(*ctx.Payload)
	err := c.store.StoreSchema(schema.Name, &schema)
	if err != nil {
		return err
	}

	if ctx.HasSetDefaults && ctx.SetDefaults {
		err = c.store.StoreDefaultValues(schema.Name)
		if err != nil {
			return err
		}
	}

	return ctx.Created(&schema)
}

// Delete runs the delete action.
func (c *SchemaController) Delete(ctx *app.DeleteSchemaContext) error {
	if ctx.HasDeleteKeys && ctx.DeleteKeys {
		err := c.store.DeleteValues(ctx.Name)
		if err == store.ErrMissingKey {
			return ctx.NotFound()
		} else if err != nil {
			return err
		}
	}

	err := c.store.DeleteSchema(ctx.Name)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		return err
	}

	return ctx.OK([]byte{})
}

// Get runs the get action.
func (c *SchemaController) Get(ctx *app.GetSchemaContext) error {
	schema, err := c.store.RetrieveSchema(ctx.Name)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		return err
	}

	return ctx.OK(schema)
}

// List runs the list action.
func (c *SchemaController) List(ctx *app.ListSchemaContext) error {
	schemas, err := c.store.ListSchemas()
	if err != nil {
		return err
	}

	return ctx.OK(schemas)
}

// SetDefaults runs the setDefaults action.
func (c *SchemaController) SetDefaults(ctx *app.SetDefaultsSchemaContext) error {
	err := c.store.StoreDefaultValues(ctx.Name)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		return err
	}

	return ctx.OK([]byte{})
}

// Update runs the update action.
func (c *SchemaController) Update(ctx *app.UpdateSchemaContext) error {
	schema := app.Schema(*ctx.Payload)
	err := c.store.StoreSchema(schema.Name, &schema)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		return err
	}

	if ctx.HasSetDefaults && ctx.SetDefaults {
		err = c.store.StoreDefaultValues(schema.Name)
		if err == store.ErrMissingKey {
			return ctx.NotFound()
		} else if err != nil {
			return err
		}
	}

	return ctx.OK(&schema)
}
<commit_msg>web(schema): add better error handling<commit_after>package web

import (
	"github.com/asteris-llc/gestalt/store"
	"github.com/asteris-llc/gestalt/web/app"
	"github.com/raphael/goa"
)

// TODO: more realistic error handling

// SchemaController implements the schema resource.
type SchemaController struct {
	goa.Controller

	store *store.Store
}

// NewSchemaController creates a schema controller.
func NewSchemaController(service goa.Service, store *store.Store) app.SchemaController {
	return &SchemaController{
		Controller: service.NewController("SchemaController"),
		store:      store,
	}
}

// Create runs the create action.
func (c *SchemaController) Create(ctx *app.CreateSchemaContext) error {
	schema := app.Schema(*ctx.Payload)
	err := c.store.StoreSchema(schema.Name, &schema)
	if err != nil {
		ctx.Logger.Error(err.Error())
		return ctx.InternalServerError()
	}

	if ctx.HasSetDefaults && ctx.SetDefaults {
		err = c.store.StoreDefaultValues(schema.Name)
		if err != nil {
			ctx.Logger.Error(err.Error())
			return ctx.InternalServerError()
		}
	}

	return ctx.Created(&schema)
}

// Delete runs the delete action.
func (c *SchemaController) Delete(ctx *app.DeleteSchemaContext) error {
	if ctx.HasDeleteKeys && ctx.DeleteKeys {
		err := c.store.DeleteValues(ctx.Name)
		if err == store.ErrMissingKey {
			return ctx.NotFound()
		} else if err != nil {
			ctx.Logger.Error(err.Error())
			return ctx.InternalServerError()
		}
	}

	err := c.store.DeleteSchema(ctx.Name)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		ctx.Logger.Error(err.Error())
		return ctx.InternalServerError()
	}

	return ctx.OK([]byte{})
}

// Get runs the get action.
func (c *SchemaController) Get(ctx *app.GetSchemaContext) error {
	schema, err := c.store.RetrieveSchema(ctx.Name)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		ctx.Logger.Error(err.Error())
		return ctx.InternalServerError()
	}

	return ctx.OK(schema)
}

// List runs the list action.
func (c *SchemaController) List(ctx *app.ListSchemaContext) error {
	schemas, err := c.store.ListSchemas()
	if err != nil {
		ctx.Logger.Error(err.Error())
		return ctx.InternalServerError()
	}

	return ctx.OK(schemas)
}

// SetDefaults runs the setDefaults action.
func (c *SchemaController) SetDefaults(ctx *app.SetDefaultsSchemaContext) error {
	err := c.store.StoreDefaultValues(ctx.Name)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		ctx.Logger.Error(err.Error())
		return ctx.InternalServerError()
	}

	return ctx.OK([]byte{})
}

// Update runs the update action.
func (c *SchemaController) Update(ctx *app.UpdateSchemaContext) error {
	schema := app.Schema(*ctx.Payload)
	err := c.store.StoreSchema(schema.Name, &schema)
	if err == store.ErrMissingKey {
		return ctx.NotFound()
	} else if err != nil {
		ctx.Logger.Error(err.Error())
		return ctx.InternalServerError()
	}

	if ctx.HasSetDefaults && ctx.SetDefaults {
		err = c.store.StoreDefaultValues(schema.Name)
		if err == store.ErrMissingKey {
			return ctx.NotFound()
		} else if err != nil {
			ctx.Logger.Error(err.Error())
			return ctx.InternalServerError()
		}
	}

	return ctx.OK(&schema)
}
<|endoftext|>


<commit_before>package jsonerror

import (
	"fmt"
	"reflect"
	"sync"
)

// DefaultErrorFormatter represents the default formatter for displaying the collection
// of errors.
var DefaultErrorFormatter = func(i int, err error, str *string) {
	*str = fmt.Sprintf("%s\n%d:%s", *str, i, err.Error())
}

// ErrorCollection allows multiple errors to be accumulated and then returned as a single error.
// ErrorCollection can be safely used by concurrent go-routines.
type ErrorCollection struct {
	RemoveDuplicates bool
	Errors           []error
	Formatter        func(i int, err error, str *string)
	lock             sync.RWMutex
}

// Creates a new empty ErrorCollection.
// When removeDuplicates is set, any duplicate error messages are discarded
// and not appended to the collection
func NewErrorCollection(removeDuplicates ...bool) ErrorCollection {
	ec := ErrorCollection{}
	ec.Errors = []error{}
	ec.Formatter = DefaultErrorFormatter
	if len(removeDuplicates) != 0 {
		ec.RemoveDuplicates = removeDuplicates[0]
	}
	return ec
}

// Append an error to the error collection without locking
func (ec *ErrorCollection) addError(err error) {
	if ec.RemoveDuplicates {
		//Don't append if err is a duplicate
		for _, containedErr := range ec.Errors {
			if reflect.DeepEqual(containedErr, err) {
				return
			}
		}
	}
	ec.Errors = append(ec.Errors, err)
}

// Append an error to the error collection
func (ec *ErrorCollection) AddError(err error) {
	ec.lock.Lock()
	defer ec.lock.Unlock()

	ec.addError(err)
}

// Append multiple errors to the error collection
func (ec *ErrorCollection) AddErrors(errs ...error) {
	ec.lock.Lock()
	defer ec.lock.Unlock()

	for _, err := range errs {
		ec.addError(err)
	}
}

// Append an entire ErrorCollection to the receiver error collection
func (ec *ErrorCollection) AddErrorCollection(errs *ErrorCollection) {
	ec.lock.Lock()
	defer ec.lock.Unlock()

	for _, err := range errs.Errors {
		ec.addError(err)
	}
}

// Return a list of all contained errors
func (ec *ErrorCollection) Error() string {
	ec.lock.RLock()
	defer ec.lock.RUnlock()
	str := ""
	for i, err := range ec.Errors {
		if ec.Formatter != nil {
			ec.Formatter(i, err, &str)
		}
	}
	return str
}

//Struct that contains the Code, Domain, Error and Message.
//Only Code and Domain are exported to encourage usage of the New(...) method to set the message and error.
//JE is shorthand for JSONError.
type JE struct {
	Code    int
	Domain  string
	error   string
	message string
}

//Creates a new JE struct.
//Domain is optional but can be at most 1 string.
func New(code int, error string, message string, domain ...string) JE {
	if len(domain) == 0 {
		return JE{Code: code, error: error, message: message}
	} else {
		return JE{Code: code, error: error, message: message, Domain: domain[0]}
	}
}

//Generates a string that neatly formats the contents of JE struct.
//Useful with panic() because JSONError satisfies error interface.
func (j JE) Error() string {
	finalString := fmt.Sprintf("[code]: %d", j.Code)

	if j.error != "" {
		finalString = finalString + fmt.Sprintf(" [error]: %s", j.error)
	}

	if j.message != "" {
		finalString = finalString + fmt.Sprintf(" [message]: %s", j.message)
	}

	if j.Domain != "" {
		finalString = finalString + fmt.Sprintf(" [domain]: %s", j.Domain)
	}

	return finalString
}

//For use with package: "gopkg.in/unrolled/render.v1".
//Can easily output properly formatted JSON error messages for REST API services.
func (j JE) Render() map[string]string {

	if j.error == "" {
		if j.message == "" {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code)}
		} else {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code), "message": j.message}
		}
	} else {
		if j.message == "" {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code), "error": j.error}
		} else {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code), "error": j.error, "message": j.message}
		}
	}
}
<commit_msg>Minor bug fix<commit_after>package jsonerror

import (
	"fmt"
	"reflect"
	"sync"
)

// DefaultErrorFormatter represents the default formatter for displaying the collection
// of errors.
var DefaultErrorFormatter = func(i int, err error, str *string) {
	*str = fmt.Sprintf("%s\n%d:%s", *str, i, err.Error())
}

// ErrorCollection allows multiple errors to be accumulated and then returned as a single error.
// ErrorCollection can be safely used by concurrent go-routines.
type ErrorCollection struct {
	RemoveDuplicates bool
	Errors           []error
	Formatter        func(i int, err error, str *string)
	lock             sync.RWMutex
}

// Creates a new empty ErrorCollection.
// When removeDuplicates is set, any duplicate error messages are discarded
// and not appended to the collection
func NewErrorCollection(removeDuplicates ...bool) ErrorCollection {
	ec := ErrorCollection{}
	ec.Errors = []error{}
	ec.Formatter = DefaultErrorFormatter
	if len(removeDuplicates) != 0 {
		ec.RemoveDuplicates = removeDuplicates[0]
	}
	return ec
}

// Append an error to the error collection without locking
func (ec *ErrorCollection) addError(err error) {
	if ec.RemoveDuplicates {
		//Don't append if err is a duplicate
		for _, containedErr := range ec.Errors {
			if reflect.DeepEqual(containedErr, err) {
				return
			}
		}
	}
	ec.Errors = append(ec.Errors, err)
}

// Append an error to the error collection
func (ec *ErrorCollection) AddError(err error) {
	ec.lock.Lock()
	defer ec.lock.Unlock()

	ec.addError(err)
}

// Append multiple errors to the error collection
func (ec *ErrorCollection) AddErrors(errs ...error) {
	ec.lock.Lock()
	defer ec.lock.Unlock()

	for _, err := range errs {
		ec.addError(err)
	}
}

// Append an entire ErrorCollection to the receiver error collection
func (ec *ErrorCollection) AddErrorCollection(errs *ErrorCollection) {
	ec.lock.Lock()
	defer ec.lock.Unlock()

	for _, err := range errs.Errors {
		ec.addError(err)
	}
}

// Return a list of all contained errors
func (ec ErrorCollection) Error() string {
	ec.lock.RLock()
	defer ec.lock.RUnlock()
	str := ""
	for i, err := range ec.Errors {
		if ec.Formatter != nil {
			ec.Formatter(i, err, &str)
		}
	}
	return str
}

//Struct that contains the Code, Domain, Error and Message.
//Only Code and Domain are exported to encourage usage of the New(...) method to set the message and error.
//JE is shorthand for JSONError.
type JE struct {
	Code    int
	Domain  string
	error   string
	message string
}

//Creates a new JE struct.
//Domain is optional but can be at most 1 string.
func New(code int, error string, message string, domain ...string) JE {
	if len(domain) == 0 {
		return JE{Code: code, error: error, message: message}
	} else {
		return JE{Code: code, error: error, message: message, Domain: domain[0]}
	}
}

//Generates a string that neatly formats the contents of JE struct.
//Useful with panic() because JSONError satisfies error interface.
func (j JE) Error() string {
	finalString := fmt.Sprintf("[code]: %d", j.Code)

	if j.error != "" {
		finalString = finalString + fmt.Sprintf(" [error]: %s", j.error)
	}

	if j.message != "" {
		finalString = finalString + fmt.Sprintf(" [message]: %s", j.message)
	}

	if j.Domain != "" {
		finalString = finalString + fmt.Sprintf(" [domain]: %s", j.Domain)
	}

	return finalString
}

//For use with package: "gopkg.in/unrolled/render.v1".
//Can easily output properly formatted JSON error messages for REST API services.
func (j JE) Render() map[string]string {

	if j.error == "" {
		if j.message == "" {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code)}
		} else {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code), "message": j.message}
		}
	} else {
		if j.message == "" {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code), "error": j.error}
		} else {
			return map[string]string{"code": fmt.Sprintf("%d", j.Code), "error": j.error, "message": j.message}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "image/png"
    "log"
    "net/http"
    "strconv"
    "strings"
    lib "github.com/johnny-morrice/godelbrot/libgodelbrot"
)

type WebCommand string
const (
    render = WebCommand("render")
    displayImage = WebCommand("displayImage")
)

type WebRenderParams struct {
    ImageWidth uint
    ImageHeight uint
    RealMin float64
    RealMax float64
    ImagMin float64
    ImagMax float64
}

type GodelbrotPacket struct {
    Command WebCommand
    Render WebRenderParams
}

const godelbrotHeader string = "X-Godelbrot-Packet"
const godelbrotGetParam string = "godelbrotPacket"

type queueCommand uint

const (
    queueRender = queueCommand(iota)
    queueStop = queueCommand(iota)
)

type renderQueueItem struct {
    command queueCommand
    w http.ResponseWriter
    req *http.Request
    complete chan<- bool
}

func launchRenderService(desc *lib.Info) (func(http.ResponseWriter, *http.Request), chan<- renderQueueItem) {
    input := make(chan renderQueueItem)

    go handleRenderRequests(desc, input)

    return httpChanWriter(input), input
}

func httpChanWriter(input chan<- renderQueueItem) func(http.ResponseWriter, *http.Request) {
    return func (w http.ResponseWriter, req *http.Request) {
        done := make(chan bool)
        input <- renderQueueItem{
            command: queueRender,
            w: w,
            req: req,
            complete: done,
        }
        // Block until rendering is complete
        <- done
    }
}

type webservice struct {
    queueItem renderQueueItem
    desc *lib.Info
}

func handleRenderRequests(desc *lib.Info, input <-chan renderQueueItem) {
    serv := webservice{}
    serv.desc = desc

    for queue := range input {
        switch queue.command {
        case queueRender:
            serv.queueItem = queue
            serv.render()
        case queueStop:
            break
        default:
            panic(fmt.Sprintf("Unknown queueCommand: %v", queue.command))
        }
    }
}

func (serv webservice) render() {
    jsonPacket := serv.queueItem.req.URL.Query().Get(godelbrotGetParam)

    if len(jsonPacket) == 0 {
        http.Error(serv.queueItem.w, fmt.Sprintf("No data found in parameter '%v'", godelbrotHeader), 400)
        serv.queueItem.complete <- true
        return
    }

    dec := json.NewDecoder(strings.NewReader(jsonPacket))
    userPacket := GodelbrotPacket{}
    jsonError := dec.Decode(&userPacket)

    if jsonError != nil {
        http.Error(serv.queueItem.w, fmt.Sprintf("Invalid JSON packet: %v", jsonError), 400)
        serv.queueItem.complete <- true
        return
    }

    args := userPacket.Render

    if args.ImageWidth == 0 || args.ImageHeight == 0 {
        http.Error(serv.queueItem.w, "ImageHeight and ImageWidth cannot be 0", 422)
        serv.queueItem.complete <- true
        return
    }

    desc, cerr := serv.configure(args)

    if cerr != nil {
        msg := fmt.Sprintf("Error in configuration: %v", cerr)
        http.Error(serv.queueItem.w, msg, 400)
        serv.queueItem.complete <- true
        return
    }

    pic, renderError := lib.Render(desc)

    if renderError != nil {
        log.Fatal(fmt.Sprintf("Render error: %v", renderError))
    }

    buff := bytes.Buffer{}
    pngError := png.Encode(&buff, pic)

    if pngError != nil {
        http.Error(serv.queueItem.w, fmt.Sprintf("Error encoding PNG: %v", pngError), 500)
        serv.queueItem.complete <- true
        return
    }

    // Craft response
    responsePacket := GodelbrotPacket{
        Command: displayImage,
    }

    responseHeaderPacket, marshalError := json.Marshal(responsePacket)

    if marshalError != nil {
        http.Error(serv.queueItem.w, fmt.Sprintf("Error marshalling response header: %v", marshalError), 500)
        serv.queueItem.complete <- true
        return
    }

    // Respond to the request
    serv.queueItem.w.Header().Set("Content-Type", "image/png")
    serv.queueItem.w.Header().Set(godelbrotHeader, string(responseHeaderPacket))

    // Write image buffer as http response
    serv.queueItem.w.Write(buff.Bytes())

    // Notify that rendering is complete
    serv.queueItem.complete <- true
}

func (serv webservice) configure(args WebRenderParams) (*lib.Info, error) {
    req := lib.DefaultRequest()
    req.RealMin = format(args.RealMin)
    req.RealMax = format(args.RealMax)
    req.ImagMin = format(args.ImagMin)
    req.ImagMax = format(args.ImagMax)
    req.ImageWidth = args.ImageWidth
    req.ImageHeight = args.ImageHeight

    userDesc, cerr := lib.Configure(req)

    if cerr != nil {
        return nil, cerr
    }

    userDesc.NativeInfo = serv.desc.NativeInfo
    userDesc.UserRequest = *req

    return userDesc, nil
}

func format(f float64) string {
    return strconv.FormatFloat(f, 'e', -1, 64)
}<commit_msg>Properly base UserRequest on config input<commit_after>package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "image/png"
    "log"
    "net/http"
    "strconv"
    "strings"
    lib "github.com/johnny-morrice/godelbrot/libgodelbrot"
)

type WebCommand string
const (
    render = WebCommand("render")
    displayImage = WebCommand("displayImage")
)

type WebRenderParams struct {
    ImageWidth uint
    ImageHeight uint
    RealMin float64
    RealMax float64
    ImagMin float64
    ImagMax float64
}

type GodelbrotPacket struct {
    Command WebCommand
    Render WebRenderParams
}

const godelbrotHeader string = "X-Godelbrot-Packet"
const godelbrotGetParam string = "godelbrotPacket"

type queueCommand uint

const (
    queueRender = queueCommand(iota)
    queueStop = queueCommand(iota)
)

type renderQueueItem struct {
    command queueCommand
    w http.ResponseWriter
    req *http.Request
    complete chan<- bool
}

func launchRenderService(desc *lib.Info) (func(http.ResponseWriter, *http.Request), chan<- renderQueueItem) {
    input := make(chan renderQueueItem)

    go handleRenderRequests(desc, input)

    return httpChanWriter(input), input
}

func httpChanWriter(input chan<- renderQueueItem) func(http.ResponseWriter, *http.Request) {
    return func (w http.ResponseWriter, req *http.Request) {
        done := make(chan bool)
        input <- renderQueueItem{
            command: queueRender,
            w: w,
            req: req,
            complete: done,
        }
        // Block until rendering is complete
        <- done
    }
}

type webservice struct {
    queueItem renderQueueItem
    desc *lib.Info
}

func handleRenderRequests(desc *lib.Info, input <-chan renderQueueItem) {
    serv := webservice{}
    serv.desc = desc

    for queue := range input {
        switch queue.command {
        case queueRender:
            serv.queueItem = queue
            serv.render()
        case queueStop:
            break
        default:
            panic(fmt.Sprintf("Unknown queueCommand: %v", queue.command))
        }
    }
}

func (serv webservice) render() {
    jsonPacket := serv.queueItem.req.URL.Query().Get(godelbrotGetParam)

    if len(jsonPacket) == 0 {
        http.Error(serv.queueItem.w, fmt.Sprintf("No data found in parameter '%v'", godelbrotHeader), 400)
        serv.queueItem.complete <- true
        return
    }

    dec := json.NewDecoder(strings.NewReader(jsonPacket))
    userPacket := GodelbrotPacket{}
    jsonError := dec.Decode(&userPacket)

    if jsonError != nil {
        http.Error(serv.queueItem.w, fmt.Sprintf("Invalid JSON packet: %v", jsonError), 400)
        serv.queueItem.complete <- true
        return
    }

    args := userPacket.Render

    if args.ImageWidth == 0 || args.ImageHeight == 0 {
        http.Error(serv.queueItem.w, "ImageHeight and ImageWidth cannot be 0", 422)
        serv.queueItem.complete <- true
        return
    }

    desc, cerr := serv.configure(args)

    if cerr != nil {
        msg := fmt.Sprintf("Error in configuration: %v", cerr)
        http.Error(serv.queueItem.w, msg, 400)
        serv.queueItem.complete <- true
        return
    }

    pic, renderError := lib.Render(desc)

    if renderError != nil {
        log.Fatal(fmt.Sprintf("Render error: %v", renderError))
    }

    buff := bytes.Buffer{}
    pngError := png.Encode(&buff, pic)

    if pngError != nil {
        http.Error(serv.queueItem.w, fmt.Sprintf("Error encoding PNG: %v", pngError), 500)
        serv.queueItem.complete <- true
        return
    }

    // Craft response
    responsePacket := GodelbrotPacket{
        Command: displayImage,
    }

    responseHeaderPacket, marshalError := json.Marshal(responsePacket)

    if marshalError != nil {
        http.Error(serv.queueItem.w, fmt.Sprintf("Error marshalling response header: %v", marshalError), 500)
        serv.queueItem.complete <- true
        return
    }

    // Respond to the request
    serv.queueItem.w.Header().Set("Content-Type", "image/png")
    serv.queueItem.w.Header().Set(godelbrotHeader, string(responseHeaderPacket))

    // Write image buffer as http response
    serv.queueItem.w.Write(buff.Bytes())

    // Notify that rendering is complete
    serv.queueItem.complete <- true
}

func (serv webservice) configure(args WebRenderParams) (*lib.Info, error) {
    req := &serv.desc.UserRequest
    req.RealMin = format(args.RealMin)
    req.RealMax = format(args.RealMax)
    req.ImagMin = format(args.ImagMin)
    req.ImagMax = format(args.ImagMax)
    req.ImageWidth = args.ImageWidth
    req.ImageHeight = args.ImageHeight

    userDesc, cerr := lib.Configure(req)

    if cerr != nil {
        return nil, cerr
    }

    userDesc.NativeInfo = serv.desc.NativeInfo
    userDesc.UserRequest = *req

    return userDesc, nil
}

func format(f float64) string {
    return strconv.FormatFloat(f, 'e', -1, 64)
}<|endoftext|>