<commit_before>package socialmedia

import (
	"net/http"

	"github.com/vardius/go-api-boilerplate/pkg/common/http/response"
	"github.com/vardius/go-api-boilerplate/pkg/common/jwt"
	"github.com/vardius/go-api-boilerplate/pkg/common/security/identity"
	user_grpc_server "github.com/vardius/go-api-boilerplate/pkg/user/interfaces/grpc"
	user_proto "github.com/vardius/go-api-boilerplate/pkg/user/interfaces/proto"
)

type facebook struct {
	client user_proto.UserClient
	jwt    jwt.Jwt
}

func (f *facebook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	accessToken := r.FormValue("accessToken")
	data, e := getProfile(accessToken, "https://graph.facebook.com/me")
	if e != nil {
		response.WithError(r.Context(), response.HTTPError{
			Code:    http.StatusBadRequest,
			Error:   e,
			Message: "Invalid access token",
		})
		return
	}

	identity := &identity.Identity{}
	identity.FromFacebookData(data)

	token, e := f.jwt.Encode(identity)
	if e != nil {
		response.WithError(r.Context(), response.HTTPError{
			Code:    http.StatusInternalServerError,
			Error:   e,
			Message: "Generate token failure",
		})
		return
	}

	payload := &commandPayload{token, data}
	_, e = f.client.DispatchCommand(r.Context(), &user_proto.DispatchCommandRequest{
		Name:    user_grpc_server.RegisterUserWithFacebook,
		Payload: payload.toJSON(),
	})

	if e != nil {
		response.WithError(r.Context(), response.HTTPError{
			Code:    http.StatusBadRequest,
			Error:   e,
			Message: "Invalid request",
		})
		return
	}

	response.WithPayload(r.Context(), &responsePayload{token, identity})
	return
}

// NewFacebook creates facebook auth handler
func NewFacebook(c user_proto.UserClient, j jwt.Jwt) http.Handler {
	return &facebook{c, j}
}
<commit_msg>Improve naming<commit_after>package socialmedia

import (
	"net/http"

	"github.com/vardius/go-api-boilerplate/pkg/common/http/response"
	"github.com/vardius/go-api-boilerplate/pkg/common/jwt"
	"github.com/vardius/go-api-boilerplate/pkg/common/security/identity"
	user_grpc "github.com/vardius/go-api-boilerplate/pkg/user/interfaces/grpc"
	user_proto "github.com/vardius/go-api-boilerplate/pkg/user/interfaces/proto"
)

type facebook struct {
	client user_proto.UserClient
	jwt    jwt.Jwt
}

func (f *facebook) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	accessToken := r.FormValue("accessToken")
	data, e := getProfile(accessToken, "https://graph.facebook.com/me")
	if e != nil {
		response.WithError(r.Context(), response.HTTPError{
			Code:    http.StatusBadRequest,
			Error:   e,
			Message: "Invalid access token",
		})
		return
	}

	identity := &identity.Identity{}
	identity.FromFacebookData(data)

	token, e := f.jwt.Encode(identity)
	if e != nil {
		response.WithError(r.Context(), response.HTTPError{
			Code:    http.StatusInternalServerError,
			Error:   e,
			Message: "Generate token failure",
		})
		return
	}

	payload := &commandPayload{token, data}
	_, e = f.client.DispatchCommand(r.Context(), &user_proto.DispatchCommandRequest{
		Name:    user_grpc.RegisterUserWithFacebook,
		Payload: payload.toJSON(),
	})

	if e != nil {
		response.WithError(r.Context(), response.HTTPError{
			Code:    http.StatusBadRequest,
			Error:   e,
			Message: "Invalid request",
		})
		return
	}

	response.WithPayload(r.Context(), &responsePayload{token, identity})
	return
}

// NewFacebook creates facebook auth handler
func NewFacebook(c user_proto.UserClient, j jwt.Jwt) http.Handler {
	return &facebook{c, j}
}
<|endoftext|>


<commit_before>package test

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"strings"

	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/config/configfile"
	"github.com/docker/cli/cli/context/docker"
	"github.com/docker/cli/cli/context/store"
	manifeststore "github.com/docker/cli/cli/manifest/store"
	registryclient "github.com/docker/cli/cli/registry/client"
	"github.com/docker/cli/cli/streams"
	"github.com/docker/cli/cli/trust"
	"github.com/docker/docker/client"
	notaryclient "github.com/theupdateframework/notary/client"
)

// NotaryClientFuncType defines a function that returns a fake notary client
type NotaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
type clientInfoFuncType func() command.ClientInfo

// FakeCli emulates the default DockerCli
type FakeCli struct {
	command.DockerCli
	client           client.APIClient
	configfile       *configfile.ConfigFile
	out              *streams.Out
	outBuffer        *bytes.Buffer
	err              *bytes.Buffer
	in               *streams.In
	server           command.ServerInfo
	clientInfoFunc   clientInfoFuncType
	notaryClientFunc NotaryClientFuncType
	manifestStore    manifeststore.Store
	registryClient   registryclient.RegistryClient
	contentTrust     bool
	contextStore     store.Store
	currentContext   string
	dockerEndpoint   docker.Endpoint
}

// NewFakeCli returns a fake for the command.Cli interface
func NewFakeCli(client client.APIClient, opts ...func(*FakeCli)) *FakeCli {
	outBuffer := new(bytes.Buffer)
	errBuffer := new(bytes.Buffer)
	c := &FakeCli{
		client:    client,
		out:       streams.NewOut(outBuffer),
		outBuffer: outBuffer,
		err:       errBuffer,
		in:        streams.NewIn(ioutil.NopCloser(strings.NewReader(""))),
		// Use an empty string for filename so that tests don't create configfiles
		// Set cli.ConfigFile().Filename to a tempfile to support Save.
		configfile:     configfile.New(""),
		currentContext: command.DefaultContextName,
	}
	for _, opt := range opts {
		opt(c)
	}
	return c
}

// SetIn sets the input of the cli to the specified ReadCloser
func (c *FakeCli) SetIn(in *streams.In) {
	c.in = in
}

// SetErr sets the stderr stream for the cli to the specified io.Writer
func (c *FakeCli) SetErr(err *bytes.Buffer) {
	c.err = err
}

// SetOut sets the stdout stream for the cli to the specified io.Writer
func (c *FakeCli) SetOut(out *streams.Out) {
	c.out = out
}

// SetConfigFile sets the "fake" config file
func (c *FakeCli) SetConfigFile(configfile *configfile.ConfigFile) {
	c.configfile = configfile
}

// SetContextStore sets the "fake" context store
func (c *FakeCli) SetContextStore(store store.Store) {
	c.contextStore = store
}

// SetCurrentContext sets the "fake" current context
func (c *FakeCli) SetCurrentContext(name string) {
	c.currentContext = name
}

// SetDockerEndpoint sets the "fake" docker endpoint
func (c *FakeCli) SetDockerEndpoint(ep docker.Endpoint) {
	c.dockerEndpoint = ep
}

// Client returns a docker API client
func (c *FakeCli) Client() client.APIClient {
	return c.client
}

// Out returns the output stream (stdout) the cli should write on
func (c *FakeCli) Out() *streams.Out {
	return c.out
}

// Err returns the output stream (stderr) the cli should write on
func (c *FakeCli) Err() io.Writer {
	return c.err
}

// In returns the input stream the cli will use
func (c *FakeCli) In() *streams.In {
	return c.in
}

// ConfigFile returns the cli configfile object (to get client configuration)
func (c *FakeCli) ConfigFile() *configfile.ConfigFile {
	return c.configfile
}

// ContextStore returns the cli context store
func (c *FakeCli) ContextStore() store.Store {
	return c.contextStore
}

// CurrentContext returns the cli context
func (c *FakeCli) CurrentContext() string {
	return c.currentContext
}

// DockerEndpoint returns the current DockerEndpoint
func (c *FakeCli) DockerEndpoint() docker.Endpoint {
	return c.dockerEndpoint
}

// ServerInfo returns API server information for the server used by this client
func (c *FakeCli) ServerInfo() command.ServerInfo {
	return c.server
}

// ClientInfo returns client information
func (c *FakeCli) ClientInfo() command.ClientInfo {
	if c.clientInfoFunc != nil {
		return c.clientInfoFunc()
	}
	return c.DockerCli.ClientInfo()
}

// SetClientInfo sets the internal getter for retrieving a ClientInfo
func (c *FakeCli) SetClientInfo(clientInfoFunc clientInfoFuncType) {
	c.clientInfoFunc = clientInfoFunc
}

// OutBuffer returns the stdout buffer
func (c *FakeCli) OutBuffer() *bytes.Buffer {
	return c.outBuffer
}

// ErrBuffer Buffer returns the stderr buffer
func (c *FakeCli) ErrBuffer() *bytes.Buffer {
	return c.err
}

// ResetOutputBuffers resets the .OutBuffer() and.ErrBuffer() back to empty
func (c *FakeCli) ResetOutputBuffers() {
	c.outBuffer.Reset()
	c.err.Reset()
}

// SetNotaryClient sets the internal getter for retrieving a NotaryClient
func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) {
	c.notaryClientFunc = notaryClientFunc
}

// NotaryClient returns an err for testing unless defined
func (c *FakeCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
	if c.notaryClientFunc != nil {
		return c.notaryClientFunc(imgRefAndAuth, actions)
	}
	return nil, fmt.Errorf("no notary client available unless defined")
}

// ManifestStore returns a fake store used for testing
func (c *FakeCli) ManifestStore() manifeststore.Store {
	return c.manifestStore
}

// RegistryClient returns a fake client for testing
func (c *FakeCli) RegistryClient(insecure bool) registryclient.RegistryClient {
	return c.registryClient
}

// SetManifestStore on the fake cli
func (c *FakeCli) SetManifestStore(store manifeststore.Store) {
	c.manifestStore = store
}

// SetRegistryClient on the fake cli
func (c *FakeCli) SetRegistryClient(client registryclient.RegistryClient) {
	c.registryClient = client
}

// ContentTrustEnabled on the fake cli
func (c *FakeCli) ContentTrustEnabled() bool {
	return c.contentTrust
}

// EnableContentTrust on the fake cli
func EnableContentTrust(c *FakeCli) {
	c.contentTrust = true
}

// BuildKitEnabled on the fake cli
func (c *FakeCli) BuildKitEnabled() (bool, error) {
	return true, nil
}
<commit_msg>internal/test: remove deprecated io/ioutil<commit_after>package test

import (
	"bytes"
	"fmt"
	"io"
	"strings"

	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/config/configfile"
	"github.com/docker/cli/cli/context/docker"
	"github.com/docker/cli/cli/context/store"
	manifeststore "github.com/docker/cli/cli/manifest/store"
	registryclient "github.com/docker/cli/cli/registry/client"
	"github.com/docker/cli/cli/streams"
	"github.com/docker/cli/cli/trust"
	"github.com/docker/docker/client"
	notaryclient "github.com/theupdateframework/notary/client"
)

// NotaryClientFuncType defines a function that returns a fake notary client
type NotaryClientFuncType func(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error)
type clientInfoFuncType func() command.ClientInfo

// FakeCli emulates the default DockerCli
type FakeCli struct {
	command.DockerCli
	client           client.APIClient
	configfile       *configfile.ConfigFile
	out              *streams.Out
	outBuffer        *bytes.Buffer
	err              *bytes.Buffer
	in               *streams.In
	server           command.ServerInfo
	clientInfoFunc   clientInfoFuncType
	notaryClientFunc NotaryClientFuncType
	manifestStore    manifeststore.Store
	registryClient   registryclient.RegistryClient
	contentTrust     bool
	contextStore     store.Store
	currentContext   string
	dockerEndpoint   docker.Endpoint
}

// NewFakeCli returns a fake for the command.Cli interface
func NewFakeCli(client client.APIClient, opts ...func(*FakeCli)) *FakeCli {
	outBuffer := new(bytes.Buffer)
	errBuffer := new(bytes.Buffer)
	c := &FakeCli{
		client:    client,
		out:       streams.NewOut(outBuffer),
		outBuffer: outBuffer,
		err:       errBuffer,
		in:        streams.NewIn(io.NopCloser(strings.NewReader(""))),
		// Use an empty string for filename so that tests don't create configfiles
		// Set cli.ConfigFile().Filename to a tempfile to support Save.
		configfile:     configfile.New(""),
		currentContext: command.DefaultContextName,
	}
	for _, opt := range opts {
		opt(c)
	}
	return c
}

// SetIn sets the input of the cli to the specified ReadCloser
func (c *FakeCli) SetIn(in *streams.In) {
	c.in = in
}

// SetErr sets the stderr stream for the cli to the specified io.Writer
func (c *FakeCli) SetErr(err *bytes.Buffer) {
	c.err = err
}

// SetOut sets the stdout stream for the cli to the specified io.Writer
func (c *FakeCli) SetOut(out *streams.Out) {
	c.out = out
}

// SetConfigFile sets the "fake" config file
func (c *FakeCli) SetConfigFile(configfile *configfile.ConfigFile) {
	c.configfile = configfile
}

// SetContextStore sets the "fake" context store
func (c *FakeCli) SetContextStore(store store.Store) {
	c.contextStore = store
}

// SetCurrentContext sets the "fake" current context
func (c *FakeCli) SetCurrentContext(name string) {
	c.currentContext = name
}

// SetDockerEndpoint sets the "fake" docker endpoint
func (c *FakeCli) SetDockerEndpoint(ep docker.Endpoint) {
	c.dockerEndpoint = ep
}

// Client returns a docker API client
func (c *FakeCli) Client() client.APIClient {
	return c.client
}

// Out returns the output stream (stdout) the cli should write on
func (c *FakeCli) Out() *streams.Out {
	return c.out
}

// Err returns the output stream (stderr) the cli should write on
func (c *FakeCli) Err() io.Writer {
	return c.err
}

// In returns the input stream the cli will use
func (c *FakeCli) In() *streams.In {
	return c.in
}

// ConfigFile returns the cli configfile object (to get client configuration)
func (c *FakeCli) ConfigFile() *configfile.ConfigFile {
	return c.configfile
}

// ContextStore returns the cli context store
func (c *FakeCli) ContextStore() store.Store {
	return c.contextStore
}

// CurrentContext returns the cli context
func (c *FakeCli) CurrentContext() string {
	return c.currentContext
}

// DockerEndpoint returns the current DockerEndpoint
func (c *FakeCli) DockerEndpoint() docker.Endpoint {
	return c.dockerEndpoint
}

// ServerInfo returns API server information for the server used by this client
func (c *FakeCli) ServerInfo() command.ServerInfo {
	return c.server
}

// ClientInfo returns client information
func (c *FakeCli) ClientInfo() command.ClientInfo {
	if c.clientInfoFunc != nil {
		return c.clientInfoFunc()
	}
	return c.DockerCli.ClientInfo()
}

// SetClientInfo sets the internal getter for retrieving a ClientInfo
func (c *FakeCli) SetClientInfo(clientInfoFunc clientInfoFuncType) {
	c.clientInfoFunc = clientInfoFunc
}

// OutBuffer returns the stdout buffer
func (c *FakeCli) OutBuffer() *bytes.Buffer {
	return c.outBuffer
}

// ErrBuffer Buffer returns the stderr buffer
func (c *FakeCli) ErrBuffer() *bytes.Buffer {
	return c.err
}

// ResetOutputBuffers resets the .OutBuffer() and.ErrBuffer() back to empty
func (c *FakeCli) ResetOutputBuffers() {
	c.outBuffer.Reset()
	c.err.Reset()
}

// SetNotaryClient sets the internal getter for retrieving a NotaryClient
func (c *FakeCli) SetNotaryClient(notaryClientFunc NotaryClientFuncType) {
	c.notaryClientFunc = notaryClientFunc
}

// NotaryClient returns an err for testing unless defined
func (c *FakeCli) NotaryClient(imgRefAndAuth trust.ImageRefAndAuth, actions []string) (notaryclient.Repository, error) {
	if c.notaryClientFunc != nil {
		return c.notaryClientFunc(imgRefAndAuth, actions)
	}
	return nil, fmt.Errorf("no notary client available unless defined")
}

// ManifestStore returns a fake store used for testing
func (c *FakeCli) ManifestStore() manifeststore.Store {
	return c.manifestStore
}

// RegistryClient returns a fake client for testing
func (c *FakeCli) RegistryClient(insecure bool) registryclient.RegistryClient {
	return c.registryClient
}

// SetManifestStore on the fake cli
func (c *FakeCli) SetManifestStore(store manifeststore.Store) {
	c.manifestStore = store
}

// SetRegistryClient on the fake cli
func (c *FakeCli) SetRegistryClient(client registryclient.RegistryClient) {
	c.registryClient = client
}

// ContentTrustEnabled on the fake cli
func (c *FakeCli) ContentTrustEnabled() bool {
	return c.contentTrust
}

// EnableContentTrust on the fake cli
func EnableContentTrust(c *FakeCli) {
	c.contentTrust = true
}

// BuildKitEnabled on the fake cli
func (c *FakeCli) BuildKitEnabled() (bool, error) {
	return true, nil
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package streaming implements encoder and decoder for streams
// of runtime.Objects over io.Writer/Readers.
package streaming

import (
	"bytes"
	"fmt"
	"io"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
)

// Encoder is a runtime.Encoder on a stream.
type Encoder interface {
	// Encode will write the provided object to the stream or return an error. It obeys the same
	// contract as runtime.VersionedEncoder.
	Encode(obj runtime.Object) error
}

// Decoder is a runtime.Decoder from a stream.
type Decoder interface {
	// Decode will return io.EOF when no more objects are available.
	Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error)
	// Close closes the underlying stream.
	Close() error
}

// Serializer is a factory for creating encoders and decoders that work over streams.
type Serializer interface {
	NewEncoder(w io.Writer) Encoder
	NewDecoder(r io.ReadCloser) Decoder
}

type decoder struct {
	reader    io.ReadCloser
	decoder   runtime.Decoder
	buf       []byte
	maxBytes  int
	resetRead bool
}

// NewDecoder creates a streaming decoder that reads object chunks from r and decodes them with d.
// The reader is expected to return ErrShortRead if the provided buffer is not large enough to read
// an entire object.
func NewDecoder(r io.ReadCloser, d runtime.Decoder) Decoder {
	return &decoder{
		reader:   r,
		decoder:  d,
		buf:      make([]byte, 1024),
		maxBytes: 16 * 1024 * 1024,
	}
}

var ErrObjectTooLarge = fmt.Errorf("object to decode was longer than maximum allowed size")

// Decode reads the next object from the stream and decodes it.
func (d *decoder) Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
	base := 0
	for {
		n, err := d.reader.Read(d.buf[base:])
		if err == io.ErrShortBuffer {
			if n == 0 {
				return nil, nil, fmt.Errorf("got short buffer with n=0, base=%d, cap=%d", base, cap(d.buf))
			}
			if d.resetRead {
				continue
			}
			// double the buffer size up to maxBytes
			if len(d.buf) < d.maxBytes {
				base += n
				d.buf = append(d.buf, make([]byte, len(d.buf))...)
				continue
			}
			// must read the rest of the frame (until we stop getting ErrShortBuffer)
			d.resetRead = true
			return nil, nil, ErrObjectTooLarge
		}
		if err != nil {
			return nil, nil, err
		}
		if d.resetRead {
			// now that we have drained the large read, continue
			d.resetRead = false
			continue
		}
		base += n
		break
	}
	return d.decoder.Decode(d.buf[:base], defaults, into)
}

func (d *decoder) Close() error {
	return d.reader.Close()
}

type encoder struct {
	writer  io.Writer
	encoder runtime.Encoder
	buf     *bytes.Buffer
}

// NewEncoder returns a new streaming encoder.
func NewEncoder(w io.Writer, e runtime.Encoder) Encoder {
	return &encoder{
		writer:  w,
		encoder: e,
		buf:     &bytes.Buffer{},
	}
}

// Encode writes the provided object to the nested writer.
func (e *encoder) Encode(obj runtime.Object) error {
	if err := e.encoder.Encode(obj, e.buf); err != nil {
		return err
	}
	_, err := e.writer.Write(e.buf.Bytes())
	e.buf.Reset()
	return err
}
<commit_msg>introduces a new streaming encoder that utilizes a memory allocator during objects serialization<commit_after>/*
Copyright 2015 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package streaming implements encoder and decoder for streams
// of runtime.Objects over io.Writer/Readers.
package streaming

import (
	"bytes"
	"fmt"
	"io"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
)

// Encoder is a runtime.Encoder on a stream.
type Encoder interface {
	// Encode will write the provided object to the stream or return an error. It obeys the same
	// contract as runtime.VersionedEncoder.
	Encode(obj runtime.Object) error
}

// Decoder is a runtime.Decoder from a stream.
type Decoder interface {
	// Decode will return io.EOF when no more objects are available.
	Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error)
	// Close closes the underlying stream.
	Close() error
}

// Serializer is a factory for creating encoders and decoders that work over streams.
type Serializer interface {
	NewEncoder(w io.Writer) Encoder
	NewDecoder(r io.ReadCloser) Decoder
}

type decoder struct {
	reader    io.ReadCloser
	decoder   runtime.Decoder
	buf       []byte
	maxBytes  int
	resetRead bool
}

// NewDecoder creates a streaming decoder that reads object chunks from r and decodes them with d.
// The reader is expected to return ErrShortRead if the provided buffer is not large enough to read
// an entire object.
func NewDecoder(r io.ReadCloser, d runtime.Decoder) Decoder {
	return &decoder{
		reader:   r,
		decoder:  d,
		buf:      make([]byte, 1024),
		maxBytes: 16 * 1024 * 1024,
	}
}

var ErrObjectTooLarge = fmt.Errorf("object to decode was longer than maximum allowed size")

// Decode reads the next object from the stream and decodes it.
func (d *decoder) Decode(defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
	base := 0
	for {
		n, err := d.reader.Read(d.buf[base:])
		if err == io.ErrShortBuffer {
			if n == 0 {
				return nil, nil, fmt.Errorf("got short buffer with n=0, base=%d, cap=%d", base, cap(d.buf))
			}
			if d.resetRead {
				continue
			}
			// double the buffer size up to maxBytes
			if len(d.buf) < d.maxBytes {
				base += n
				d.buf = append(d.buf, make([]byte, len(d.buf))...)
				continue
			}
			// must read the rest of the frame (until we stop getting ErrShortBuffer)
			d.resetRead = true
			return nil, nil, ErrObjectTooLarge
		}
		if err != nil {
			return nil, nil, err
		}
		if d.resetRead {
			// now that we have drained the large read, continue
			d.resetRead = false
			continue
		}
		base += n
		break
	}
	return d.decoder.Decode(d.buf[:base], defaults, into)
}

func (d *decoder) Close() error {
	return d.reader.Close()
}

type encoder struct {
	writer  io.Writer
	encoder runtime.Encoder
	buf     *bytes.Buffer
}

// NewEncoder returns a new streaming encoder.
func NewEncoder(w io.Writer, e runtime.Encoder) Encoder {
	return &encoder{
		writer:  w,
		encoder: e,
		buf:     &bytes.Buffer{},
	}
}

// Encode writes the provided object to the nested writer.
func (e *encoder) Encode(obj runtime.Object) error {
	if err := e.encoder.Encode(obj, e.buf); err != nil {
		return err
	}
	_, err := e.writer.Write(e.buf.Bytes())
	e.buf.Reset()
	return err
}

type encoderWithAllocator struct {
	writer       io.Writer
	encoder      runtime.EncoderWithAllocator
	memAllocator runtime.MemoryAllocator
}

// NewEncoderWithAllocator returns a new streaming encoder
func NewEncoderWithAllocator(w io.Writer, e runtime.EncoderWithAllocator, a runtime.MemoryAllocator) Encoder {
	return &encoderWithAllocator{
		writer:       w,
		encoder:      e,
		memAllocator: a,
	}
}

// Encode writes the provided object to the nested writer
func (e *encoderWithAllocator) Encode(obj runtime.Object) error {
	return e.encoder.EncodeWithAllocator(obj, e.writer, e.memAllocator)
}
<|endoftext|>


<commit_before>// Copyright 2015 Hajime Hoshi
//
// 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.

// +build js

package ui

import (
	"github.com/gopherjs/gopherjs/js"
	"github.com/gopherjs/webgl"
	"github.com/hajimehoshi/ebiten/internal/opengl"
	"strconv"
	"time"
)

var canvas js.Object
var context *opengl.Context

func Use(f func(*opengl.Context)) {
	f(context)
}

func DoEvents() {
	time.Sleep(0)
}

func Terminate() {
	// Do nothing.
}

func IsClosed() bool {
	return false
}

func SwapBuffers() {
	// Do nothing.
}

func init() {
	ch := make(chan struct{})
	js.Global.Get("window").Set("onload", func() {
		close(ch)
	})
	<-ch

	doc := js.Global.Get("document")
	doc.Set("onkeydown", func(e js.Object) bool {
		code := e.Get("keyCode").Int()
		// Backspace
		if code == 8 {
			return false
		}
		// Functions
		if 112 <= code && code <= 123 {
			return false
		}
		// Alt and arrows
		if code == 37 && code == 39 {
			// Don't need to check Alt.
			return false
		}
		return true
	})

	canvas = doc.Call("createElement", "canvas")
	canvas.Set("width", 16)
	canvas.Set("height", 16)
	doc.Get("body").Call("appendChild", canvas)

	htmlStyle := doc.Get("documentElement").Get("style")
	htmlStyle.Set("height", "100%")
	htmlStyle.Set("margin", "0")
	htmlStyle.Set("padding", "0")

	bodyStyle := doc.Get("body").Get("style")
	bodyStyle.Set("backgroundColor", "#000")
	bodyStyle.Set("position", "relative")
	bodyStyle.Set("height", "100%")
	bodyStyle.Set("margin", "0")
	bodyStyle.Set("padding", "0")
	doc.Get("body").Set("onclick", func() {
		canvas.Call("focus")
	})

	canvasStyle := canvas.Get("style")
	canvasStyle.Set("position", "absolute")

	webglContext, err := webgl.NewContext(canvas, &webgl.ContextAttributes{
		Alpha:              true,
		PremultipliedAlpha: true,
	})
	if err != nil {
		panic(err)
	}
	context = opengl.NewContext(webglContext)

	// Make the canvas focusable.
	canvas.Call("setAttribute", "tabindex", 1)
	canvas.Get("style").Set("outline", "none")

	canvas.Set("onkeydown", func(e js.Object) bool {
		code := e.Get("keyCode").Int()
		currentInput.keyDown(code)
		return false
	})
	canvas.Set("onkeyup", func(e js.Object) bool {
		code := e.Get("keyCode").Int()
		currentInput.keyUp(code)
		return false
	})
	canvas.Set("onmousedown", func(e js.Object) bool {
		button := e.Get("button").Int()
		currentInput.mouseDown(button)
		return false
	})
	canvas.Set("onmouseup", func(e js.Object) bool {
		button := e.Get("button").Int()
		currentInput.mouseUp(button)
		return false
	})
	canvas.Set("oncontextmenu", func(e js.Object) bool {
		return false
	})
}

func Start(width, height, scale int, title string) (actualScale int, err error) {
	doc := js.Global.Get("document")
	doc.Set("title", title)
	canvas.Set("width", width*scale)
	canvas.Set("height", height*scale)
	canvasStyle := canvas.Get("style")
	canvasStyle.Set("left", "calc(50% - "+strconv.Itoa(width*scale/2)+"px)")
	canvasStyle.Set("top", "calc(50% - "+strconv.Itoa(height*scale/2)+"px)")

	canvas.Set("onmousemove", func(e js.Object) {
		rect := canvas.Call("getBoundingClientRect")
		x, y := e.Get("clientX").Int(), e.Get("clientY").Int()
		x -= rect.Get("left").Int()
		y -= rect.Get("top").Int()
		currentInput.mouseMove(x/scale, y/scale)
	})
	canvas.Call("focus")

	return scale, nil
}
<commit_msg>Bug fix: blurred canvas in Retina display (#68)<commit_after>// Copyright 2015 Hajime Hoshi
//
// 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.

// +build js

package ui

import (
	"github.com/gopherjs/gopherjs/js"
	"github.com/gopherjs/webgl"
	"github.com/hajimehoshi/ebiten/internal/opengl"
	"strconv"
	"time"
)

var canvas js.Object
var context *opengl.Context

func Use(f func(*opengl.Context)) {
	f(context)
}

func DoEvents() {
	time.Sleep(0)
}

func Terminate() {
	// Do nothing.
}

func IsClosed() bool {
	return false
}

func SwapBuffers() {
	// Do nothing.
}

func init() {
	ch := make(chan struct{})
	js.Global.Get("window").Set("onload", func() {
		close(ch)
	})
	<-ch

	doc := js.Global.Get("document")
	doc.Set("onkeydown", func(e js.Object) bool {
		code := e.Get("keyCode").Int()
		// Backspace
		if code == 8 {
			return false
		}
		// Functions
		if 112 <= code && code <= 123 {
			return false
		}
		// Alt and arrows
		if code == 37 && code == 39 {
			// Don't need to check Alt.
			return false
		}
		return true
	})

	canvas = doc.Call("createElement", "canvas")
	canvas.Set("width", 16)
	canvas.Set("height", 16)
	doc.Get("body").Call("appendChild", canvas)

	htmlStyle := doc.Get("documentElement").Get("style")
	htmlStyle.Set("height", "100%")
	htmlStyle.Set("margin", "0")
	htmlStyle.Set("padding", "0")

	bodyStyle := doc.Get("body").Get("style")
	bodyStyle.Set("backgroundColor", "#000")
	bodyStyle.Set("position", "relative")
	bodyStyle.Set("height", "100%")
	bodyStyle.Set("margin", "0")
	bodyStyle.Set("padding", "0")
	doc.Get("body").Set("onclick", func() {
		canvas.Call("focus")
	})

	canvasStyle := canvas.Get("style")
	canvasStyle.Set("position", "absolute")

	webglContext, err := webgl.NewContext(canvas, &webgl.ContextAttributes{
		Alpha:              true,
		PremultipliedAlpha: true,
	})
	if err != nil {
		panic(err)
	}
	context = opengl.NewContext(webglContext)

	// Make the canvas focusable.
	canvas.Call("setAttribute", "tabindex", 1)
	canvas.Get("style").Set("outline", "none")

	canvas.Set("onkeydown", func(e js.Object) bool {
		code := e.Get("keyCode").Int()
		currentInput.keyDown(code)
		return false
	})
	canvas.Set("onkeyup", func(e js.Object) bool {
		code := e.Get("keyCode").Int()
		currentInput.keyUp(code)
		return false
	})
	canvas.Set("onmousedown", func(e js.Object) bool {
		button := e.Get("button").Int()
		currentInput.mouseDown(button)
		return false
	})
	canvas.Set("onmouseup", func(e js.Object) bool {
		button := e.Get("button").Int()
		currentInput.mouseUp(button)
		return false
	})
	canvas.Set("oncontextmenu", func(e js.Object) bool {
		return false
	})
}

func devicePixelRatio() int {
	// TODO: What if ratio is not an integer but a float?
	ratio := js.Global.Get("window").Get("devicePixelRatio").Int()
	if ratio == 0 {
		ratio = 1
	}
	return ratio
}

func Start(width, height, scale int, title string) (actualScale int, err error) {
	doc := js.Global.Get("document")
	doc.Set("title", title)
	// for retina
	actualScale = scale * devicePixelRatio()
	canvas.Set("width", width*actualScale)
	canvas.Set("height", height*actualScale)
	canvasStyle := canvas.Get("style")

	cssWidth := width * scale
	cssHeight := height * scale
	canvasStyle.Set("width", strconv.Itoa(cssWidth)+"px")
	canvasStyle.Set("height", strconv.Itoa(cssHeight)+"px")
	canvasStyle.Set("left", "calc(50% - "+strconv.Itoa(cssWidth/2)+"px)")
	canvasStyle.Set("top", "calc(50% - "+strconv.Itoa(cssHeight/2)+"px)")

	canvas.Set("onmousemove", func(e js.Object) {
		rect := canvas.Call("getBoundingClientRect")
		x, y := e.Get("clientX").Int(), e.Get("clientY").Int()
		x -= rect.Get("left").Int()
		y -= rect.Get("top").Int()
		currentInput.mouseMove(x/scale, y/scale)
	})
	canvas.Call("focus")

	return actualScale, nil
}
<|endoftext|>


<commit_before>package notifiers

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/grafana/grafana/pkg/bus"
	"github.com/grafana/grafana/pkg/log"
	m "github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/services/alerting"
	"github.com/grafana/grafana/pkg/setting"
)

func init() {
	alerting.RegisterNotifier(&alerting.NotifierPlugin{
		Type: "googlechat",
		Name: "Google Hangouts Chat",
		Description: "Sends notifications to Google Hangouts Chat via webhooks based on the official JSON message " +
			"format (https://developers.google.com/hangouts/chat/reference/message-formats/).",
		Factory: NewGoogleChatNotifier,
		OptionsTemplate: `

Google Hangouts Chat settings

        Url
        <input type="text" required class="gf-form-input max-width-30" ng-model="ctrl.model.settings.url" placeholder="Google Hangouts Chat incoming webhook url"></input>

    `,
	})
}

func NewGoogleChatNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
	url := model.Settings.Get("url").MustString()
	if url == "" {
		return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
	}

	return &GoogleChatNotifier{
		NotifierBase: NewNotifierBase(model),
		Url:          url,
		log:          log.New("alerting.notifier.googlechat"),
	}, nil
}

type GoogleChatNotifier struct {
	NotifierBase
	Url    string
	method string
	log    log.Logger
}

/**
Structs used to build a custom Google Hangouts Chat message card.
See: https://developers.google.com/hangouts/chat/reference/message-formats/cards
*/
type outerStruct struct {
	Cards []card `json:"cards"`
}

type card struct {
	Header   header    `json:"header"`
	Sections []section `json:"sections"`
}

type header struct {
	Title string `json:"title"`
}

type section struct {
	Widgets []widget `json:"widgets"`
}

// "generic" widget used to add different types of widgets (buttonWidget, textParagraphWidget, imageWidget)
type widget interface {
}

type buttonWidget struct {
	Buttons []button `json:"buttons"`
}

type textParagraphWidget struct {
	Text text `json:"textParagraph"`
}

type text struct {
	Text string `json:"text"`
}

type imageWidget struct {
	Image image `json:"image"`
}

type image struct {
	ImageUrl string `json:"imageUrl"`
}

type button struct {
	TextButton textButton `json:"textButton"`
}

type textButton struct {
	Text    string  `json:"text"`
	OnClick onClick `json:"onClick"`
}

type onClick struct {
	OpenLink openLink `json:"openLink"`
}

type openLink struct {
	Url string `json:"url"`
}

func (this *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error {
	this.log.Info("Executing Google Chat notification")

	headers := map[string]string{
		"Content-Type": "application/json; charset=UTF-8",
	}

	ruleUrl, err := evalContext.GetRuleUrl()
	if err != nil {
		this.log.Error("evalContext returned an invalid rule URL")
	}

	// add a text paragraph widget for the message
	widgets := []widget{
		textParagraphWidget{
			Text: text{
				Text: evalContext.Rule.Message,
			},
		},
	}

	// add a text paragraph widget for the fields
	var fields []textParagraphWidget
	fieldLimitCount := 4
	for index, evt := range evalContext.EvalMatches {
		fields = append(fields,
			textParagraphWidget{
				Text: text{
					Text: "" + evt.Metric + ": " + fmt.Sprint(evt.Value) + "",
				},
			},
		)
		if index > fieldLimitCount {
			break
		}
	}
	widgets = append(widgets, fields)

	// if an image exists, add it as an image widget
	if evalContext.ImagePublicUrl != "" {
		widgets = append(widgets, imageWidget{
			Image: image{
				ImageUrl: evalContext.ImagePublicUrl,
			},
		})
	} else {
		this.log.Info("Could not retrieve a public image URL.")
	}

	// add a button widget (link to Grafana)
	widgets = append(widgets, buttonWidget{
		Buttons: []button{
			{
				TextButton: textButton{
					Text: "OPEN IN GRAFANA",
					OnClick: onClick{
						OpenLink: openLink{
							Url: ruleUrl,
						},
					},
				},
			},
		},
	})

	// add text paragraph widget for the build version and timestamp
	widgets = append(widgets, textParagraphWidget{
		Text: text{
			Text: "Grafana v" + setting.BuildVersion + " | " + (time.Now()).Format(time.RFC822),
		},
	})

	// nest the required structs
	res1D := &outerStruct{
		Cards: []card{
			{
				Header: header{
					Title: evalContext.GetNotificationTitle(),
				},
				Sections: []section{
					{
						Widgets: widgets,
					},
				},
			},
		},
	}
	body, _ := json.Marshal(res1D)

	cmd := &m.SendWebhookSync{
		Url:        this.Url,
		HttpMethod: "POST",
		HttpHeader: headers,
		Body:       string(body),
	}

	if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
		this.log.Error("Failed to send Google Hangouts Chat alert", "error", err, "webhook", this.Name)
		return err
	}

	return nil
}
<commit_msg>removes unused code<commit_after>package notifiers

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/grafana/grafana/pkg/bus"
	"github.com/grafana/grafana/pkg/log"
	m "github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/services/alerting"
	"github.com/grafana/grafana/pkg/setting"
)

func init() {
	alerting.RegisterNotifier(&alerting.NotifierPlugin{
		Type: "googlechat",
		Name: "Google Hangouts Chat",
		Description: "Sends notifications to Google Hangouts Chat via webhooks based on the official JSON message " +
			"format (https://developers.google.com/hangouts/chat/reference/message-formats/).",
		Factory: NewGoogleChatNotifier,
		OptionsTemplate: `

Google Hangouts Chat settings

        Url
        <input type="text" required class="gf-form-input max-width-30" ng-model="ctrl.model.settings.url" placeholder="Google Hangouts Chat incoming webhook url"></input>

    `,
	})
}

func NewGoogleChatNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
	url := model.Settings.Get("url").MustString()
	if url == "" {
		return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
	}

	return &GoogleChatNotifier{
		NotifierBase: NewNotifierBase(model),
		Url:          url,
		log:          log.New("alerting.notifier.googlechat"),
	}, nil
}

type GoogleChatNotifier struct {
	NotifierBase
	Url string
	log log.Logger
}

/**
Structs used to build a custom Google Hangouts Chat message card.
See: https://developers.google.com/hangouts/chat/reference/message-formats/cards
*/
type outerStruct struct {
	Cards []card `json:"cards"`
}

type card struct {
	Header   header    `json:"header"`
	Sections []section `json:"sections"`
}

type header struct {
	Title string `json:"title"`
}

type section struct {
	Widgets []widget `json:"widgets"`
}

// "generic" widget used to add different types of widgets (buttonWidget, textParagraphWidget, imageWidget)
type widget interface {
}

type buttonWidget struct {
	Buttons []button `json:"buttons"`
}

type textParagraphWidget struct {
	Text text `json:"textParagraph"`
}

type text struct {
	Text string `json:"text"`
}

type imageWidget struct {
	Image image `json:"image"`
}

type image struct {
	ImageUrl string `json:"imageUrl"`
}

type button struct {
	TextButton textButton `json:"textButton"`
}

type textButton struct {
	Text    string  `json:"text"`
	OnClick onClick `json:"onClick"`
}

type onClick struct {
	OpenLink openLink `json:"openLink"`
}

type openLink struct {
	Url string `json:"url"`
}

func (this *GoogleChatNotifier) Notify(evalContext *alerting.EvalContext) error {
	this.log.Info("Executing Google Chat notification")

	headers := map[string]string{
		"Content-Type": "application/json; charset=UTF-8",
	}

	ruleUrl, err := evalContext.GetRuleUrl()
	if err != nil {
		this.log.Error("evalContext returned an invalid rule URL")
	}

	// add a text paragraph widget for the message
	widgets := []widget{
		textParagraphWidget{
			Text: text{
				Text: evalContext.Rule.Message,
			},
		},
	}

	// add a text paragraph widget for the fields
	var fields []textParagraphWidget
	fieldLimitCount := 4
	for index, evt := range evalContext.EvalMatches {
		fields = append(fields,
			textParagraphWidget{
				Text: text{
					Text: "" + evt.Metric + ": " + fmt.Sprint(evt.Value) + "",
				},
			},
		)
		if index > fieldLimitCount {
			break
		}
	}
	widgets = append(widgets, fields)

	// if an image exists, add it as an image widget
	if evalContext.ImagePublicUrl != "" {
		widgets = append(widgets, imageWidget{
			Image: image{
				ImageUrl: evalContext.ImagePublicUrl,
			},
		})
	} else {
		this.log.Info("Could not retrieve a public image URL.")
	}

	// add a button widget (link to Grafana)
	widgets = append(widgets, buttonWidget{
		Buttons: []button{
			{
				TextButton: textButton{
					Text: "OPEN IN GRAFANA",
					OnClick: onClick{
						OpenLink: openLink{
							Url: ruleUrl,
						},
					},
				},
			},
		},
	})

	// add text paragraph widget for the build version and timestamp
	widgets = append(widgets, textParagraphWidget{
		Text: text{
			Text: "Grafana v" + setting.BuildVersion + " | " + (time.Now()).Format(time.RFC822),
		},
	})

	// nest the required structs
	res1D := &outerStruct{
		Cards: []card{
			{
				Header: header{
					Title: evalContext.GetNotificationTitle(),
				},
				Sections: []section{
					{
						Widgets: widgets,
					},
				},
			},
		},
	}
	body, _ := json.Marshal(res1D)

	cmd := &m.SendWebhookSync{
		Url:        this.Url,
		HttpMethod: "POST",
		HttpHeader: headers,
		Body:       string(body),
	}

	if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
		this.log.Error("Failed to send Google Hangouts Chat alert", "error", err, "webhook", this.Name)
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 Hajime Hoshi
//
// 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.

// +build js

package ui

import (
	"image"
	"strconv"

	"github.com/hajimehoshi/gopherwasm/js"

	"github.com/hajimehoshi/ebiten/internal/devicescale"
	"github.com/hajimehoshi/ebiten/internal/hooks"
	"github.com/hajimehoshi/ebiten/internal/input"
	"github.com/hajimehoshi/ebiten/internal/opengl"
	"github.com/hajimehoshi/ebiten/internal/web"
)

var canvas js.Value

type userInterface struct {
	width                int
	height               int
	scale                float64
	fullscreen           bool
	runnableInBackground bool

	sizeChanged bool
	windowFocus bool
	pageVisible bool
}

var currentUI = &userInterface{
	sizeChanged: true,
	windowFocus: true,
	pageVisible: true,
}

func MonitorSize() (int, int) {
	w := js.Global.Get("window")
	return w.Get("innerWidth").Int(), w.Get("innerHeight").Int()
}

func SetScreenSize(width, height int) bool {
	return currentUI.setScreenSize(width, height, currentUI.scale, currentUI.fullscreen)
}

func SetScreenScale(scale float64) bool {
	return currentUI.setScreenSize(currentUI.width, currentUI.height, scale, currentUI.fullscreen)
}

func ScreenScale() float64 {
	return currentUI.scale
}

func SetFullscreen(fullscreen bool) {
	currentUI.setScreenSize(currentUI.width, currentUI.height, currentUI.scale, fullscreen)
}

func IsFullscreen() bool {
	return currentUI.fullscreen
}

func SetRunnableInBackground(runnableInBackground bool) {
	currentUI.runnableInBackground = runnableInBackground
}

func IsRunnableInBackground() bool {
	return currentUI.runnableInBackground
}

func ScreenPadding() (x0, y0, x1, y1 float64) {
	return 0, 0, 0, 0
}

func adjustPosition(x, y int) (int, int) {
	rect := canvas.Call("getBoundingClientRect")
	x -= rect.Get("left").Int()
	y -= rect.Get("top").Int()
	scale := currentUI.getScale()
	return int(float64(x) / scale), int(float64(y) / scale)
}

func AdjustedCursorPosition() (x, y int) {
	return adjustPosition(input.Get().CursorPosition())
}

func AdjustedTouches() []*input.Touch {
	ts := input.Get().Touches()
	adjusted := make([]*input.Touch, len(ts))
	for i, t := range ts {
		x, y := adjustPosition(t.Position())
		adjusted[i] = input.NewTouch(t.ID(), x, y)
	}
	return adjusted
}

func IsCursorVisible() bool {
	// The initial value is an empty string, so don't compare with "auto" here.
	return canvas.Get("style").Get("cursor").String() != "none"
}

func SetCursorVisible(visible bool) {
	if visible {
		canvas.Get("style").Set("cursor", "auto")
	} else {
		canvas.Get("style").Set("cursor", "none")
	}
}

func SetWindowTitle(title string) {
	doc := js.Global.Get("document")
	doc.Set("title", title)
}

func SetWindowIcon(iconImages []image.Image) {
	// Do nothing
}

func IsWindowDecorated() bool {
	return false
}

func SetWindowDecorated(decorated bool) {
	// Do nothing
}

func (u *userInterface) getScale() float64 {
	if !u.fullscreen {
		return u.scale
	}
	doc := js.Global.Get("document")
	body := doc.Get("body")
	bw := body.Get("clientWidth").Float()
	bh := body.Get("clientHeight").Float()
	sw := bw / float64(u.width)
	sh := bh / float64(u.height)
	if sw > sh {
		return sh
	}
	return sw
}

func (u *userInterface) actualScreenScale() float64 {
	// CSS imageRendering property seems useful to enlarge the screen,
	// but doesn't work in some cases (#306):
	// * Chrome just after restoring the lost context
	// * Safari
	// Let's use the devicePixelRatio as it is here.
	return u.getScale() * devicescale.DeviceScale()
}

func (u *userInterface) updateGraphicsContext(g GraphicsContext) {
	if u.sizeChanged {
		u.sizeChanged = false
		g.SetSize(u.width, u.height, u.actualScreenScale())
	}
}

func (u *userInterface) suspended() bool {
	return !u.runnableInBackground && (!u.windowFocus || !u.pageVisible)
}

func (u *userInterface) update(g GraphicsContext) error {
	if u.suspended() {
		hooks.SuspendAudio()
		return nil
	}
	hooks.ResumeAudio()

	if opengl.GetContext().IsContextLost() {
		opengl.GetContext().RestoreContext()
		g.Invalidate()

		// Need to return once to wait restored (#526)
		// TODO: Is it necessary to handle webglcontextrestored event?
		return nil
	}

	input.Get().UpdateGamepads()
	u.updateGraphicsContext(g)
	if err := g.Update(func() {
		input.Get().ClearRuneBuffer()
		// The offscreens must be updated every frame (#490).
		u.updateGraphicsContext(g)
	}); err != nil {
		return err
	}
	return nil
}

func (u *userInterface) loop(g GraphicsContext) error {
	ch := make(chan error)
	var f func([]js.Value)
	var cf js.Callback
	f = func([]js.Value) {
		if err := u.update(g); err != nil {
			ch <- err
			close(ch)
			return
		}
		js.Global.Get("window").Call("requestAnimationFrame", cf)
	}
	cf = js.NewCallback(f)
	f(nil)
	return <-ch
}

func init() {
	// Do nothing in node.js.
	if web.IsNodeJS() {
		return
	}
	doc := js.Global.Get("document")
	window := js.Global.Get("window")
	if doc.Get("body") == js.Null {
		ch := make(chan struct{})
		window.Call("addEventListener", "load", js.NewCallback(func([]js.Value) {
			close(ch)
		}))
		<-ch
	}

	window.Call("addEventListener", "focus", js.NewCallback(func([]js.Value) {
		currentUI.windowFocus = true
		if currentUI.suspended() {
			hooks.SuspendAudio()
		} else {
			hooks.ResumeAudio()
		}
	}))
	window.Call("addEventListener", "blur", js.NewCallback(func([]js.Value) {
		currentUI.windowFocus = false
		if currentUI.suspended() {
			hooks.SuspendAudio()
		} else {
			hooks.ResumeAudio()
		}
	}))
	doc.Call("addEventListener", "visibilitychange", js.NewCallback(func([]js.Value) {
		currentUI.pageVisible = !doc.Get("hidden").Bool()
		if currentUI.suspended() {
			hooks.SuspendAudio()
		} else {
			hooks.ResumeAudio()
		}
	}))
	window.Call("addEventListener", "resize", js.NewCallback(func([]js.Value) {
		currentUI.updateScreenSize()
	}))

	// Adjust the initial scale to 1.
	// https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
	meta := doc.Call("createElement", "meta")
	meta.Set("name", "viewport")
	meta.Set("content", "width=device-width, initial-scale=1")
	doc.Get("head").Call("appendChild", meta)

	canvas = doc.Call("createElement", "canvas")
	canvas.Set("width", 16)
	canvas.Set("height", 16)
	doc.Get("body").Call("appendChild", canvas)

	htmlStyle := doc.Get("documentElement").Get("style")
	htmlStyle.Set("height", "100%")
	htmlStyle.Set("margin", "0")
	htmlStyle.Set("padding", "0")

	bodyStyle := doc.Get("body").Get("style")
	bodyStyle.Set("backgroundColor", "#000")
	bodyStyle.Set("position", "relative")
	bodyStyle.Set("height", "100%")
	bodyStyle.Set("margin", "0")
	bodyStyle.Set("padding", "0")
	// TODO: This is OK as long as the game is in an independent iframe.
	// What if the canvas is embedded in a HTML directly?
	doc.Get("body").Call("addEventListener", "click", js.NewCallback(func([]js.Value) {
		canvas.Call("focus")
	}))

	canvasStyle := canvas.Get("style")
	canvasStyle.Set("position", "absolute")

	// Make the canvas focusable.
	canvas.Call("setAttribute", "tabindex", 1)
	canvas.Get("style").Set("outline", "none")

	// Keyboard
	canvas.Call("addEventListener", "keydown", js.NewEventCallback(true, false, false, input.OnKeyDown))
	canvas.Call("addEventListener", "keypress", js.NewEventCallback(true, false, false, input.OnKeyPress))
	canvas.Call("addEventListener", "keyup", js.NewEventCallback(true, false, false, input.OnKeyUp))

	// Mouse
	canvas.Call("addEventListener", "mousedown", js.NewEventCallback(true, false, false, input.OnMouseDown))
	canvas.Call("addEventListener", "mouseup", js.NewEventCallback(true, false, false, input.OnMouseUp))
	canvas.Call("addEventListener", "mousemove", js.NewEventCallback(true, false, false, input.OnMouseMove))

	// Touch
	canvas.Call("addEventListener", "touchstart", js.NewEventCallback(true, false, false, input.OnTouchStart))
	canvas.Call("addEventListener", "touchend", js.NewEventCallback(true, false, false, input.OnTouchEnd))
	canvas.Call("addEventListener", "touchmove", js.NewEventCallback(true, false, false, input.OnTouchMove))

	// Gamepad
	window.Call("addEventListener", "gamepadconnected", js.NewCallback(func(e []js.Value) {
		// Do nothing.
	}))

	canvas.Call("addEventListener", "contextmenu", js.NewEventCallback(true, false, false, func(js.Value) {
		// Do nothing.
	}))

	canvas.Call("addEventListener", "webglcontextlost", js.NewEventCallback(true, false, false, func(js.Value) {
		// Do nothing.
	}))
	canvas.Call("addEventListener", "webglcontextrestored", js.NewCallback(func(e []js.Value) {
		// Do nothing.
	}))
}

func RunMainThreadLoop(ch <-chan error) error {
	return <-ch
}

func Run(width, height int, scale float64, title string, g GraphicsContext, mainloop bool) error {
	u := currentUI
	doc := js.Global.Get("document")
	doc.Set("title", title)
	u.setScreenSize(width, height, scale, u.fullscreen)
	canvas.Call("focus")
	if err := opengl.Init(); err != nil {
		return err
	}
	return u.loop(g)
}

func (u *userInterface) setScreenSize(width, height int, scale float64, fullscreen bool) bool {
	if u.width == width && u.height == height &&
		u.scale == scale && fullscreen == u.fullscreen {
		return false
	}
	u.width = width
	u.height = height
	u.scale = scale
	u.fullscreen = fullscreen
	u.updateScreenSize()
	return true
}

func (u *userInterface) updateScreenSize() {
	canvas.Set("width", int(float64(u.width)*u.actualScreenScale()))
	canvas.Set("height", int(float64(u.height)*u.actualScreenScale()))
	canvasStyle := canvas.Get("style")

	s := u.getScale()
	cssWidth := int(float64(u.width) * s)
	cssHeight := int(float64(u.height) * s)
	canvasStyle.Set("width", strconv.Itoa(cssWidth)+"px")
	canvasStyle.Set("height", strconv.Itoa(cssHeight)+"px")
	// CSS calc requires space chars.
	canvasStyle.Set("left", "calc((100% - "+strconv.Itoa(cssWidth)+"px) / 2)")
	canvasStyle.Set("top", "calc((100% - "+strconv.Itoa(cssHeight)+"px) / 2)")

	u.sizeChanged = true
}
<commit_msg>ui: Use goroutine to avoid blocking on GopherJS<commit_after>// Copyright 2015 Hajime Hoshi
//
// 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.

// +build js

package ui

import (
	"image"
	"strconv"

	"github.com/hajimehoshi/gopherwasm/js"

	"github.com/hajimehoshi/ebiten/internal/devicescale"
	"github.com/hajimehoshi/ebiten/internal/hooks"
	"github.com/hajimehoshi/ebiten/internal/input"
	"github.com/hajimehoshi/ebiten/internal/opengl"
	"github.com/hajimehoshi/ebiten/internal/web"
)

var canvas js.Value

type userInterface struct {
	width                int
	height               int
	scale                float64
	fullscreen           bool
	runnableInBackground bool

	sizeChanged bool
	windowFocus bool
	pageVisible bool
}

var currentUI = &userInterface{
	sizeChanged: true,
	windowFocus: true,
	pageVisible: true,
}

func MonitorSize() (int, int) {
	w := js.Global.Get("window")
	return w.Get("innerWidth").Int(), w.Get("innerHeight").Int()
}

func SetScreenSize(width, height int) bool {
	return currentUI.setScreenSize(width, height, currentUI.scale, currentUI.fullscreen)
}

func SetScreenScale(scale float64) bool {
	return currentUI.setScreenSize(currentUI.width, currentUI.height, scale, currentUI.fullscreen)
}

func ScreenScale() float64 {
	return currentUI.scale
}

func SetFullscreen(fullscreen bool) {
	currentUI.setScreenSize(currentUI.width, currentUI.height, currentUI.scale, fullscreen)
}

func IsFullscreen() bool {
	return currentUI.fullscreen
}

func SetRunnableInBackground(runnableInBackground bool) {
	currentUI.runnableInBackground = runnableInBackground
}

func IsRunnableInBackground() bool {
	return currentUI.runnableInBackground
}

func ScreenPadding() (x0, y0, x1, y1 float64) {
	return 0, 0, 0, 0
}

func adjustPosition(x, y int) (int, int) {
	rect := canvas.Call("getBoundingClientRect")
	x -= rect.Get("left").Int()
	y -= rect.Get("top").Int()
	scale := currentUI.getScale()
	return int(float64(x) / scale), int(float64(y) / scale)
}

func AdjustedCursorPosition() (x, y int) {
	return adjustPosition(input.Get().CursorPosition())
}

func AdjustedTouches() []*input.Touch {
	ts := input.Get().Touches()
	adjusted := make([]*input.Touch, len(ts))
	for i, t := range ts {
		x, y := adjustPosition(t.Position())
		adjusted[i] = input.NewTouch(t.ID(), x, y)
	}
	return adjusted
}

func IsCursorVisible() bool {
	// The initial value is an empty string, so don't compare with "auto" here.
	return canvas.Get("style").Get("cursor").String() != "none"
}

func SetCursorVisible(visible bool) {
	if visible {
		canvas.Get("style").Set("cursor", "auto")
	} else {
		canvas.Get("style").Set("cursor", "none")
	}
}

func SetWindowTitle(title string) {
	doc := js.Global.Get("document")
	doc.Set("title", title)
}

func SetWindowIcon(iconImages []image.Image) {
	// Do nothing
}

func IsWindowDecorated() bool {
	return false
}

func SetWindowDecorated(decorated bool) {
	// Do nothing
}

func (u *userInterface) getScale() float64 {
	if !u.fullscreen {
		return u.scale
	}
	doc := js.Global.Get("document")
	body := doc.Get("body")
	bw := body.Get("clientWidth").Float()
	bh := body.Get("clientHeight").Float()
	sw := bw / float64(u.width)
	sh := bh / float64(u.height)
	if sw > sh {
		return sh
	}
	return sw
}

func (u *userInterface) actualScreenScale() float64 {
	// CSS imageRendering property seems useful to enlarge the screen,
	// but doesn't work in some cases (#306):
	// * Chrome just after restoring the lost context
	// * Safari
	// Let's use the devicePixelRatio as it is here.
	return u.getScale() * devicescale.DeviceScale()
}

func (u *userInterface) updateGraphicsContext(g GraphicsContext) {
	if u.sizeChanged {
		u.sizeChanged = false
		g.SetSize(u.width, u.height, u.actualScreenScale())
	}
}

func (u *userInterface) suspended() bool {
	return !u.runnableInBackground && (!u.windowFocus || !u.pageVisible)
}

func (u *userInterface) update(g GraphicsContext) error {
	if u.suspended() {
		hooks.SuspendAudio()
		return nil
	}
	hooks.ResumeAudio()

	if opengl.GetContext().IsContextLost() {
		opengl.GetContext().RestoreContext()
		g.Invalidate()

		// Need to return once to wait restored (#526)
		// TODO: Is it necessary to handle webglcontextrestored event?
		return nil
	}

	input.Get().UpdateGamepads()
	u.updateGraphicsContext(g)
	if err := g.Update(func() {
		input.Get().ClearRuneBuffer()
		// The offscreens must be updated every frame (#490).
		u.updateGraphicsContext(g)
	}); err != nil {
		return err
	}
	return nil
}

func (u *userInterface) loop(g GraphicsContext) error {
	ch := make(chan error)
	var f func([]js.Value)
	var cf js.Callback
	f = func([]js.Value) {
		if err := u.update(g); err != nil {
			go func() {
				ch <- err
				close(ch)
			}()
			return
		}
		js.Global.Get("window").Call("requestAnimationFrame", cf)
	}
	cf = js.NewCallback(f)
	f(nil)
	return <-ch
}

func init() {
	// Do nothing in node.js.
	if web.IsNodeJS() {
		return
	}
	doc := js.Global.Get("document")
	window := js.Global.Get("window")
	if doc.Get("body") == js.Null {
		ch := make(chan struct{})
		window.Call("addEventListener", "load", js.NewCallback(func([]js.Value) {
			close(ch)
		}))
		<-ch
	}

	window.Call("addEventListener", "focus", js.NewCallback(func([]js.Value) {
		currentUI.windowFocus = true
		if currentUI.suspended() {
			hooks.SuspendAudio()
		} else {
			hooks.ResumeAudio()
		}
	}))
	window.Call("addEventListener", "blur", js.NewCallback(func([]js.Value) {
		currentUI.windowFocus = false
		if currentUI.suspended() {
			hooks.SuspendAudio()
		} else {
			hooks.ResumeAudio()
		}
	}))
	doc.Call("addEventListener", "visibilitychange", js.NewCallback(func([]js.Value) {
		currentUI.pageVisible = !doc.Get("hidden").Bool()
		if currentUI.suspended() {
			hooks.SuspendAudio()
		} else {
			hooks.ResumeAudio()
		}
	}))
	window.Call("addEventListener", "resize", js.NewCallback(func([]js.Value) {
		currentUI.updateScreenSize()
	}))

	// Adjust the initial scale to 1.
	// https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
	meta := doc.Call("createElement", "meta")
	meta.Set("name", "viewport")
	meta.Set("content", "width=device-width, initial-scale=1")
	doc.Get("head").Call("appendChild", meta)

	canvas = doc.Call("createElement", "canvas")
	canvas.Set("width", 16)
	canvas.Set("height", 16)
	doc.Get("body").Call("appendChild", canvas)

	htmlStyle := doc.Get("documentElement").Get("style")
	htmlStyle.Set("height", "100%")
	htmlStyle.Set("margin", "0")
	htmlStyle.Set("padding", "0")

	bodyStyle := doc.Get("body").Get("style")
	bodyStyle.Set("backgroundColor", "#000")
	bodyStyle.Set("position", "relative")
	bodyStyle.Set("height", "100%")
	bodyStyle.Set("margin", "0")
	bodyStyle.Set("padding", "0")
	// TODO: This is OK as long as the game is in an independent iframe.
	// What if the canvas is embedded in a HTML directly?
	doc.Get("body").Call("addEventListener", "click", js.NewCallback(func([]js.Value) {
		canvas.Call("focus")
	}))

	canvasStyle := canvas.Get("style")
	canvasStyle.Set("position", "absolute")

	// Make the canvas focusable.
	canvas.Call("setAttribute", "tabindex", 1)
	canvas.Get("style").Set("outline", "none")

	// Keyboard
	canvas.Call("addEventListener", "keydown", js.NewEventCallback(true, false, false, input.OnKeyDown))
	canvas.Call("addEventListener", "keypress", js.NewEventCallback(true, false, false, input.OnKeyPress))
	canvas.Call("addEventListener", "keyup", js.NewEventCallback(true, false, false, input.OnKeyUp))

	// Mouse
	canvas.Call("addEventListener", "mousedown", js.NewEventCallback(true, false, false, input.OnMouseDown))
	canvas.Call("addEventListener", "mouseup", js.NewEventCallback(true, false, false, input.OnMouseUp))
	canvas.Call("addEventListener", "mousemove", js.NewEventCallback(true, false, false, input.OnMouseMove))

	// Touch
	canvas.Call("addEventListener", "touchstart", js.NewEventCallback(true, false, false, input.OnTouchStart))
	canvas.Call("addEventListener", "touchend", js.NewEventCallback(true, false, false, input.OnTouchEnd))
	canvas.Call("addEventListener", "touchmove", js.NewEventCallback(true, false, false, input.OnTouchMove))

	// Gamepad
	window.Call("addEventListener", "gamepadconnected", js.NewCallback(func(e []js.Value) {
		// Do nothing.
	}))

	canvas.Call("addEventListener", "contextmenu", js.NewEventCallback(true, false, false, func(js.Value) {
		// Do nothing.
	}))

	canvas.Call("addEventListener", "webglcontextlost", js.NewEventCallback(true, false, false, func(js.Value) {
		// Do nothing.
	}))
	canvas.Call("addEventListener", "webglcontextrestored", js.NewCallback(func(e []js.Value) {
		// Do nothing.
	}))
}

func RunMainThreadLoop(ch <-chan error) error {
	return <-ch
}

func Run(width, height int, scale float64, title string, g GraphicsContext, mainloop bool) error {
	u := currentUI
	doc := js.Global.Get("document")
	doc.Set("title", title)
	u.setScreenSize(width, height, scale, u.fullscreen)
	canvas.Call("focus")
	if err := opengl.Init(); err != nil {
		return err
	}
	return u.loop(g)
}

func (u *userInterface) setScreenSize(width, height int, scale float64, fullscreen bool) bool {
	if u.width == width && u.height == height &&
		u.scale == scale && fullscreen == u.fullscreen {
		return false
	}
	u.width = width
	u.height = height
	u.scale = scale
	u.fullscreen = fullscreen
	u.updateScreenSize()
	return true
}

func (u *userInterface) updateScreenSize() {
	canvas.Set("width", int(float64(u.width)*u.actualScreenScale()))
	canvas.Set("height", int(float64(u.height)*u.actualScreenScale()))
	canvasStyle := canvas.Get("style")

	s := u.getScale()
	cssWidth := int(float64(u.width) * s)
	cssHeight := int(float64(u.height) * s)
	canvasStyle.Set("width", strconv.Itoa(cssWidth)+"px")
	canvasStyle.Set("height", strconv.Itoa(cssHeight)+"px")
	// CSS calc requires space chars.
	canvasStyle.Set("left", "calc((100% - "+strconv.Itoa(cssWidth)+"px) / 2)")
	canvasStyle.Set("top", "calc((100% - "+strconv.Itoa(cssHeight)+"px) / 2)")

	u.sizeChanged = true
}
<|endoftext|>


<commit_before>package workload

import (
	"fmt"
	"io"
	"math/rand"

	"golang.org/x/net/context"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pfs/pfsutil"
	"github.com/pachyderm/pachyderm/src/pps"
	"github.com/pachyderm/pachyderm/src/pps/ppsutil"
)

func RunWorkload(
	pfsClient pfs.APIClient,
	ppsClient pps.APIClient,
	rand *rand.Rand,
	size int,
) error {
	worker := newWorker(rand)
	for i := 0; i < size; i++ {
		if err := worker.work(pfsClient, ppsClient); err != nil {
			return err
		}
	}
	for _, job := range worker.startedJobs {
		jobInfo, err := ppsClient.InspectJob(
			context.Background(),
			&pps.InspectJobRequest{
				Job:        job,
				BlockState: true,
			},
		)
		if err != nil {
			return err
		}
		if jobInfo.State != pps.JobState_JOB_STATE_SUCCESS {
			return fmt.Errorf("job %s failed", job.Id)
		}
	}
	return nil
}

type worker struct {
	repos       []*pfs.Repo
	finished    []*pfs.Commit
	started     []*pfs.Commit
	files       []*pfs.File
	startedJobs []*pps.Job
	jobs        []*pps.Job
	pipelines   []*pps.Pipeline
	rand        *rand.Rand
}

func newWorker(rand *rand.Rand) *worker {
	return &worker{
		rand: rand,
	}
}

const (
	repo     float64 = .02
	commit           = .1
	file             = .9
	job              = .98
	pipeline         = 1.0
)

const maxStartedCommits = 6
const maxStartedJobs = 6

func (w *worker) work(pfsClient pfs.APIClient, ppsClient pps.APIClient) error {
	opt := w.rand.Float64()
	switch {
	case opt < repo:
		repoName := w.randString(10)
		if err := pfsutil.CreateRepo(pfsClient, repoName); err != nil {
			return err
		}
		w.repos = append(w.repos, &pfs.Repo{Name: repoName})
		commit, err := pfsutil.StartCommit(pfsClient, repoName, "")
		if err != nil {
			return err
		}
		w.started = append(w.started, commit)
	case opt < commit:
		if len(w.started) >= maxStartedCommits || len(w.finished) == 0 {
			if len(w.started) == 0 {
				return nil
			}
			i := w.rand.Intn(len(w.started))
			commit := w.started[i]
			if err := pfsutil.FinishCommit(pfsClient, commit.Repo.Name, commit.Id); err != nil {
				return err
			}
			w.started = append(w.started[:i], w.started[i+1:]...)
			w.finished = append(w.finished, commit)
		} else {
			if len(w.finished) == 0 {
				return nil
			}
			commit := w.finished[w.rand.Intn(len(w.finished))]
			commit, err := pfsutil.StartCommit(pfsClient, commit.Repo.Name, commit.Id)
			if err != nil {
				return err
			}
			w.started = append(w.started, commit)
		}
	case opt < file:
		if len(w.started) == 0 {
			return nil
		}
		commit := w.started[w.rand.Intn(len(w.started))]
		if _, err := pfsutil.PutFile(pfsClient, commit.Repo.Name, commit.Id, w.randString(10), 0, w.reader()); err != nil {
			return err
		}
	case opt < job:
		if len(w.startedJobs) >= maxStartedJobs {
			job := w.startedJobs[0]
			w.startedJobs = w.startedJobs[1:]
			jobInfo, err := ppsClient.InspectJob(
				context.Background(),
				&pps.InspectJobRequest{
					Job:        job,
					BlockState: true,
				},
			)
			if err != nil {
				return err
			}
			if jobInfo.State != pps.JobState_JOB_STATE_SUCCESS {
				return fmt.Errorf("job %s failed", job.Id)
			}
			w.jobs = append(w.jobs, job)
		} else {
			if len(w.finished) == 0 {
				return nil
			}
			inputs := [5]string{}
			var jobInputs []*pps.JobInput
			repoSet := make(map[string]bool)
			for i := range inputs {
				commit := w.finished[w.rand.Intn(len(w.finished))]
				if _, ok := repoSet[commit.Repo.Name]; ok {
					continue
				}
				repoSet[commit.Repo.Name] = true
				inputs[i] = commit.Repo.Name
				jobInputs = append(jobInputs, &pps.JobInput{Commit: commit})
			}
			var parentJobID string
			if len(w.jobs) > 0 {
				parentJobID = w.jobs[w.rand.Intn(len(w.jobs))].Id
			}
			outFilename := w.randString(10)
			job, err := ppsutil.CreateJob(
				ppsClient,
				"",
				[]string{"bash"},
				w.grepCmd(inputs, outFilename),
				1,
				jobInputs,
				parentJobID,
			)
			if err != nil {
				return err
			}
			w.startedJobs = append(w.startedJobs, job)
		}
	case opt < pipeline:
		if len(w.repos) == 0 {
			return nil
		}
		inputs := [5]string{}
		var pipelineInputs []*pps.PipelineInput
		repoSet := make(map[string]bool)
		for i := range inputs {
			repo := w.repos[w.rand.Intn(len(w.repos))]
			if _, ok := repoSet[repo.Name]; ok {
				continue
			}
			repoSet[repo.Name] = true
			inputs[i] = repo.Name
			pipelineInputs = append(pipelineInputs, &pps.PipelineInput{Repo: repo})
		}
		pipelineName := w.randString(10)
		outFilename := w.randString(10)
		if err := ppsutil.CreatePipeline(
			ppsClient,
			pipelineName,
			"",
			[]string{"bash"},
			w.grepCmd(inputs, outFilename),
			1,
			pipelineInputs,
		); err != nil {
			return err
		}
		w.pipelines = append(w.pipelines, ppsutil.NewPipeline(pipelineName))
	}
	return nil
}

const letters = "abcdefghijklmnopqrstuvwxyz"
const lettersAndSpaces = "abcdefghijklmnopqrstuvwxyz      "

func (w *worker) randString(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letters[w.rand.Intn(len(letters))]
	}
	return string(b)
}

type reader struct {
	rand  *rand.Rand
	lines int
}

func NewReader(rand *rand.Rand, lines int) io.Reader {
	return &reader{
		rand:  rand,
		lines: lines,
	}
}

func (r *reader) Read(p []byte) (int, error) {
	for i := range p {
		if i%128 == 127 {
			p[i] = '\n'
			r.lines--
		} else {
			p[i] = lettersAndSpaces[r.rand.Intn(len(lettersAndSpaces))]
		}
	}
	p[len(p)-1] = '\n'
	if r.lines <= 0 {
		return len(p), io.EOF
	}
	return len(p), nil
}

func (w *worker) reader() io.Reader {
	return NewReader(w.rand, 1000)
}

func (w *worker) grepCmd(inputs [5]string, outFilename string) string {
	return fmt.Sprintf(
		"grep %s /pfs/{%s,%s,%s,%s,%s}/* >/pfs/out/%s; true",
		w.randString(4),
		inputs[0],
		inputs[1],
		inputs[2],
		inputs[3],
		inputs[4],
		outFilename,
	)
}
<commit_msg>Do bytes instead of lines.<commit_after>package workload

import (
	"fmt"
	"io"
	"math/rand"

	"golang.org/x/net/context"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pfs/pfsutil"
	"github.com/pachyderm/pachyderm/src/pps"
	"github.com/pachyderm/pachyderm/src/pps/ppsutil"
)

func RunWorkload(
	pfsClient pfs.APIClient,
	ppsClient pps.APIClient,
	rand *rand.Rand,
	size int,
) error {
	worker := newWorker(rand)
	for i := 0; i < size; i++ {
		if err := worker.work(pfsClient, ppsClient); err != nil {
			return err
		}
	}
	for _, job := range worker.startedJobs {
		jobInfo, err := ppsClient.InspectJob(
			context.Background(),
			&pps.InspectJobRequest{
				Job:        job,
				BlockState: true,
			},
		)
		if err != nil {
			return err
		}
		if jobInfo.State != pps.JobState_JOB_STATE_SUCCESS {
			return fmt.Errorf("job %s failed", job.Id)
		}
	}
	return nil
}

type worker struct {
	repos       []*pfs.Repo
	finished    []*pfs.Commit
	started     []*pfs.Commit
	files       []*pfs.File
	startedJobs []*pps.Job
	jobs        []*pps.Job
	pipelines   []*pps.Pipeline
	rand        *rand.Rand
}

func newWorker(rand *rand.Rand) *worker {
	return &worker{
		rand: rand,
	}
}

const (
	repo     float64 = .02
	commit           = .1
	file             = .9
	job              = .98
	pipeline         = 1.0
)

const maxStartedCommits = 6
const maxStartedJobs = 6

func (w *worker) work(pfsClient pfs.APIClient, ppsClient pps.APIClient) error {
	opt := w.rand.Float64()
	switch {
	case opt < repo:
		repoName := w.randString(10)
		if err := pfsutil.CreateRepo(pfsClient, repoName); err != nil {
			return err
		}
		w.repos = append(w.repos, &pfs.Repo{Name: repoName})
		commit, err := pfsutil.StartCommit(pfsClient, repoName, "")
		if err != nil {
			return err
		}
		w.started = append(w.started, commit)
	case opt < commit:
		if len(w.started) >= maxStartedCommits || len(w.finished) == 0 {
			if len(w.started) == 0 {
				return nil
			}
			i := w.rand.Intn(len(w.started))
			commit := w.started[i]
			if err := pfsutil.FinishCommit(pfsClient, commit.Repo.Name, commit.Id); err != nil {
				return err
			}
			w.started = append(w.started[:i], w.started[i+1:]...)
			w.finished = append(w.finished, commit)
		} else {
			if len(w.finished) == 0 {
				return nil
			}
			commit := w.finished[w.rand.Intn(len(w.finished))]
			commit, err := pfsutil.StartCommit(pfsClient, commit.Repo.Name, commit.Id)
			if err != nil {
				return err
			}
			w.started = append(w.started, commit)
		}
	case opt < file:
		if len(w.started) == 0 {
			return nil
		}
		commit := w.started[w.rand.Intn(len(w.started))]
		if _, err := pfsutil.PutFile(pfsClient, commit.Repo.Name, commit.Id, w.randString(10), 0, w.reader()); err != nil {
			return err
		}
	case opt < job:
		if len(w.startedJobs) >= maxStartedJobs {
			job := w.startedJobs[0]
			w.startedJobs = w.startedJobs[1:]
			jobInfo, err := ppsClient.InspectJob(
				context.Background(),
				&pps.InspectJobRequest{
					Job:        job,
					BlockState: true,
				},
			)
			if err != nil {
				return err
			}
			if jobInfo.State != pps.JobState_JOB_STATE_SUCCESS {
				return fmt.Errorf("job %s failed", job.Id)
			}
			w.jobs = append(w.jobs, job)
		} else {
			if len(w.finished) == 0 {
				return nil
			}
			inputs := [5]string{}
			var jobInputs []*pps.JobInput
			repoSet := make(map[string]bool)
			for i := range inputs {
				commit := w.finished[w.rand.Intn(len(w.finished))]
				if _, ok := repoSet[commit.Repo.Name]; ok {
					continue
				}
				repoSet[commit.Repo.Name] = true
				inputs[i] = commit.Repo.Name
				jobInputs = append(jobInputs, &pps.JobInput{Commit: commit})
			}
			var parentJobID string
			if len(w.jobs) > 0 {
				parentJobID = w.jobs[w.rand.Intn(len(w.jobs))].Id
			}
			outFilename := w.randString(10)
			job, err := ppsutil.CreateJob(
				ppsClient,
				"",
				[]string{"bash"},
				w.grepCmd(inputs, outFilename),
				1,
				jobInputs,
				parentJobID,
			)
			if err != nil {
				return err
			}
			w.startedJobs = append(w.startedJobs, job)
		}
	case opt < pipeline:
		if len(w.repos) == 0 {
			return nil
		}
		inputs := [5]string{}
		var pipelineInputs []*pps.PipelineInput
		repoSet := make(map[string]bool)
		for i := range inputs {
			repo := w.repos[w.rand.Intn(len(w.repos))]
			if _, ok := repoSet[repo.Name]; ok {
				continue
			}
			repoSet[repo.Name] = true
			inputs[i] = repo.Name
			pipelineInputs = append(pipelineInputs, &pps.PipelineInput{Repo: repo})
		}
		pipelineName := w.randString(10)
		outFilename := w.randString(10)
		if err := ppsutil.CreatePipeline(
			ppsClient,
			pipelineName,
			"",
			[]string{"bash"},
			w.grepCmd(inputs, outFilename),
			1,
			pipelineInputs,
		); err != nil {
			return err
		}
		w.pipelines = append(w.pipelines, ppsutil.NewPipeline(pipelineName))
	}
	return nil
}

const letters = "abcdefghijklmnopqrstuvwxyz"
const lettersAndSpaces = "abcdefghijklmnopqrstuvwxyz      "

func (w *worker) randString(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letters[w.rand.Intn(len(letters))]
	}
	return string(b)
}

type reader struct {
	rand  *rand.Rand
	bytes int
}

func NewReader(rand *rand.Rand, bytes int) io.Reader {
	return &reader{
		rand:  rand,
		bytes: bytes,
	}
}

func (r *reader) Read(p []byte) (int, error) {
	for i := range p {
		if i%128 == 127 {
			p[i] = '\n'
		} else {
			p[i] = lettersAndSpaces[r.rand.Intn(len(lettersAndSpaces))]
		}
	}
	p[len(p)-1] = '\n'
	r.bytes -= len(p)
	if r.bytes <= 0 {
		return len(p), io.EOF
	}
	return len(p), nil
}

func (w *worker) reader() io.Reader {
	return NewReader(w.rand, 1000)
}

func (w *worker) grepCmd(inputs [5]string, outFilename string) string {
	return fmt.Sprintf(
		"grep %s /pfs/{%s,%s,%s,%s,%s}/* >/pfs/out/%s; true",
		w.randString(4),
		inputs[0],
		inputs[1],
		inputs[2],
		inputs[3],
		inputs[4],
		outFilename,
	)
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"io"
	"io/ioutil"
	"net"

	"github.com/spf13/cobra"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	genericapiserver "k8s.io/apiserver/pkg/server"
	genericoptions "k8s.io/apiserver/pkg/server/options"
	"k8s.io/kubernetes/pkg/kubectl/cmd/util"

	"github.com/openshift/origin/pkg/template/servicebroker/apis/config"
	configinstall "github.com/openshift/origin/pkg/template/servicebroker/apis/config/install"
	"github.com/openshift/origin/pkg/templateservicebroker/openservicebroker/server"
)

type TemplateServiceBrokerServerOptions struct {
	// we don't have any storage, so we shouldn't use the recommended options
	SecureServing  *genericoptions.SecureServingOptionsWithLoopback
	Authentication *genericoptions.DelegatingAuthenticationOptions
	Authorization  *genericoptions.DelegatingAuthorizationOptions
	Audit          *genericoptions.AuditOptions
	Features       *genericoptions.FeatureOptions

	StdOut io.Writer
	StdErr io.Writer

	TSBConfig *config.TemplateServiceBrokerConfig
}

func NewTemplateServiceBrokerServerOptions(out, errOut io.Writer) *TemplateServiceBrokerServerOptions {
	o := &TemplateServiceBrokerServerOptions{
		SecureServing:  genericoptions.WithLoopback(genericoptions.NewSecureServingOptions()),
		Authentication: genericoptions.NewDelegatingAuthenticationOptions(),
		Authorization:  genericoptions.NewDelegatingAuthorizationOptions(),
		Audit:          genericoptions.NewAuditOptions(),
		Features:       genericoptions.NewFeatureOptions(),

		StdOut: out,
		StdErr: errOut,
	}

	return o
}

func NewCommandStartTemplateServiceBrokerServer(out, errOut io.Writer, stopCh <-chan struct{}) *cobra.Command {
	o := NewTemplateServiceBrokerServerOptions(out, errOut)

	cmd := &cobra.Command{
		Use:   "template-service-broker",
		Short: "Launch a template service broker server",
		Long:  "Launch a template service broker server",
		RunE: func(c *cobra.Command, args []string) error {
			if err := o.Complete(c); err != nil {
				return err
			}
			if err := o.Validate(args); err != nil {
				return err
			}
			if err := o.RunTemplateServiceBrokerServer(stopCh); err != nil {
				return err
			}
			return nil
		},
	}

	flags := cmd.Flags()
	o.SecureServing.AddFlags(flags)
	o.Authentication.AddFlags(flags)
	o.Authorization.AddFlags(flags)
	o.Audit.AddFlags(flags)
	o.Features.AddFlags(flags)
	flags.String("config", "", "filename containing the TemplateServiceBrokerConfig")

	return cmd
}

func (o TemplateServiceBrokerServerOptions) Validate(args []string) error {
	if o.TSBConfig == nil {
		return fmt.Errorf("missing config: specify --config")
	}
	if len(o.TSBConfig.TemplateNamespaces) == 0 {
		return fmt.Errorf("templateNamespaces are required")
	}

	return nil
}

func (o *TemplateServiceBrokerServerOptions) Complete(cmd *cobra.Command) error {
	configFile := util.GetFlagString(cmd, "config")
	if len(configFile) > 0 {
		content, err := ioutil.ReadFile(configFile)
		if err != nil {
			return err
		}
		configObj, err := runtime.Decode(configCodecs.UniversalDecoder(), content)
		if err != nil {
			return err
		}
		config, ok := configObj.(*config.TemplateServiceBrokerConfig)
		if !ok {
			return fmt.Errorf("unexpected type: %T", configObj)
		}
		o.TSBConfig = config
	}

	return nil
}

func (o TemplateServiceBrokerServerOptions) Config() (*server.TemplateServiceBrokerConfig, error) {
	// TODO have a "real" external address
	if err := o.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil {
		return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
	}

	serverConfig := genericapiserver.NewConfig(server.Codecs)
	if err := o.SecureServing.ApplyTo(serverConfig); err != nil {
		return nil, err
	}
	if err := o.Authentication.ApplyTo(&serverConfig.Authentication, serverConfig.SecureServing, serverConfig.OpenAPIConfig); err != nil {
		return nil, err
	}
	if err := o.Authorization.ApplyTo(&serverConfig.Authorization); err != nil {
		return nil, err
	}
	if err := o.Audit.ApplyTo(serverConfig); err != nil {
		return nil, err
	}
	if err := o.Features.ApplyTo(serverConfig); err != nil {
		return nil, err
	}

	serverConfig.EnableMetrics = true

	config := &server.TemplateServiceBrokerConfig{
		GenericConfig: &genericapiserver.RecommendedConfig{Config: *serverConfig},

		ExtraConfig: server.ExtraConfig{TemplateNamespaces: o.TSBConfig.TemplateNamespaces},
		// TODO add the code to set up the client and informers that you need here
	}
	return config, nil
}

func (o TemplateServiceBrokerServerOptions) RunTemplateServiceBrokerServer(stopCh <-chan struct{}) error {
	config, err := o.Config()
	if err != nil {
		return err
	}

	server, err := config.Complete().New(genericapiserver.NewEmptyDelegate())
	if err != nil {
		return err
	}
	return server.GenericAPIServer.PrepareRun().Run(stopCh)
}

// these are used to set up for reading the config
var (
	configScheme = runtime.NewScheme()
	configCodecs = serializer.NewCodecFactory(configScheme)
)

func init() {
	configinstall.Install(configScheme)
}
<commit_msg>Template servicebroker wiring<commit_after>package server

import (
	"fmt"
	"io"
	"io/ioutil"
	"net"

	"github.com/spf13/cobra"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	genericapiserver "k8s.io/apiserver/pkg/server"
	genericoptions "k8s.io/apiserver/pkg/server/options"
	"k8s.io/kubernetes/pkg/kubectl/cmd/util"

	"github.com/openshift/origin/pkg/template/servicebroker/apis/config"
	configinstall "github.com/openshift/origin/pkg/template/servicebroker/apis/config/install"
	"github.com/openshift/origin/pkg/templateservicebroker/openservicebroker/server"
)

type TemplateServiceBrokerServerOptions struct {
	// we don't have any storage, so we shouldn't use the recommended options
	SecureServing  *genericoptions.SecureServingOptionsWithLoopback
	Authentication *genericoptions.DelegatingAuthenticationOptions
	Authorization  *genericoptions.DelegatingAuthorizationOptions
	Audit          *genericoptions.AuditOptions
	Features       *genericoptions.FeatureOptions

	StdOut io.Writer
	StdErr io.Writer

	TSBConfig *config.TemplateServiceBrokerConfig
}

func NewTemplateServiceBrokerServerOptions(out, errOut io.Writer) *TemplateServiceBrokerServerOptions {
	o := &TemplateServiceBrokerServerOptions{
		SecureServing:  genericoptions.NewSecureServingOptions().WithLoopback(),
		Authentication: genericoptions.NewDelegatingAuthenticationOptions(),
		Authorization:  genericoptions.NewDelegatingAuthorizationOptions(),
		Audit:          genericoptions.NewAuditOptions(),
		Features:       genericoptions.NewFeatureOptions(),

		StdOut: out,
		StdErr: errOut,
	}

	return o
}

func NewCommandStartTemplateServiceBrokerServer(out, errOut io.Writer, stopCh <-chan struct{}) *cobra.Command {
	o := NewTemplateServiceBrokerServerOptions(out, errOut)

	cmd := &cobra.Command{
		Use:   "template-service-broker",
		Short: "Launch a template service broker server",
		Long:  "Launch a template service broker server",
		RunE: func(c *cobra.Command, args []string) error {
			if err := o.Complete(c); err != nil {
				return err
			}
			if err := o.Validate(args); err != nil {
				return err
			}
			if err := o.RunTemplateServiceBrokerServer(stopCh); err != nil {
				return err
			}
			return nil
		},
	}

	flags := cmd.Flags()
	o.SecureServing.AddFlags(flags)
	o.Authentication.AddFlags(flags)
	o.Authorization.AddFlags(flags)
	o.Audit.AddFlags(flags)
	o.Features.AddFlags(flags)
	flags.String("config", "", "filename containing the TemplateServiceBrokerConfig")

	return cmd
}

func (o TemplateServiceBrokerServerOptions) Validate(args []string) error {
	if o.TSBConfig == nil {
		return fmt.Errorf("missing config: specify --config")
	}
	if len(o.TSBConfig.TemplateNamespaces) == 0 {
		return fmt.Errorf("templateNamespaces are required")
	}

	return nil
}

func (o *TemplateServiceBrokerServerOptions) Complete(cmd *cobra.Command) error {
	configFile := util.GetFlagString(cmd, "config")
	if len(configFile) > 0 {
		content, err := ioutil.ReadFile(configFile)
		if err != nil {
			return err
		}
		configObj, err := runtime.Decode(configCodecs.UniversalDecoder(), content)
		if err != nil {
			return err
		}
		config, ok := configObj.(*config.TemplateServiceBrokerConfig)
		if !ok {
			return fmt.Errorf("unexpected type: %T", configObj)
		}
		o.TSBConfig = config
	}

	return nil
}

func (o TemplateServiceBrokerServerOptions) Config() (*server.TemplateServiceBrokerConfig, error) {
	// TODO have a "real" external address
	if err := o.SecureServing.MaybeDefaultWithSelfSignedCerts("localhost", nil, []net.IP{net.ParseIP("127.0.0.1")}); err != nil {
		return nil, fmt.Errorf("error creating self-signed certificates: %v", err)
	}

	serverConfig := genericapiserver.NewConfig(server.Codecs)
	if err := o.SecureServing.ApplyTo(&serverConfig.SecureServing, &serverConfig.LoopbackClientConfig); err != nil {
		return nil, err
	}
	if err := o.Authentication.ApplyTo(&serverConfig.Authentication, serverConfig.SecureServing, serverConfig.OpenAPIConfig); err != nil {
		return nil, err
	}
	if err := o.Authorization.ApplyTo(&serverConfig.Authorization); err != nil {
		return nil, err
	}
	if err := o.Audit.ApplyTo(serverConfig); err != nil {
		return nil, err
	}
	if err := o.Features.ApplyTo(serverConfig); err != nil {
		return nil, err
	}

	serverConfig.EnableMetrics = true

	config := &server.TemplateServiceBrokerConfig{
		GenericConfig: &genericapiserver.RecommendedConfig{Config: *serverConfig},

		ExtraConfig: server.ExtraConfig{TemplateNamespaces: o.TSBConfig.TemplateNamespaces},
		// TODO add the code to set up the client and informers that you need here
	}
	return config, nil
}

func (o TemplateServiceBrokerServerOptions) RunTemplateServiceBrokerServer(stopCh <-chan struct{}) error {
	config, err := o.Config()
	if err != nil {
		return err
	}

	server, err := config.Complete().New(genericapiserver.NewEmptyDelegate())
	if err != nil {
		return err
	}
	return server.GenericAPIServer.PrepareRun().Run(stopCh)
}

// these are used to set up for reading the config
var (
	configScheme = runtime.NewScheme()
	configCodecs = serializer.NewCodecFactory(configScheme)
)

func init() {
	configinstall.Install(configScheme)
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"fmt"
	"log"
	"reflect"
	"strings"

	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
)

type Vehiculo struct {
	Id            int          `orm:"column(id);pk;auto"`
	Placa         string       `orm:"column(placa)"`
	IdNfc         int          `orm:"column(id_nfc)"`
	IdPropietario *Propietario `orm:"column(id_propietario);rel(fk)"`
}

func (t *Vehiculo) TableName() string {
	return "vehiculo"
}

func init() {
	orm.RegisterModel(new(Vehiculo))
}

// AddVehiculo insert a new Vehiculo into database and returns
// last inserted Id on success.
func AddVehiculo(m *Vehiculo) (id int64, err error) {
	o := orm.NewOrm()
	valid := validation.Validation{}
	valid.Required(m.Placa, "Placa")
	valid.MaxSize(m.Placa, 6, "PlacaMax")
	valid.Required(m.IdNfc, "IdNfc")
	valid.AlphaNumeric(m.Placa, "PlacaAlphaNum")
	if valid.HasErrors() {
		for _, err := range valid.Errors {
			log.Println(err.Key, err.Message)
		}
	} else {
		log.Println("Insert New Register")
		m.IdPropietario, _ = GetPropietarioById(m.IdPropietario.Id)
		id, err = o.Insert(m)
	}
	return
}

// GetVehiculoById retrieves Vehiculo by Id. Returns error if
// Id doesn't exist
func GetVehiculoById(id int) (v *Vehiculo, err error) {
	o := orm.NewOrm()
	v = &Vehiculo{Id: id}
	if err = o.Read(v); err == nil {
		v.IdPropietario, _ = GetPropietarioById(v.IdPropietario.Id)
		return v, nil
	}
	return nil, err
}

// GetAllVehiculo retrieves all Vehiculo matches certain condition. Returns empty list if
// no records exist
func GetAllVehiculo(query map[string]string, fields []string, sortby []string, order []string,
	offset int64, limit int64) (ml []interface{}, err error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(Vehiculo))
	// query k=v
	for k, v := range query {
		// rewrite dot-notation to Object__Attribute
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	// order by:
	var sortFields []string
	if len(sortby) != 0 {
		if len(sortby) == len(order) {
			// 1) for each sort field, there is an associated order
			for i, v := range sortby {
				orderby := ""
				if order[i] == "desc" {
					orderby = "-" + v
				} else if order[i] == "asc" {
					orderby = v
				} else {
					return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
				}
				sortFields = append(sortFields, orderby)
			}
			qs = qs.OrderBy(sortFields...)
		} else if len(sortby) != len(order) && len(order) == 1 {
			// 2) there is exactly one order, all the sorted fields will be sorted by this order
			for _, v := range sortby {
				orderby := ""
				if order[0] == "desc" {
					orderby = "-" + v
				} else if order[0] == "asc" {
					orderby = v
				} else {
					return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
				}
				sortFields = append(sortFields, orderby)
			}
		} else if len(sortby) != len(order) && len(order) != 1 {
			return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
		}
	} else {
		if len(order) != 0 {
			return nil, errors.New("Error: unused 'order' fields")
		}
	}

	var l []Vehiculo
	qs = qs.OrderBy("id")
	if _, err := qs.Limit(limit, offset).All(&l, fields...); err == nil {
		if len(fields) == 0 {
			for _, v := range l {
				v.IdPropietario, _ = GetPropietarioById(v.IdPropietario.Id)
				ml = append(ml, v)
			}
		} else {
			// trim unused fields
			for _, v := range l {
				m := make(map[string]interface{})
				val := reflect.ValueOf(v)
				for _, fname := range fields {
					m[fname] = val.FieldByName(fname).Interface()
				}
				ml = append(ml, m)
			}
		}
		return ml, nil
	}
	return nil, err
}

// UpdateVehiculo updates Vehiculo by Id and returns error if
// the record to be updated doesn't exist
func UpdateVehiculoById(m *Vehiculo) (err error) {
	o := orm.NewOrm()
	v := Vehiculo{Id: m.Id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Update(m); err == nil {
			fmt.Println("Number of records updated in database:", num)
		}
	}
	return
}

// DeleteVehiculo deletes Vehiculo by Id and returns error if
// the record to be deleted doesn't exist
func DeleteVehiculo(id int) (err error) {
	o := orm.NewOrm()
	v := Vehiculo{Id: id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Delete(&Vehiculo{Id: id}); err == nil {
			fmt.Println("Number of records deleted in database:", num)
		}
	}
	return
}
<commit_msg>Se modifica el atributo IdNfc de int a int16<commit_after>package models

import (
	"errors"
	"fmt"
	"log"
	"reflect"
	"strings"

	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
)

type Vehiculo struct {
	Id            int          `orm:"column(id);pk;auto"`
	Placa         string       `orm:"column(placa)"`
	IdNfc         int16        `orm:"column(id_nfc)"`
	IdPropietario *Propietario `orm:"column(id_propietario);rel(fk)"`
}

func (t *Vehiculo) TableName() string {
	return "vehiculo"
}

func init() {
	orm.RegisterModel(new(Vehiculo))
}

// AddVehiculo insert a new Vehiculo into database and returns
// last inserted Id on success.
func AddVehiculo(m *Vehiculo) (id int64, err error) {
	o := orm.NewOrm()
	valid := validation.Validation{}
	valid.Required(m.Placa, "Placa")
	valid.MaxSize(m.Placa, 6, "PlacaMax")
	valid.Required(m.IdNfc, "IdNfc")
	valid.AlphaNumeric(m.Placa, "PlacaAlphaNum")
	if valid.HasErrors() {
		for _, err := range valid.Errors {
			log.Println(err.Key, err.Message)
		}
	} else {
		log.Println("Insert New Register")
		m.IdPropietario, _ = GetPropietarioById(m.IdPropietario.Id)
		id, err = o.Insert(m)
	}
	return
}

// GetVehiculoById retrieves Vehiculo by Id. Returns error if
// Id doesn't exist
func GetVehiculoById(id int) (v *Vehiculo, err error) {
	o := orm.NewOrm()
	v = &Vehiculo{Id: id}
	if err = o.Read(v); err == nil {
		v.IdPropietario, _ = GetPropietarioById(v.IdPropietario.Id)
		return v, nil
	}
	return nil, err
}

// GetAllVehiculo retrieves all Vehiculo matches certain condition. Returns empty list if
// no records exist
func GetAllVehiculo(query map[string]string, fields []string, sortby []string, order []string,
	offset int64, limit int64) (ml []interface{}, err error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(Vehiculo))
	// query k=v
	for k, v := range query {
		// rewrite dot-notation to Object__Attribute
		k = strings.Replace(k, ".", "__", -1)
		qs = qs.Filter(k, v)
	}
	// order by:
	var sortFields []string
	if len(sortby) != 0 {
		if len(sortby) == len(order) {
			// 1) for each sort field, there is an associated order
			for i, v := range sortby {
				orderby := ""
				if order[i] == "desc" {
					orderby = "-" + v
				} else if order[i] == "asc" {
					orderby = v
				} else {
					return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
				}
				sortFields = append(sortFields, orderby)
			}
			qs = qs.OrderBy(sortFields...)
		} else if len(sortby) != len(order) && len(order) == 1 {
			// 2) there is exactly one order, all the sorted fields will be sorted by this order
			for _, v := range sortby {
				orderby := ""
				if order[0] == "desc" {
					orderby = "-" + v
				} else if order[0] == "asc" {
					orderby = v
				} else {
					return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
				}
				sortFields = append(sortFields, orderby)
			}
		} else if len(sortby) != len(order) && len(order) != 1 {
			return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
		}
	} else {
		if len(order) != 0 {
			return nil, errors.New("Error: unused 'order' fields")
		}
	}

	var l []Vehiculo
	qs = qs.OrderBy("id")
	if _, err := qs.Limit(limit, offset).All(&l, fields...); err == nil {
		if len(fields) == 0 {
			for _, v := range l {
				v.IdPropietario, _ = GetPropietarioById(v.IdPropietario.Id)
				ml = append(ml, v)
			}
		} else {
			// trim unused fields
			for _, v := range l {
				m := make(map[string]interface{})
				val := reflect.ValueOf(v)
				for _, fname := range fields {
					m[fname] = val.FieldByName(fname).Interface()
				}
				ml = append(ml, m)
			}
		}
		return ml, nil
	}
	return nil, err
}

// UpdateVehiculo updates Vehiculo by Id and returns error if
// the record to be updated doesn't exist
func UpdateVehiculoById(m *Vehiculo) (err error) {
	o := orm.NewOrm()
	v := Vehiculo{Id: m.Id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Update(m); err == nil {
			fmt.Println("Number of records updated in database:", num)
		}
	}
	return
}

// DeleteVehiculo deletes Vehiculo by Id and returns error if
// the record to be deleted doesn't exist
func DeleteVehiculo(id int) (err error) {
	o := orm.NewOrm()
	v := Vehiculo{Id: id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Delete(&Vehiculo{Id: id}); err == nil {
			fmt.Println("Number of records deleted in database:", num)
		}
	}
	return
}
<|endoftext|>


<commit_before>package connector

import (
	"time"

	"github.com/sendgridlabs/go-kinesis"
)

// Pipeline is used as a record processor to configure a pipline.
//
// The user should implement this such that each method returns a configured implementation of each
// interface. It has a data type (Model) as Records come in as a byte[] and are transformed to a Model.
// Then they are buffered in Model form and when the buffer is full, Models's are passed to the emitter.
type Pipeline struct {
	Buffer      Buffer
	Checkpoint  Checkpoint
	Emitter     Emitter
	Filter      Filter
	StreamName  string
	Transformer Transformer
}

// ProcessShard kicks off the process of a Kinesis Shard.
// It is a long running process that will continue to read from the shard.
func (p Pipeline) ProcessShard(ksis *kinesis.Kinesis, shardID string) {
	args := kinesis.NewArgs()
	args.Add("ShardId", shardID)
	args.Add("StreamName", p.StreamName)

	if p.Checkpoint.CheckpointExists(shardID) {
		args.Add("ShardIteratorType", "AFTER_SEQUENCE_NUMBER")
		args.Add("StartingSequenceNumber", p.Checkpoint.SequenceNumber())
	} else {
		args.Add("ShardIteratorType", "TRIM_HORIZON")
	}

	shardInfo, err := ksis.GetShardIterator(args)

	if err != nil {
		logger.Fatalf("GetShardIterator ERROR: %v\n", err)
	}

	shardIterator := shardInfo.ShardIterator

	for {
		args = kinesis.NewArgs()
		args.Add("ShardIterator", shardIterator)
		recordSet, err := ksis.GetRecords(args)

		if err != nil {
			logger.Fatalf("GetRecords ERROR: %v\n", err)
		}

		if len(recordSet.Records) > 0 {
			for _, v := range recordSet.Records {
				data := v.GetData()

				if err != nil {
					logger.Printf("GetData ERROR: %v\n", err)
					continue
				}

				r := p.Transformer.ToRecord(data)

				if p.Filter.KeepRecord(r) {
					p.Buffer.ProcessRecord(r, v.SequenceNumber)
				}
			}
		} else if recordSet.NextShardIterator == "" || shardIterator == recordSet.NextShardIterator || err != nil {
			logger.Printf("NextShardIterator ERROR: %v\n", err)
			break
		} else {
			time.Sleep(5 * time.Second)
		}

		if p.Buffer.ShouldFlush() {
			p.Emitter.Emit(p.Buffer, p.Transformer)
			p.Checkpoint.SetCheckpoint(shardID, p.Buffer.LastSequenceNumber())
			p.Buffer.Flush()
		}

		shardIterator = recordSet.NextShardIterator
	}
}
<commit_msg>Add recoverability in the Pipeline<commit_after>package connector

import (
	"math"
	"time"

	"github.com/sendgridlabs/go-kinesis"
)

// Pipeline is used as a record processor to configure a pipline.
//
// The user should implement this such that each method returns a configured implementation of each
// interface. It has a data type (Model) as Records come in as a byte[] and are transformed to a Model.
// Then they are buffered in Model form and when the buffer is full, Models's are passed to the emitter.
type Pipeline struct {
	Buffer      Buffer
	Checkpoint  Checkpoint
	Emitter     Emitter
	Filter      Filter
	StreamName  string
	Transformer Transformer
}

// determine whether the error is recoverable
func (p Pipeline) isRecoverableError(err error) bool {
	cErr, ok := err.(*kinesis.Error)
	if ok && cErr.Code == "ProvisionedThroughputExceeded" {
		return true
	}
	return false
}

// handle the aws exponential backoff
// http://docs.aws.amazon.com/general/latest/gr/api-retries.html
func (p Pipeline) handleAwsWaitTimeExp(attempts int) {
	// wait up to 5 minutes based on the aws exponential backoff algorithm
	logger.Printf("waitingnow")
	waitTime := time.Duration(math.Min(100*math.Pow(2, float64(attempts)), 300000)) * time.Millisecond
	time.Sleep(waitTime)
}

// ProcessShard kicks off the process of a Kinesis Shard.
// It is a long running process that will continue to read from the shard.
func (p Pipeline) ProcessShard(ksis *kinesis.Kinesis, shardID string) {
	args := kinesis.NewArgs()
	args.Add("ShardId", shardID)
	args.Add("StreamName", p.StreamName)

	if p.Checkpoint.CheckpointExists(shardID) {
		args.Add("ShardIteratorType", "AFTER_SEQUENCE_NUMBER")
		args.Add("StartingSequenceNumber", p.Checkpoint.SequenceNumber())
	} else {
		args.Add("ShardIteratorType", "TRIM_HORIZON")
	}

	shardInfo, err := ksis.GetShardIterator(args)

	if err != nil {
		logger.Fatalf("GetShardIterator ERROR: %v\n", err)
	}

	shardIterator := shardInfo.ShardIterator
	consecutiveErrorAttempts := 0

	for {
		args = kinesis.NewArgs()
		args.Add("ShardIterator", shardIterator)
		recordSet, err := ksis.GetRecords(args)

		if err != nil {
			if p.isRecoverableError(err) {
				logger.Printf("GetRecords RECOVERABLE_ERROR: %v\n", err)
				consecutiveErrorAttempts++
				p.handleAwsWaitTimeExp(consecutiveErrorAttempts)
				continue
			} else {
				logger.Fatalf("GetRecords ERROR: %v\n", err)
			}
		} else {
			consecutiveErrorAttempts = 0
		}

		if len(recordSet.Records) > 0 {
			for _, v := range recordSet.Records {
				data := v.GetData()

				if err != nil {
					logger.Printf("GetData ERROR: %v\n", err)
					continue
				}

				r := p.Transformer.ToRecord(data)

				if p.Filter.KeepRecord(r) {
					p.Buffer.ProcessRecord(r, v.SequenceNumber)
				}
			}
		} else if recordSet.NextShardIterator == "" || shardIterator == recordSet.NextShardIterator || err != nil {
			logger.Printf("NextShardIterator ERROR: %v\n", err)
			break
		} else {
			time.Sleep(5 * time.Second)
		}

		if p.Buffer.ShouldFlush() {
			p.Emitter.Emit(p.Buffer, p.Transformer)
			p.Checkpoint.SetCheckpoint(shardID, p.Buffer.LastSequenceNumber())
			p.Buffer.Flush()
		}

		shardIterator = recordSet.NextShardIterator
	}
}
<|endoftext|>