<commit_before>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("README.md", nREADME))
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile(".codeclimate.yml", nCodeClimate))

	if data["ciProvider"] == "travis" {
		g.Add(gentronics.NewFile(".travis.yml", nTravis))
	}

	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)

	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nREADME = `
# Welcome to Buffalo!

Thank you for chosing Buffalo for your web development needs.

{{#if withPop}}
## Database Setup

It looks like you chose to set up your application using a {{dbType}} database! Fantastic!

The first thing you need to do is open up the "database.yml" file and edit it to use the correct usernames, passwords, hosts, etc... that are appropriate for your environment.

You will also need to make sure that **you** start/install the database of your choice. Buffalo **won't** install and start {{dbType}} for you.

### Create Your Databases

Ok, so you've edited the "database.yml" file and started {{dbType}}, now Buffalo can create the databases in that file for you:

	$ buffalo db create -a
{{/if}}

## Starting the Application

Buffalo ships with a command that will watch your application and automatically rebuild the Go binary and any assets for you. To do that run the "buffalo dev" command:

	$ buffalo dev

If you point your browser to [http://127.0.0.1:3000](http://127.0.0.1:3000) you should see a "Welcome to Buffalo!" page.

**Congratulations!** You now have your Buffalo application up and running.

## What Next?

We recommend you heading over to [http://gobuffalo.io](http://gobuffalo.io) and reviewing all of the great documentation there.

Good luck!

[Powered by Buffalo](http://gobuffalo.io)`

const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
			SessionName: "_{{name}}_session",
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolverFunc: func() resolvers.FileResolver {
			return &resolvers.RiceBox{
				Box: rice.MustFindBox("../templates"),
			}
		},
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
.idea/
bin/
tmp/
node_modules/
.sass-cache/
rice-box.go
public/assets/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- bin
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nCodeClimate = `engines:
  fixme:
    enabled: true
  gofmt:
    enabled: true
  golint:
    enabled: true
  govet:
    enabled: true
exclude_paths:
  - grifts/**/*
  - "**/*_test.go"
  - "*_test.go"
  - "**_test.go"
  - logs/*
  - public/*
  - templates/*
ratings:
  paths:
    - "**.go"

`

const nTravis = `language: go
env:
- GO_ENV=test

before_script:
  - psql -c 'create database {{name}}_test;' -U postgres
	- mysql -e 'CREATE DATABASE {{name}}_test;'
  - mkdir -p $TRAVIS_BUILD_DIR/public/assets

go:
  - 1.7.x
  - master

go_import_path: {{ packagePath }}
`
<commit_msg>Add an empty Helpers map to actions/render.go<commit_after>package cmd

import (
	"os/exec"

	"github.com/gobuffalo/buffalo/buffalo/cmd/generate"
	"github.com/markbates/gentronics"
)

func newAppGenerator(data gentronics.Data) *gentronics.Generator {
	g := gentronics.New()
	g.Add(gentronics.NewFile("README.md", nREADME))
	g.Add(gentronics.NewFile("main.go", nMain))
	g.Add(gentronics.NewFile(".buffalo.dev.yml", nRefresh))
	g.Add(gentronics.NewFile(".codeclimate.yml", nCodeClimate))

	if data["ciProvider"] == "travis" {
		g.Add(gentronics.NewFile(".travis.yml", nTravis))
	}

	g.Add(gentronics.NewFile("actions/app.go", nApp))
	g.Add(gentronics.NewFile("actions/home.go", nHomeHandler))
	g.Add(gentronics.NewFile("actions/home_test.go", nHomeHandlerTest))
	g.Add(gentronics.NewFile("actions/render.go", nRender))
	g.Add(gentronics.NewFile("grifts/routes.go", nGriftRoutes))
	g.Add(gentronics.NewFile("templates/index.html", nIndexHTML))
	g.Add(gentronics.NewFile("templates/application.html", nApplicationHTML))
	g.Add(gentronics.NewFile(".gitignore", nGitignore))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/refresh/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/refresh")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/markbates/grift/...")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/markbates/grift")))
	g.Add(gentronics.NewCommand(generate.GoGet("github.com/motemen/gore")))
	g.Add(gentronics.NewCommand(generate.GoInstall("github.com/motemen/gore")))
	g.Add(generate.NewWebpackGenerator(data))
	g.Add(newSodaGenerator())
	g.Add(gentronics.NewCommand(appGoGet()))
	g.Add(generate.Fmt)

	return g
}

func appGoGet() *exec.Cmd {
	appArgs := []string{"get", "-t"}
	if verbose {
		appArgs = append(appArgs, "-v")
	}
	appArgs = append(appArgs, "./...")
	return exec.Command("go", appArgs...)
}

const nREADME = `
# Welcome to Buffalo!

Thank you for chosing Buffalo for your web development needs.

{{#if withPop}}
## Database Setup

It looks like you chose to set up your application using a {{dbType}} database! Fantastic!

The first thing you need to do is open up the "database.yml" file and edit it to use the correct usernames, passwords, hosts, etc... that are appropriate for your environment.

You will also need to make sure that **you** start/install the database of your choice. Buffalo **won't** install and start {{dbType}} for you.

### Create Your Databases

Ok, so you've edited the "database.yml" file and started {{dbType}}, now Buffalo can create the databases in that file for you:

	$ buffalo db create -a
{{/if}}

## Starting the Application

Buffalo ships with a command that will watch your application and automatically rebuild the Go binary and any assets for you. To do that run the "buffalo dev" command:

	$ buffalo dev

If you point your browser to [http://127.0.0.1:3000](http://127.0.0.1:3000) you should see a "Welcome to Buffalo!" page.

**Congratulations!** You now have your Buffalo application up and running.

## What Next?

We recommend you heading over to [http://gobuffalo.io](http://gobuffalo.io) and reviewing all of the great documentation there.

Good luck!

[Powered by Buffalo](http://gobuffalo.io)`

const nMain = `package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"{{actionsPath}}"
	"github.com/markbates/going/defaults"
)

func main() {
	port := defaults.String(os.Getenv("PORT"), "3000")
	log.Printf("Starting {{name}} on port %s\n", port)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), actions.App()))
}

`
const nApp = `package actions

import (
	"os"

	"github.com/gobuffalo/buffalo"
	{{#if withPop }}
	"github.com/gobuffalo/buffalo/middleware"
	"{{modelsPath}}"
	{{/if}}
	"github.com/markbates/going/defaults"
)

// ENV is used to help switch settings based on where the
// application is being run. Default is "development".
var ENV = defaults.String(os.Getenv("GO_ENV"), "development")
var app *buffalo.App

// App is where all routes and middleware for buffalo
// should be defined. This is the nerve center of your
// application.
func App() *buffalo.App {
	if app == nil {
		app = buffalo.Automatic(buffalo.Options{
			Env: ENV,
			SessionName: "_{{name}}_session",
		})

		{{#if withPop }}
		app.Use(middleware.PopTransaction(models.DB))
		{{/if}}

		app.GET("/", HomeHandler)

		app.ServeFiles("/assets", assetsPath())
	}

	return app
}
`

const nRender = `package actions

import (
	"net/http"

	rice "github.com/GeertJohan/go.rice"
	"github.com/gobuffalo/buffalo/render"
	"github.com/gobuffalo/buffalo/render/resolvers"
)

var r *render.Engine

func init() {
	r = render.New(render.Options{
		HTMLLayout:     "application.html",
		CacheTemplates: ENV == "production",
		FileResolverFunc: func() resolvers.FileResolver {
			return &resolvers.RiceBox{
				Box: rice.MustFindBox("../templates"),
			}
		},
		Helpers: map[string]interface{}{},
	})
}

func assetsPath() http.FileSystem {
	box := rice.MustFindBox("../public/assets")
	return box.HTTPBox()
}
`

const nHomeHandler = `package actions

import "github.com/gobuffalo/buffalo"

// HomeHandler is a default handler to serve up
// a home page.
func HomeHandler(c buffalo.Context) error {
	return c.Render(200, r.HTML("index.html"))
}
`

const nHomeHandlerTest = `package actions_test

import (
	"testing"

	"{{actionsPath}}"
	"github.com/markbates/willie"
	"github.com/stretchr/testify/require"
)

func Test_HomeHandler(t *testing.T) {
	r := require.New(t)

	w := willie.New(actions.App())
	res := w.Request("/").Get()

	r.Equal(200, res.Code)
	r.Contains(res.Body.String(), "Welcome to Buffalo!")
}
`

const nIndexHTML = `

Welcome to Buffalo! [v{{version}}]

       https://github.com/gobuffalo/buffalo

       Documentation

Defined Routes

          METHOD
          PATH
          HANDLER

        \{{#each routes as |r|}}

          \{{r.Method}}
          \{{r.Path}}
          \{{r.HandlerName}}

        \{{/each}}

`

const nApplicationHTML = `

  <meta charset="utf-8">
  <title>Buffalo - {{ titleName }}</title>
  <link rel="stylesheet" href="/assets/application.css" type="text/css" media="all" />

    \{{ yield }}

`

const nGitignore = `vendor/
**/*.log
**/*.sqlite
.idea/
bin/
tmp/
node_modules/
.sass-cache/
rice-box.go
public/assets/
{{ name }}
`

const nGriftRoutes = `package grifts

import (
	"os"

	. "github.com/markbates/grift/grift"
	"{{actionsPath}}"
	"github.com/olekukonko/tablewriter"
)

var _ = Add("routes", func(c *Context) error {
	a := actions.App()
	routes := a.Routes()

	table := tablewriter.NewWriter(os.Stdout)
	table.SetHeader([]string{"Method", "Path", "Handler"})
	for _, r := range routes {
		table.Append([]string{r.Method, r.Path, r.HandlerName})
	}
	table.SetCenterSeparator("|")
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.Render()
	return nil
})`

const nRefresh = `app_root: .
ignored_folders:
- vendor
- log
- logs
- assets
- public
- grifts
- tmp
- bin
- node_modules
- .sass-cache
included_extensions:
- .go
- .html
- .md
- .js
- .tmpl
build_path: tmp
build_delay: 200ns
binary_name: {{name}}-build
command_flags: []
enable_colors: true
log_name: buffalo
`

const nCodeClimate = `engines:
  fixme:
    enabled: true
  gofmt:
    enabled: true
  golint:
    enabled: true
  govet:
    enabled: true
exclude_paths:
  - grifts/**/*
  - "**/*_test.go"
  - "*_test.go"
  - "**_test.go"
  - logs/*
  - public/*
  - templates/*
ratings:
  paths:
    - "**.go"

`

const nTravis = `language: go
env:
- GO_ENV=test

before_script:
  - psql -c 'create database {{name}}_test;' -U postgres
	- mysql -e 'CREATE DATABASE {{name}}_test;'
  - mkdir -p $TRAVIS_BUILD_DIR/public/assets

go:
  - 1.7.x
  - master

go_import_path: {{ packagePath }}
`
<|endoftext|>


<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 crypto

import (
	"crypto/ecdsa"
	"crypto/x509"
	"github.com/op/go-logging"
	"github.com/openblockchain/obc-peer/openchain/crypto/utils"
)

// Public Struct

type nodeImpl struct {
	isInitialized bool

	// Configuration
	conf *configuration

	// Logging
	log *logging.Logger

	// keyStore
	ks *keyStore

	// Certs
	rootsCertPool *x509.CertPool

	// 48-bytes identifier
	id []byte

	// Enrollment Certificate and private key
	enrollID      string
	enrollCert    *x509.Certificate
	enrollPrivKey *ecdsa.PrivateKey

	// Enrollment Chain
	enrollChainKey []byte
}

func (node *nodeImpl) GetName() string {
	return node.conf.name
}

func (node *nodeImpl) register(prefix, name string, pwd []byte, enrollID, enrollPWD string) error {
	if node.isInitialized {
		node.log.Error("Registering [%s]...done! Initialization already performed", enrollID)

		return utils.ErrAlreadyInitialized
	}

	// Init Conf
	if err := node.initConfiguration(prefix, name); err != nil {
		log.Error("Failed initiliazing configuration [%s] [%s].", enrollID, err)

		return err
	}

	// Start registration
	node.log.Info("Registering [%s]...", enrollID)

	if node.isRegistered() {
		node.log.Error("Registering [%s]...done! Registration already performed", enrollID)

		return utils.ErrAlreadyRegistered
	}
	// TODO: handle the error in a better way
	if err := node.createKeyStorage(); err != nil {
		node.log.Error("Failed creating key storage [%s].", err.Error())

		return err
	}

	if err := node.retrieveECACertsChain(enrollID); err != nil {
		node.log.Error("Failed retrieveing ECA certs chain [%s].", err.Error())

		return err
	}

	if err := node.retrieveTCACertsChain(enrollID); err != nil {
		node.log.Error("Failed retrieveing ECA certs chain [%s].", err.Error())

		return err
	}

	if err := node.retrieveEnrollmentData(enrollID, enrollPWD); err != nil {
		node.log.Error("Failed retrieveing enrollment data [%s].", err.Error())

		return err
	}

	if err := node.retrieveTLSCertificate(enrollID, enrollPWD); err != nil {
		node.log.Error("Failed retrieveing enrollment data: %s", err)

		return err
	}

	node.log.Info("Registering [%s]...done!", enrollID)

	return nil
}

func (node *nodeImpl) init(prefix, name string, pwd []byte) error {
	if node.isInitialized {
		node.log.Error("Already initializaed.")

		return utils.ErrAlreadyInitialized
	}

	// Init Conf
	if err := node.initConfiguration(prefix, name); err != nil {
		return err
	}

	if !node.isRegistered() {
		node.log.Error("Not registered yet.")

		return utils.ErrRegistrationRequired
	}

	// Initialize keystore
	node.log.Info("Init keystore...")
	// TODO: password support
	err := node.initKeyStore()
	if err != nil {
		if err != utils.ErrKeyStoreAlreadyInitialized {
			node.log.Error("Keystore already initialized.")
		} else {
			node.log.Error("Failed initiliazing keystore [%s].", err.Error())

			return err
		}
	}
	node.log.Info("Init keystore...done.")

	// Init crypto engine
	err = node.initCryptoEngine()
	if err != nil {
		node.log.Error("Failed initiliazing crypto engine [%s].", err.Error())
		return err
	}

	// Initialisation complete
	node.isInitialized = true

	node.log.Info("Initialization...done.")

	return nil
}

func (node *nodeImpl) close() error {
	// Close keystore
	var err error

	if node.ks != nil {
		err = node.ks.close()
	}

	return err
}
<commit_msg>Fixed log message<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 crypto

import (
	"crypto/ecdsa"
	"crypto/x509"
	"github.com/op/go-logging"
	"github.com/openblockchain/obc-peer/openchain/crypto/utils"
)

// Public Struct

type nodeImpl struct {
	isInitialized bool

	// Configuration
	conf *configuration

	// Logging
	log *logging.Logger

	// keyStore
	ks *keyStore

	// Certs
	rootsCertPool *x509.CertPool

	// 48-bytes identifier
	id []byte

	// Enrollment Certificate and private key
	enrollID      string
	enrollCert    *x509.Certificate
	enrollPrivKey *ecdsa.PrivateKey

	// Enrollment Chain
	enrollChainKey []byte
}

func (node *nodeImpl) GetName() string {
	return node.conf.name
}

func (node *nodeImpl) register(prefix, name string, pwd []byte, enrollID, enrollPWD string) error {
	if node.isInitialized {
		node.log.Error("Registering [%s]...done! Initialization already performed", enrollID)

		return utils.ErrAlreadyInitialized
	}

	// Init Conf
	if err := node.initConfiguration(prefix, name); err != nil {
		log.Error("Failed initiliazing configuration [%s] [%s].", enrollID, err)

		return err
	}

	// Start registration
	node.log.Info("Registering [%s]...", enrollID)

	if node.isRegistered() {
		node.log.Error("Registering [%s]...done! Registration already performed", enrollID)

		return utils.ErrAlreadyRegistered
	}
	// TODO: handle the error in a better way
	if err := node.createKeyStorage(); err != nil {
		node.log.Error("Failed creating key storage [%s].", err.Error())

		return err
	}

	if err := node.retrieveECACertsChain(enrollID); err != nil {
		node.log.Error("Failed retrieveing ECA certs chain [%s].", err.Error())

		return err
	}

	if err := node.retrieveTCACertsChain(enrollID); err != nil {
		node.log.Error("Failed retrieveing ECA certs chain [%s].", err.Error())

		return err
	}

	if err := node.retrieveEnrollmentData(enrollID, enrollPWD); err != nil {
		node.log.Error("Failed retrieveing enrollment data [%s].", err.Error())

		return err
	}

	if err := node.retrieveTLSCertificate(enrollID, enrollPWD); err != nil {
		node.log.Error("Failed retrieveing tls certificate data: %s", err)

		return err
	}

	node.log.Info("Registering [%s]...done!", enrollID)

	return nil
}

func (node *nodeImpl) init(prefix, name string, pwd []byte) error {
	if node.isInitialized {
		node.log.Error("Already initializaed.")

		return utils.ErrAlreadyInitialized
	}

	// Init Conf
	if err := node.initConfiguration(prefix, name); err != nil {
		return err
	}

	if !node.isRegistered() {
		node.log.Error("Not registered yet.")

		return utils.ErrRegistrationRequired
	}

	// Initialize keystore
	node.log.Info("Init keystore...")
	// TODO: password support
	err := node.initKeyStore()
	if err != nil {
		if err != utils.ErrKeyStoreAlreadyInitialized {
			node.log.Error("Keystore already initialized.")
		} else {
			node.log.Error("Failed initiliazing keystore [%s].", err.Error())

			return err
		}
	}
	node.log.Info("Init keystore...done.")

	// Init crypto engine
	err = node.initCryptoEngine()
	if err != nil {
		node.log.Error("Failed initiliazing crypto engine [%s].", err.Error())
		return err
	}

	// Initialisation complete
	node.isInitialized = true

	node.log.Info("Initialization...done.")

	return nil
}

func (node *nodeImpl) close() error {
	// Close keystore
	var err error

	if node.ks != nil {
		err = node.ks.close()
	}

	return err
}
<|endoftext|>


<commit_before>package daemon

import (
	"encoding/json"
	"errors"
	"fmt"
	"runtime"

	"golang.org/x/net/context"

	"github.com/docker/docker/api/types/backend"
	"github.com/docker/docker/container"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/versions"
	"github.com/docker/engine-api/types/versions/v1p20"
)

// ContainerStats writes information about the container to the stream
// given in the config object.
func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *backend.ContainerStatsConfig) error {
	if runtime.GOOS == "windows" {
		return errors.New("Windows does not support stats")
	}
	// Remote API version (used for backwards compatibility)
	apiVersion := config.Version

	container, err := daemon.GetContainer(prefixOrName)
	if err != nil {
		return err
	}

	// If the container is not running and requires no stream, return an empty stats.
	if !container.IsRunning() && !config.Stream {
		return json.NewEncoder(config.OutStream).Encode(&types.Stats{})
	}

	outStream := config.OutStream
	if config.Stream {
		wf := ioutils.NewWriteFlusher(outStream)
		defer wf.Close()
		wf.Flush()
		outStream = wf
	}

	var preCPUStats types.CPUStats
	getStatJSON := func(v interface{}) *types.StatsJSON {
		ss := v.(types.StatsJSON)
		ss.PreCPUStats = preCPUStats
		preCPUStats = ss.CPUStats
		return &ss
	}

	enc := json.NewEncoder(outStream)

	updates := daemon.subscribeToContainerStats(container)
	defer daemon.unsubscribeToContainerStats(container, updates)

	noStreamFirstFrame := true
	for {
		select {
		case v, ok := <-updates:
			if !ok {
				return nil
			}

			var statsJSON interface{}
			statsJSONPost120 := getStatJSON(v)
			if versions.LessThan(apiVersion, "1.21") {
				var (
					rxBytes   uint64
					rxPackets uint64
					rxErrors  uint64
					rxDropped uint64
					txBytes   uint64
					txPackets uint64
					txErrors  uint64
					txDropped uint64
				)
				for _, v := range statsJSONPost120.Networks {
					rxBytes += v.RxBytes
					rxPackets += v.RxPackets
					rxErrors += v.RxErrors
					rxDropped += v.RxDropped
					txBytes += v.TxBytes
					txPackets += v.TxPackets
					txErrors += v.TxErrors
					txDropped += v.TxDropped
				}
				statsJSON = &v1p20.StatsJSON{
					Stats: statsJSONPost120.Stats,
					Network: types.NetworkStats{
						RxBytes:   rxBytes,
						RxPackets: rxPackets,
						RxErrors:  rxErrors,
						RxDropped: rxDropped,
						TxBytes:   txBytes,
						TxPackets: txPackets,
						TxErrors:  txErrors,
						TxDropped: txDropped,
					},
				}
			} else {
				statsJSON = statsJSONPost120
			}

			if !config.Stream && noStreamFirstFrame {
				// prime the cpu stats so they aren't 0 in the final output
				noStreamFirstFrame = false
				continue
			}

			if err := enc.Encode(statsJSON); err != nil {
				return err
			}

			if !config.Stream {
				return nil
			}
		case <-ctx.Done():
			return nil
		}
	}
}

func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
	return daemon.statsCollector.collect(c)
}

func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
	daemon.statsCollector.unsubscribe(c, ch)
}

// GetContainerStats collects all the stats published by a container
func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.StatsJSON, error) {
	stats, err := daemon.stats(container)
	if err != nil {
		return nil, err
	}

	if stats.Networks, err = daemon.getNetworkStats(container); err != nil {
		return nil, err
	}

	return stats, nil
}

// Resolve Network SandboxID in case the container reuse another container's network stack
func (daemon *Daemon) getNetworkSandboxID(c *container.Container) (string, error) {
	curr := c
	for curr.HostConfig.NetworkMode.IsContainer() {
		containerID := curr.HostConfig.NetworkMode.ConnectedContainer()
		connected, err := daemon.GetContainer(containerID)
		if err != nil {
			return "", fmt.Errorf("Could not get container for %s", containerID)
		}
		curr = connected
	}
	return curr.NetworkSettings.SandboxID, nil
}

func (daemon *Daemon) getNetworkStats(c *container.Container) (map[string]types.NetworkStats, error) {
	sandboxID, err := daemon.getNetworkSandboxID(c)
	if err != nil {
		return nil, err
	}

	sb, err := daemon.netController.SandboxByID(sandboxID)
	if err != nil {
		return nil, err
	}

	lnstats, err := sb.Statistics()
	if err != nil {
		return nil, err
	}

	stats := make(map[string]types.NetworkStats)
	// Convert libnetwork nw stats into engine-api stats
	for ifName, ifStats := range lnstats {
		stats[ifName] = types.NetworkStats{
			RxBytes:   ifStats.RxBytes,
			RxPackets: ifStats.RxPackets,
			RxErrors:  ifStats.RxErrors,
			RxDropped: ifStats.RxDropped,
			TxBytes:   ifStats.TxBytes,
			TxPackets: ifStats.TxPackets,
			TxErrors:  ifStats.TxErrors,
			TxDropped: ifStats.TxDropped,
		}
	}

	return stats, nil
}
<commit_msg>Return an empty stats if the container is restarting<commit_after>package daemon

import (
	"encoding/json"
	"errors"
	"fmt"
	"runtime"

	"golang.org/x/net/context"

	"github.com/docker/docker/api/types/backend"
	"github.com/docker/docker/container"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/engine-api/types"
	"github.com/docker/engine-api/types/versions"
	"github.com/docker/engine-api/types/versions/v1p20"
)

// ContainerStats writes information about the container to the stream
// given in the config object.
func (daemon *Daemon) ContainerStats(ctx context.Context, prefixOrName string, config *backend.ContainerStatsConfig) error {
	if runtime.GOOS == "windows" {
		return errors.New("Windows does not support stats")
	}
	// Remote API version (used for backwards compatibility)
	apiVersion := config.Version

	container, err := daemon.GetContainer(prefixOrName)
	if err != nil {
		return err
	}

	// If the container is either not running or restarting and requires no stream, return an empty stats.
	if (!container.IsRunning() || container.IsRestarting()) && !config.Stream {
		return json.NewEncoder(config.OutStream).Encode(&types.Stats{})
	}

	outStream := config.OutStream
	if config.Stream {
		wf := ioutils.NewWriteFlusher(outStream)
		defer wf.Close()
		wf.Flush()
		outStream = wf
	}

	var preCPUStats types.CPUStats
	getStatJSON := func(v interface{}) *types.StatsJSON {
		ss := v.(types.StatsJSON)
		ss.PreCPUStats = preCPUStats
		preCPUStats = ss.CPUStats
		return &ss
	}

	enc := json.NewEncoder(outStream)

	updates := daemon.subscribeToContainerStats(container)
	defer daemon.unsubscribeToContainerStats(container, updates)

	noStreamFirstFrame := true
	for {
		select {
		case v, ok := <-updates:
			if !ok {
				return nil
			}

			var statsJSON interface{}
			statsJSONPost120 := getStatJSON(v)
			if versions.LessThan(apiVersion, "1.21") {
				var (
					rxBytes   uint64
					rxPackets uint64
					rxErrors  uint64
					rxDropped uint64
					txBytes   uint64
					txPackets uint64
					txErrors  uint64
					txDropped uint64
				)
				for _, v := range statsJSONPost120.Networks {
					rxBytes += v.RxBytes
					rxPackets += v.RxPackets
					rxErrors += v.RxErrors
					rxDropped += v.RxDropped
					txBytes += v.TxBytes
					txPackets += v.TxPackets
					txErrors += v.TxErrors
					txDropped += v.TxDropped
				}
				statsJSON = &v1p20.StatsJSON{
					Stats: statsJSONPost120.Stats,
					Network: types.NetworkStats{
						RxBytes:   rxBytes,
						RxPackets: rxPackets,
						RxErrors:  rxErrors,
						RxDropped: rxDropped,
						TxBytes:   txBytes,
						TxPackets: txPackets,
						TxErrors:  txErrors,
						TxDropped: txDropped,
					},
				}
			} else {
				statsJSON = statsJSONPost120
			}

			if !config.Stream && noStreamFirstFrame {
				// prime the cpu stats so they aren't 0 in the final output
				noStreamFirstFrame = false
				continue
			}

			if err := enc.Encode(statsJSON); err != nil {
				return err
			}

			if !config.Stream {
				return nil
			}
		case <-ctx.Done():
			return nil
		}
	}
}

func (daemon *Daemon) subscribeToContainerStats(c *container.Container) chan interface{} {
	return daemon.statsCollector.collect(c)
}

func (daemon *Daemon) unsubscribeToContainerStats(c *container.Container, ch chan interface{}) {
	daemon.statsCollector.unsubscribe(c, ch)
}

// GetContainerStats collects all the stats published by a container
func (daemon *Daemon) GetContainerStats(container *container.Container) (*types.StatsJSON, error) {
	stats, err := daemon.stats(container)
	if err != nil {
		return nil, err
	}

	if stats.Networks, err = daemon.getNetworkStats(container); err != nil {
		return nil, err
	}

	return stats, nil
}

// Resolve Network SandboxID in case the container reuse another container's network stack
func (daemon *Daemon) getNetworkSandboxID(c *container.Container) (string, error) {
	curr := c
	for curr.HostConfig.NetworkMode.IsContainer() {
		containerID := curr.HostConfig.NetworkMode.ConnectedContainer()
		connected, err := daemon.GetContainer(containerID)
		if err != nil {
			return "", fmt.Errorf("Could not get container for %s", containerID)
		}
		curr = connected
	}
	return curr.NetworkSettings.SandboxID, nil
}

func (daemon *Daemon) getNetworkStats(c *container.Container) (map[string]types.NetworkStats, error) {
	sandboxID, err := daemon.getNetworkSandboxID(c)
	if err != nil {
		return nil, err
	}

	sb, err := daemon.netController.SandboxByID(sandboxID)
	if err != nil {
		return nil, err
	}

	lnstats, err := sb.Statistics()
	if err != nil {
		return nil, err
	}

	stats := make(map[string]types.NetworkStats)
	// Convert libnetwork nw stats into engine-api stats
	for ifName, ifStats := range lnstats {
		stats[ifName] = types.NetworkStats{
			RxBytes:   ifStats.RxBytes,
			RxPackets: ifStats.RxPackets,
			RxErrors:  ifStats.RxErrors,
			RxDropped: ifStats.RxDropped,
			TxBytes:   ifStats.TxBytes,
			TxPackets: ifStats.TxPackets,
			TxErrors:  ifStats.TxErrors,
			TxDropped: ifStats.TxDropped,
		}
	}

	return stats, nil
}
<|endoftext|>


<commit_before>package daemon

import (
	"github.com/BluePecker/JwtAuth/dialog/server/parameter/token/request"
	coderQ "github.com/BluePecker/JwtAuth/dialog/server/parameter/coder/request"
	"github.com/BluePecker/JwtAuth/dialog/server/parameter/token/response"
	"github.com/BluePecker/JwtAuth/daemon/coder"
	"github.com/Sirupsen/logrus"
)

func (d *Daemon) List(req request.List) ([]response.Token, error) {
	if sings, err := (*d.Cache).LRange(req.Unique, 0, coder.LoginNum); err != nil {
		return nil, err
	} else {
		ttl := (*d.Cache).TTL(req.Unique)
		tokens := []response.Token{}
		for _, singed := range sings {
			if token, err := coder.Decode(coderQ.Decode{
				JsonWebToken: singed,
			}, (*d.Options).Secret); err == nil && token != nil {
				logrus.Error("token error: ", sings, err, (*d.Options).Secret)
				if claims, ok := token.Claims.(*coder.CustomClaim); ok {
					tokens = append(tokens, response.Token{
						Singed: singed,
						TTL:    ttl,
						Addr:   claims.Addr,
						Device: claims.Device,
					})
				}
			}
		}
		return tokens, nil
	}
}
<commit_msg>fix bug<commit_after>package daemon

import (
	"github.com/BluePecker/JwtAuth/dialog/server/parameter/token/request"
	coderQ "github.com/BluePecker/JwtAuth/dialog/server/parameter/coder/request"
	"github.com/BluePecker/JwtAuth/dialog/server/parameter/token/response"
	"github.com/BluePecker/JwtAuth/daemon/coder"
	"github.com/Sirupsen/logrus"
)

func (d *Daemon) List(req request.List) ([]response.Token, error) {
	if sings, err := (*d.Cache).LRange(req.Unique, 0, coder.LoginNum); err != nil {
		return nil, err
	} else {
		ttl := (*d.Cache).TTL(req.Unique)
		tokens := []response.Token{}
		logrus.Error("token error: ", sings, (*d.Options).Secret)
		for _, singed := range sings {
			if token, err := coder.Decode(coderQ.Decode{
				JsonWebToken: singed,
			}, (*d.Options).Secret); err == nil && token != nil {
				if claims, ok := token.Claims.(*coder.CustomClaim); ok {
					tokens = append(tokens, response.Token{
						Singed: singed,
						TTL:    ttl,
						Addr:   claims.Addr,
						Device: claims.Device,
					})
				}
			}
		}
		return tokens, nil
	}
}
<|endoftext|>


<commit_before><commit_msg>enhance (breaking): openapi3: update function names<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Santiago Arias | Remy Jourde
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package tournaments

import (
	"errors"
	"net/http"
	"strconv"

	"appengine"

	"github.com/taironas/route"

	"github.com/santiaago/gonawin/helpers"
	"github.com/santiaago/gonawin/helpers/log"
	templateshlp "github.com/santiaago/gonawin/helpers/templates"

	mdl "github.com/santiaago/gonawin/models"
)

// Tournament ranking handler:
// Use this handler to get the ranking of a tournament.
// The ranking is an array of users (members) or teams,
// You can specify the rankby parameter to be "users" or "teams".
//	GET	/j/tournament/[0-9]+/ranking/
//
// The response is an array of users.
//
func Ranking(w http.ResponseWriter, r *http.Request, u *mdl.User) error {
	c := appengine.NewContext(r)
	desc := "Tournament Ranking Handler:"

	if r.Method == "GET" {
		// get tournament id
		strTournamentId, err := route.Context.Get(r, "tournamentId")
		if err != nil {
			log.Errorf(c, "%s error getting tournament id, err:%v", desc, err)
			return &helpers.BadRequest{Err: errors.New(helpers.ErrorCodeTournamentNotFound)}
		}

		var tournamentId int64
		tournamentId, err = strconv.ParseInt(strTournamentId, 0, 64)
		if err != nil {
			log.Errorf(c, "%s error converting tournament id from string to int64, err:%v", desc, err)
			return &helpers.BadRequest{Err: errors.New(helpers.ErrorCodeTournamentNotFound)}
		}

		var t *mdl.Tournament
		t, err = mdl.TournamentById(c, tournamentId)
		if err != nil {
			log.Errorf(c, "%s tournament with id:%v was not found %v", desc, tournamentId, err)
			return &helpers.NotFound{Err: errors.New(helpers.ErrorCodeTournamentNotFound)}
		}

		rankby := r.FormValue("rankby")
		// if wrong data, we set rankby to "users"
		if rankby != "teams" && rankby != "users" {
			rankby = "users"
		}

		strlimit := r.FormValue("limit")
		limit := 100
		if len(strlimit) > 0 {
			if n, err := strconv.ParseInt(strlimit, 10, 64); err != nil {
				log.Infof(c, "%s, unable to parse %v, error:%v", strlimit, err)
			} else {
				if n > 0 {
					limit = int(n)
				}
			}
		}

		if rankby == "users" {
			log.Infof(c, "%s ready to build a user array", desc)
			users := t.RankingByUser(c, limit)

			fieldsToKeep := []string{"Id", "Username", "Alias", "Score"}
			usersJson := make([]mdl.UserJson, len(users))
			helpers.TransformFromArrayOfPointers(&users, &usersJson, fieldsToKeep)

			data := struct {
				Users []mdl.UserJson
			}{
				usersJson,
			}

			return templateshlp.RenderJson(w, c, data)

		} else if rankby == "teams" {
			log.Infof(c, "%s ready to build team array", desc)
			teams := t.RankingByTeam(c, limit)

			fieldsToKeep := []string{"Id", "Name", "Accuracy"}
			teamsJson := make([]mdl.TeamJson, len(teams))
			helpers.TransformFromArrayOfPointers(&teams, &teamsJson, fieldsToKeep)

			data := struct {
				Teams []mdl.TeamJson
			}{
				teamsJson,
			}
			return templateshlp.RenderJson(w, c, data)
		}
	}
	return &helpers.BadRequest{Err: errors.New(helpers.ErrorCodeNotSupported)}
}
<commit_msg>tournament ranking exit first if wrong method<commit_after>/*
 * Copyright (c) 2014 Santiago Arias | Remy Jourde
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package tournaments

import (
	"errors"
	"net/http"
	"strconv"

	"appengine"

	"github.com/taironas/route"

	"github.com/santiaago/gonawin/helpers"
	"github.com/santiaago/gonawin/helpers/log"
	templateshlp "github.com/santiaago/gonawin/helpers/templates"

	mdl "github.com/santiaago/gonawin/models"
)

// Tournament ranking handler:
// Use this handler to get the ranking of a tournament.
// The ranking is an array of users (members) or teams,
// You can specify the rankby parameter to be "users" or "teams".
//	GET	/j/tournament/[0-9]+/ranking/
//
// The response is an array of users.
//
func Ranking(w http.ResponseWriter, r *http.Request, u *mdl.User) error {
	if r.Method == "GET" {
		return &helpers.BadRequest{Err: errors.New(helpers.ErrorCodeNotSupported)}
	}

	c := appengine.NewContext(r)
	desc := "Tournament Ranking Handler:"

	// get tournament id
	strTournamentId, err := route.Context.Get(r, "tournamentId")
	if err != nil {
		log.Errorf(c, "%s error getting tournament id, err:%v", desc, err)
		return &helpers.BadRequest{Err: errors.New(helpers.ErrorCodeTournamentNotFound)}
	}

	var tournamentId int64
	tournamentId, err = strconv.ParseInt(strTournamentId, 0, 64)
	if err != nil {
		log.Errorf(c, "%s error converting tournament id from string to int64, err:%v", desc, err)
		return &helpers.BadRequest{Err: errors.New(helpers.ErrorCodeTournamentNotFound)}
	}

	var t *mdl.Tournament
	t, err = mdl.TournamentById(c, tournamentId)
	if err != nil {
		log.Errorf(c, "%s tournament with id:%v was not found %v", desc, tournamentId, err)
		return &helpers.NotFound{Err: errors.New(helpers.ErrorCodeTournamentNotFound)}
	}

	rankby := r.FormValue("rankby")
	// if wrong data, we set rankby to "users"
	if rankby != "teams" && rankby != "users" {
		rankby = "users"
	}

	strlimit := r.FormValue("limit")
	limit := 100
	if len(strlimit) > 0 {
		if n, err := strconv.ParseInt(strlimit, 10, 64); err != nil {
			log.Infof(c, "%s, unable to parse %v, error:%v", strlimit, err)
		} else {
			if n > 0 {
				limit = int(n)
			}
		}
	}

	if rankby == "users" {
		log.Infof(c, "%s ready to build a user array", desc)
		users := t.RankingByUser(c, limit)

		fieldsToKeep := []string{"Id", "Username", "Alias", "Score"}
		usersJson := make([]mdl.UserJson, len(users))
		helpers.TransformFromArrayOfPointers(&users, &usersJson, fieldsToKeep)

		data := struct {
			Users []mdl.UserJson
		}{
			usersJson,
		}

		return templateshlp.RenderJson(w, c, data)

	} else if rankby == "teams" {
		log.Infof(c, "%s ready to build team array", desc)
		teams := t.RankingByTeam(c, limit)

		fieldsToKeep := []string{"Id", "Name", "Accuracy"}
		teamsJson := make([]mdl.TeamJson, len(teams))
		helpers.TransformFromArrayOfPointers(&teams, &teamsJson, fieldsToKeep)

		data := struct {
			Teams []mdl.TeamJson
		}{
			teamsJson,
		}
		return templateshlp.RenderJson(w, c, data)
	}
}
<|endoftext|>


<commit_before>package terraform

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"sync"

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

// BuiltinEvalContext is an EvalContext implementation that is used by
// Terraform by default.
type BuiltinEvalContext struct {
	PathValue     []string
	Interpolater  *Interpolater
	Providers     map[string]ResourceProviderFactory
	ProviderCache map[string]ResourceProvider
	ProviderLock  *sync.Mutex

	once sync.Once
}

func (ctx *BuiltinEvalContext) InitProvider(n string) (ResourceProvider, error) {
	ctx.once.Do(ctx.init)

	// If we already initialized, it is an error
	if p := ctx.Provider(n); p != nil {
		return nil, fmt.Errorf("Provider '%s' already initialized", n)
	}

	// Warning: make sure to acquire these locks AFTER the call to Provider
	// above, since it also acquires locks.
	ctx.ProviderLock.Lock()
	defer ctx.ProviderLock.Unlock()

	f, ok := ctx.Providers[n]
	if !ok {
		return nil, fmt.Errorf("Provider '%s' not found", n)
	}

	p, err := f()
	if err != nil {
		return nil, err
	}

	ctx.ProviderCache[ctx.pathCacheKey()] = p
	return p, nil
}

func (ctx *BuiltinEvalContext) Provider(n string) ResourceProvider {
	ctx.once.Do(ctx.init)

	ctx.ProviderLock.Lock()
	defer ctx.ProviderLock.Unlock()

	return ctx.ProviderCache[ctx.pathCacheKey()]
}

func (ctx *BuiltinEvalContext) Interpolate(
	cfg *config.RawConfig, r *Resource) (*ResourceConfig, error) {
	if cfg != nil {
		scope := &InterpolationScope{
			Path:     ctx.Path(),
			Resource: r,
		}
		vs, err := ctx.Interpolater.Values(scope, cfg.Variables)
		if err != nil {
			return nil, err
		}

		// Do the interpolation
		if err := cfg.Interpolate(vs); err != nil {
			return nil, err
		}
	}

	result := NewResourceConfig(cfg)
	result.interpolateForce()
	return result, nil
}

func (ctx *BuiltinEvalContext) Path() []string {
	return ctx.PathValue
}

func (ctx *BuiltinEvalContext) init() {
	// We nil-check the things below because they're meant to be configured,
	// and we just default them to non-nil.
	if ctx.Providers == nil {
		ctx.Providers = make(map[string]ResourceProviderFactory)
	}
}

func (ctx *BuiltinEvalContext) pathCacheKey() string {
	hash := md5.New()
	for _, p := range ctx.Path() {
		if _, err := hash.Write([]byte(p)); err != nil {
			panic(err)
		}
	}

	return hex.EncodeToString(hash.Sum(nil))
}
<commit_msg>terraform: comments, and better<commit_after>package terraform

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"sync"

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

// BuiltinEvalContext is an EvalContext implementation that is used by
// Terraform by default.
type BuiltinEvalContext struct {
	PathValue     []string
	Interpolater  *Interpolater
	Providers     map[string]ResourceProviderFactory
	ProviderCache map[string]ResourceProvider
	ProviderLock  *sync.Mutex

	once sync.Once
}

func (ctx *BuiltinEvalContext) InitProvider(n string) (ResourceProvider, error) {
	ctx.once.Do(ctx.init)

	// If we already initialized, it is an error
	if p := ctx.Provider(n); p != nil {
		return nil, fmt.Errorf("Provider '%s' already initialized", n)
	}

	// Warning: make sure to acquire these locks AFTER the call to Provider
	// above, since it also acquires locks.
	ctx.ProviderLock.Lock()
	defer ctx.ProviderLock.Unlock()

	f, ok := ctx.Providers[n]
	if !ok {
		return nil, fmt.Errorf("Provider '%s' not found", n)
	}

	p, err := f()
	if err != nil {
		return nil, err
	}

	ctx.ProviderCache[ctx.pathCacheKey()] = p
	return p, nil
}

func (ctx *BuiltinEvalContext) Provider(n string) ResourceProvider {
	ctx.once.Do(ctx.init)

	ctx.ProviderLock.Lock()
	defer ctx.ProviderLock.Unlock()

	return ctx.ProviderCache[ctx.pathCacheKey()]
}

func (ctx *BuiltinEvalContext) Interpolate(
	cfg *config.RawConfig, r *Resource) (*ResourceConfig, error) {
	if cfg != nil {
		scope := &InterpolationScope{
			Path:     ctx.Path(),
			Resource: r,
		}
		vs, err := ctx.Interpolater.Values(scope, cfg.Variables)
		if err != nil {
			return nil, err
		}

		// Do the interpolation
		if err := cfg.Interpolate(vs); err != nil {
			return nil, err
		}
	}

	result := NewResourceConfig(cfg)
	result.interpolateForce()
	return result, nil
}

func (ctx *BuiltinEvalContext) Path() []string {
	return ctx.PathValue
}

func (ctx *BuiltinEvalContext) init() {
	// We nil-check the things below because they're meant to be configured,
	// and we just default them to non-nil.
	if ctx.Providers == nil {
		ctx.Providers = make(map[string]ResourceProviderFactory)
	}
}

// pathCacheKey returns a cache key for the current module path, unique to
// the module path.
//
// This is used because there is a variety of information that needs to be
// cached per-path, rather than per-context.
func (ctx *BuiltinEvalContext) pathCacheKey() string {
	// There is probably a better way to do this, but this is working for now.
	// We just create an MD5 hash of all the MD5 hashes of all the path
	// elements. This gets us the property that it is unique per ordering.
	hash := md5.New()
	for _, p := range ctx.Path() {
		single := md5.Sum([]byte(p))
		if _, err := hash.Write(single[:]); err != nil {
			panic(err)
		}
	}

	return hex.EncodeToString(hash.Sum(nil))
}
<|endoftext|>


<commit_before>package toolbox_test

import (
	"strings"
	"testing"

	"fmt"
	"github.com/stretchr/testify/assert"
	"github.com/viant/toolbox"
	"os"
	"path"
)

func TestDecoderFactory(t *testing.T) {
	{
		reader := strings.NewReader("[1, 2, 3]")
		decoder := toolbox.NewJSONDecoderFactory().Create(reader)
		aSlice := make([]int, 0)
		err := decoder.Decode(&aSlice)
		assert.Nil(t, err)
		assert.Equal(t, 3, len(aSlice))
	}
	{
		reader := strings.NewReader("[1, 2, 3]")
		decoder := toolbox.NewJSONDecoderFactoryWithOption(true).Create(reader)
		aSlice := make([]int, 0)
		err := decoder.Decode(&aSlice)
		assert.Nil(t, err)
		assert.Equal(t, 3, len(aSlice))
	}
}

func TestUnMarshalerDecoderFactory(t *testing.T) {
	reader := strings.NewReader("abc")
	decoder := toolbox.NewUnMarshalerDecoderFactory().Create(reader)
	foo := &Foo100{}
	err := decoder.Decode(foo)
	assert.Nil(t, err)
	assert.Equal(t, "abc", foo.Attr)

	err = decoder.Decode(&Foo101{})
	assert.NotNil(t, err)

}

type Foo100 struct {
	Attr string
}

func (m *Foo100) Unmarshal(data []byte) error {
	m.Attr = string(data)
	return nil
}

type Foo101 struct {
	Attr string
}

func TestDelimiterDecoderFactory(t *testing.T) {

	record := &toolbox.DelimiteredRecord{
		Delimiter: ",",
	}
	{
		decoder := toolbox.NewDelimiterDecoderFactory().Create(strings.NewReader("column1,\"column2\", column3,column4"))
		err := decoder.Decode(record)
		if assert.Nil(t, err) {
			assert.Equal(t, []string{"column1", "column2", "column3", "column4"}, record.Columns)

		}
	}

	{
		decoder := toolbox.NewDelimiterDecoderFactory().Create(strings.NewReader("1,2,\"ab,cd\",3"))
		err := decoder.Decode(record)
		if assert.Nil(t, err) {
			assert.EqualValues(t, "1", record.Record["column1"])
			assert.EqualValues(t, "2", record.Record["column2"])
			assert.EqualValues(t, "ab,cd", record.Record["column3"])
			assert.EqualValues(t, "3", record.Record["column4"])
		}
	}

	{
		decoder := toolbox.NewDelimiterDecoderFactory().Create(strings.NewReader("1,2,\" \"\"location:[\\\"\"BE\\\"\"]\"\"  \",3"))
		err := decoder.Decode(record)
		if assert.Nil(t, err) {
			assert.EqualValues(t, "1", record.Record["column1"])
			assert.EqualValues(t, "2", record.Record["column2"])
			assert.EqualValues(t, " \"location:[\\\"BE\\\"]\"  ", record.Record["column3"])
			assert.EqualValues(t, "3", record.Record["column4"])
		}
	}

}

func TestTestYamlDecoder(t *testing.T) {
	var filename = path.Join(os.Getenv("TMPDIR"), "test.yaml")
	toolbox.RemoveFileIfExist(filename)
	defer toolbox.RemoveFileIfExist(filename)
	var aMap = map[string]interface{}{
		"a": 1,
		"b": "123",
		"c": []int{1, 3, 6},
	}
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, 0644)
	fmt.Printf("%v\n", filename)
	if assert.Nil(t, err) {
		err = toolbox.NewYamlEncoderFactory().Create(file).Encode(aMap)
		assert.Nil(t, err)
	}
	var cloneMap = make(map[string]interface{})
	file.Close()
	file, err = os.OpenFile(filename, os.O_RDONLY, 0644)
	if assert.Nil(t, err) {
		defer file.Close()
		err = toolbox.NewYamlDecoderFactory().Create(file).Decode(&cloneMap)
		if assert.Nil(t, err) {
			assert.EqualValues(t, aMap["a"], cloneMap["a"])
			assert.EqualValues(t, aMap["b"], cloneMap["b"])
			assert.EqualValues(t, toolbox.AsSlice(aMap["c"]), cloneMap["c"])

		}
	}

}
<commit_msg>remove debug info<commit_after>package toolbox_test

import (
	"strings"
	"testing"

	"fmt"
	"github.com/stretchr/testify/assert"
	"github.com/viant/toolbox"
	"os"
	"path"
)

func TestDecoderFactory(t *testing.T) {
	{
		reader := strings.NewReader("[1, 2, 3]")
		decoder := toolbox.NewJSONDecoderFactory().Create(reader)
		aSlice := make([]int, 0)
		err := decoder.Decode(&aSlice)
		assert.Nil(t, err)
		assert.Equal(t, 3, len(aSlice))
	}
	{
		reader := strings.NewReader("[1, 2, 3]")
		decoder := toolbox.NewJSONDecoderFactoryWithOption(true).Create(reader)
		aSlice := make([]int, 0)
		err := decoder.Decode(&aSlice)
		assert.Nil(t, err)
		assert.Equal(t, 3, len(aSlice))
	}
}

func TestUnMarshalerDecoderFactory(t *testing.T) {
	reader := strings.NewReader("abc")
	decoder := toolbox.NewUnMarshalerDecoderFactory().Create(reader)
	foo := &Foo100{}
	err := decoder.Decode(foo)
	assert.Nil(t, err)
	assert.Equal(t, "abc", foo.Attr)

	err = decoder.Decode(&Foo101{})
	assert.NotNil(t, err)

}

type Foo100 struct {
	Attr string
}

func (m *Foo100) Unmarshal(data []byte) error {
	m.Attr = string(data)
	return nil
}

type Foo101 struct {
	Attr string
}

func TestDelimiterDecoderFactory(t *testing.T) {

	record := &toolbox.DelimiteredRecord{
		Delimiter: ",",
	}
	{
		decoder := toolbox.NewDelimiterDecoderFactory().Create(strings.NewReader("column1,\"column2\", column3,column4"))
		err := decoder.Decode(record)
		if assert.Nil(t, err) {
			assert.Equal(t, []string{"column1", "column2", "column3", "column4"}, record.Columns)

		}
	}

	{
		decoder := toolbox.NewDelimiterDecoderFactory().Create(strings.NewReader("1,2,\"ab,cd\",3"))
		err := decoder.Decode(record)
		if assert.Nil(t, err) {
			assert.EqualValues(t, "1", record.Record["column1"])
			assert.EqualValues(t, "2", record.Record["column2"])
			assert.EqualValues(t, "ab,cd", record.Record["column3"])
			assert.EqualValues(t, "3", record.Record["column4"])
		}
	}

	{
		decoder := toolbox.NewDelimiterDecoderFactory().Create(strings.NewReader("1,2,\" \"\"location:[\\\"\"BE\\\"\"]\"\"  \",3"))
		err := decoder.Decode(record)
		if assert.Nil(t, err) {
			assert.EqualValues(t, "1", record.Record["column1"])
			assert.EqualValues(t, "2", record.Record["column2"])
			assert.EqualValues(t, " \"location:[\\\"BE\\\"]\"  ", record.Record["column3"])
			assert.EqualValues(t, "3", record.Record["column4"])
		}
	}

}

func TestTestYamlDecoder(t *testing.T) {
	var filename = path.Join(os.Getenv("TMPDIR"), "test.yaml")
	toolbox.RemoveFileIfExist(filename)
	defer toolbox.RemoveFileIfExist(filename)
	var aMap = map[string]interface{}{
		"a": 1,
		"b": "123",
		"c": []int{1, 3, 6},
	}
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, 0644)
	if assert.Nil(t, err) {
		err = toolbox.NewYamlEncoderFactory().Create(file).Encode(aMap)
		assert.Nil(t, err)
	}
	var cloneMap = make(map[string]interface{})
	file.Close()
	file, err = os.OpenFile(filename, os.O_RDONLY, 0644)
	if assert.Nil(t, err) {
		defer file.Close()
		err = toolbox.NewYamlDecoderFactory().Create(file).Decode(&cloneMap)
		if assert.Nil(t, err) {
			assert.EqualValues(t, aMap["a"], cloneMap["a"])
			assert.EqualValues(t, aMap["b"], cloneMap["b"])
			assert.EqualValues(t, toolbox.AsSlice(aMap["c"]), cloneMap["c"])

		}
	}

}
<|endoftext|>


<commit_before>/*
 * Spreed Speak Freely.
 * Copyright (C) 2013-2014 struktur AG
 *
 * This file is part of Spreed Speak Freely.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package main

import (
	"crypto/rand"
	pseudoRand "math/rand"
	"time"
)

const (
	dict = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW0123456789"
)

func RandomString(length int) string {

	buf := make([]byte, length)
	_, err := rand.Read(buf)
	if err != nil {
		// fallback to pseudo-random
		for i := 0; i < length; i++ {
			buf[i] = dict[pseudoRand.Intn(len(dict))]
		}
	} else {
		for i := 0; i < length; i++ {
			buf[i] = dict[int(buf[i])%len(dict)]
		}
	}
	return string(buf)

}

func init() {
	// Make sure to seed default random generator.
	pseudoRand.Seed(time.Now().UTC().UnixNano())
}
<commit_msg>Added method to generate URL-safe random string.<commit_after>/*
 * Spreed Speak Freely.
 * Copyright (C) 2013-2014 struktur AG
 *
 * This file is part of Spreed Speak Freely.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package main

import (
	"crypto/rand"
	"encoding/base64"
	pseudoRand "math/rand"
	"time"
)

const (
	dict = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW0123456789"
)

func RandomString(length int) string {

	buf := make([]byte, length)
	_, err := rand.Read(buf)
	if err != nil {
		// fallback to pseudo-random
		for i := 0; i < length; i++ {
			buf[i] = dict[pseudoRand.Intn(len(dict))]
		}
	} else {
		for i := 0; i < length; i++ {
			buf[i] = dict[int(buf[i])%len(dict)]
		}
	}
	return string(buf)

}

func RandomUrlString(length int) string {

	buf := make([]byte, length)
	_, err := rand.Read(buf)
	if err != nil {
		// fallback to pseudo-random
		for i := 0; i < length; i++ {
			buf[i] = byte(pseudoRand.Intn(256))
		}
	}
	return base64.URLEncoding.EncodeToString(buf)

}

func init() {
	// Make sure to seed default random generator.
	pseudoRand.Seed(time.Now().UTC().UnixNano())
}
<|endoftext|>


<commit_before>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package http

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"testing"
	"time"

	"github.com/TheThingsNetwork/ttn/core"
	"github.com/TheThingsNetwork/ttn/lorawan"
	"github.com/TheThingsNetwork/ttn/utils/pointer"
	. "github.com/TheThingsNetwork/ttn/utils/testing"
	"github.com/apex/log"
)

// Send(p core.Packet, r ...core.Recipient) error
func TestSend(t *testing.T) {
	tests := []struct {
		Packet      core.Packet
		WantPayload string
		WantError   error
	}{
		{
			genCorePacket(),
			genJSONPayload(genCorePacket()),
			nil,
		},
		{
			core.Packet{},
			"",
			ErrInvalidPacket,
		},
	}

	s := genMockServer(3100)

	// Logging
	log.SetHandler(NewLogHandler(t))
	ctx := log.WithFields(log.Fields{
		"tag": "Adapter",
	})

	adapter, err := NewAdapter(3101, ctx)
	if err != nil {
		panic(err)
	}

	for _, test := range tests {
		Desc(t, "Sending packet: %v", test.Packet)
		<-time.After(time.Millisecond * 100)
		_, err := adapter.Send(test.Packet, s.Recipient)
		checkErrors(t, test.WantError, err)
		checkSend(t, test.WantPayload, s)
	}
}

// Check utilities
func checkErrors(t *testing.T, want error, got error) {
	if want == got {
		Ok(t, "Check errors")
		return
	}
	Ko(t, "Expected error to be {%v} but got {%v}", want, got)
}

func checkSend(t *testing.T, want string, s MockServer) {
	select {
	case got := <-s.Payloads:
		if want != got {
			Ko(t, "Received payload does not match expectations.\nWant: %s\nGot:  %s", want, got)
			return
		}
	case <-time.After(time.Millisecond * 100):
		if want != "" {
			Ko(t, "Expected payload %s to be sent but got nothing", want)
			return
		}
	}
	Ok(t, "Check send result")
}

// Build utilities
type MockServer struct {
	Recipient core.Recipient
	Payloads  chan string
}

func genMockServer(port uint) MockServer {
	addr := fmt.Sprintf("0.0.0.0:%d", port)
	payloads := make(chan string)

	serveMux := http.NewServeMux()
	serveMux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		body := make([]byte, 256)
		n, err := req.Body.Read(body)
		if err != nil && err != io.EOF {
			panic(err)
		}
		w.Write(body[:n]) // NOTE TEMPORARY, the response is supposed to be different
		go func() { payloads <- string(body[:n]) }()
	})

	go func() {
		server := http.Server{
			Handler: serveMux,
			Addr:    addr,
		}
		server.ListenAndServe()
	}()

	<-time.After(time.Millisecond * 50)

	return MockServer{
		Recipient: core.Recipient{
			Address: addr,
			Id:      "Mock server",
		},
		Payloads: payloads,
	}
}

// Generate a Physical payload representing an uplink message
func genPHYPayload(msg string, devAddr [4]byte) lorawan.PHYPayload {
	nwkSKey := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
	appSKey := [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}

	macPayload := lorawan.NewMACPayload(true)
	macPayload.FHDR = lorawan.FHDR{
		DevAddr: lorawan.DevAddr(devAddr),
		FCtrl: lorawan.FCtrl{
			ADR:       false,
			ADRACKReq: false,
			ACK:       false,
		},
		FCnt: 0,
	}
	macPayload.FPort = 10
	macPayload.FRMPayload = []lorawan.Payload{&lorawan.DataPayload{Bytes: []byte(msg)}}

	if err := macPayload.EncryptFRMPayload(appSKey); err != nil {
		panic(err)
	}

	payload := lorawan.NewPHYPayload(true)
	payload.MHDR = lorawan.MHDR{
		MType: lorawan.ConfirmedDataUp,
		Major: lorawan.LoRaWANR1,
	}
	payload.MACPayload = macPayload

	if err := payload.SetMIC(nwkSKey); err != nil {
		panic(err)
	}

	return payload
}

func genCorePacket() core.Packet {
	return core.Packet{
		Payload:  genPHYPayload("myData", [4]byte{0x1, 0x2, 0x3, 0x4}),
		Metadata: core.Metadata{Rssi: pointer.Int(-20), Modu: pointer.String("LORA")},
	}
}

func genJSONPayload(p core.Packet) string {
	raw, err := p.Payload.MarshalBinary()
	if err != nil {
		panic(err)
	}
	payload := base64.StdEncoding.EncodeToString(raw)
	metadatas, err := json.Marshal(p.Metadata)
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf(`{"payload":"%s","metadata":%s}`, payload, string(metadatas))
}
<commit_msg>Write tests for next() method<commit_after>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package http

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"testing"
	"time"

	"github.com/TheThingsNetwork/ttn/core"
	"github.com/TheThingsNetwork/ttn/lorawan"
	"github.com/TheThingsNetwork/ttn/utils/pointer"
	. "github.com/TheThingsNetwork/ttn/utils/testing"
	"github.com/apex/log"
	"reflect"
)

// Send(p core.Packet, r ...core.Recipient) error
func TestSend(t *testing.T) {
	tests := []struct {
		Packet      core.Packet
		WantPayload string
		WantError   error
	}{
		{
			genCorePacket(),
			genJSONPayload(genCorePacket()),
			nil,
		},
		{
			core.Packet{},
			"",
			ErrInvalidPacket,
		},
	}

	s := genMockServer(3100)

	// Logging
	log.SetHandler(NewLogHandler(t))
	ctx := log.WithFields(log.Fields{
		"tag": "Adapter",
	})

	adapter, err := NewAdapter(3101, JSONPacketParser{}, ctx)
	if err != nil {
		panic(err)
	}

	for _, test := range tests {
		Desc(t, "Sending packet: %v", test.Packet)
		<-time.After(time.Millisecond * 100)
		_, err := adapter.Send(test.Packet, s.Recipient)
		checkErrors(t, test.WantError, err)
		checkSend(t, test.WantPayload, s)
	}
}

// Next() (core.Packet, an core.AckNacker, error)
func TestNext(t *testing.T) {
	tests := []struct {
		Payload    string
		IsNotFound bool
		WantPacket core.Packet
		WantStatus int
		WantError  error
	}{
		{
			Payload:    genJSONPayload(genCorePacket()),
			IsNotFound: false,
			WantPacket: genCorePacket(),
			WantStatus: http.StatusOK,
			WantError:  nil,
		},
		{
			Payload:    genJSONPayload(genCorePacket()),
			IsNotFound: true,
			WantPacket: genCorePacket(),
			WantStatus: http.StatusNotFound,
			WantError:  nil,
		},
		{
			Payload:    "Patate",
			IsNotFound: false,
			WantPacket: core.Packet{},
			WantStatus: http.StatusBadRequest,
			WantError:  nil,
		},
	}
	// Build
	log.SetHandler(NewLogHandler(t))
	ctx := log.WithFields(log.Fields{"tag": "Adapter"})
	adapter, err := NewAdapter(3102, JSONPacketParser{}, ctx)
	if err != nil {
		panic(err)
	}

	c := client{adapter: "0.0.0.0:3102"}

	for _, test := range tests {
		// Describe
		Desc(t, "Send payload to the adapter %s", test.Payload)
		<-time.After(time.Millisecond * 100)

		// Operate
		gotPacket := make(chan core.Packet)
		gotError := make(chan error)
		go func() {
			packet, an, err := adapter.Next()
			if err != nil {
				if test.IsNotFound {
					an.Nack()
				} else {
					an.Ack(core.Packet{})
				}
			}
			gotError <- err
			gotPacket <- packet
		}()

		resp := c.send(test.Payload)

		// Check
		select {
		case err := <-gotError:
			checkErrors(t, test.WantError, err)
		case <-time.After(time.Millisecond * 250):
			checkErrors(t, test.WantError, nil)
		}

		select {
		case packet := <-gotPacket:
			checkPackets(t, test.WantPacket, packet)
		case <-time.After(time.Millisecond * 250):
			checkPackets(t, test.WantPacket, core.Packet{})
		}

		checkStatus(t, test.WantStatus, resp.StatusCode)
	}
}

// Check utilities
func checkErrors(t *testing.T, want error, got error) {
	if want == got {
		Ok(t, "Check errors")
		return
	}
	Ko(t, "Expected error to be {%v} but got {%v}", want, got)
}

func checkSend(t *testing.T, want string, s MockServer) {
	select {
	case got := <-s.Payloads:
		if want != got {
			Ko(t, "Received payload does not match expectations.\nWant: %s\nGot:  %s", want, got)
			return
		}
	case <-time.After(time.Millisecond * 100):
		if want != "" {
			Ko(t, "Expected payload %s to be sent but got nothing", want)
			return
		}
	}
	Ok(t, "Check send result")
}

func checkPackets(t *testing.T, want core.Packet, got core.Packet) {
	if reflect.DeepEqual(want, got) {
		Ok(t, "Check packets")
		return
	}
	Ko(t, "Received packet does not match expectations.\nWant: %s\nGot:  %s", want, got)
}

func checkStatus(t *testing.T, want int, got int) {
	if want == got {
		Ok(t, "Check status")
		return
	}
	Ko(t, "Expected status to be %d but got %d", want, got)
}

// Build utilities
type MockServer struct {
	Recipient core.Recipient
	Payloads  chan string
}

func genMockServer(port uint) MockServer {
	addr := fmt.Sprintf("0.0.0.0:%d", port)
	payloads := make(chan string)

	serveMux := http.NewServeMux()
	serveMux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		body := make([]byte, 256)
		n, err := req.Body.Read(body)
		if err != nil && err != io.EOF {
			panic(err)
		}
		w.Write(body[:n]) // NOTE TEMPORARY, the response is supposed to be different
		go func() { payloads <- string(body[:n]) }()
	})

	go func() {
		server := http.Server{
			Handler: serveMux,
			Addr:    addr,
		}
		server.ListenAndServe()
	}()

	<-time.After(time.Millisecond * 50)

	return MockServer{
		Recipient: core.Recipient{
			Address: addr,
			Id:      "Mock server",
		},
		Payloads: payloads,
	}
}

// Generate a Physical payload representing an uplink message
func genPHYPayload(msg string, devAddr [4]byte) lorawan.PHYPayload {
	nwkSKey := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
	appSKey := [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}

	macPayload := lorawan.NewMACPayload(true)
	macPayload.FHDR = lorawan.FHDR{
		DevAddr: lorawan.DevAddr(devAddr),
		FCtrl: lorawan.FCtrl{
			ADR:       false,
			ADRACKReq: false,
			ACK:       false,
		},
		FCnt: 0,
	}
	macPayload.FPort = 10
	macPayload.FRMPayload = []lorawan.Payload{&lorawan.DataPayload{Bytes: []byte(msg)}}

	if err := macPayload.EncryptFRMPayload(appSKey); err != nil {
		panic(err)
	}

	payload := lorawan.NewPHYPayload(true)
	payload.MHDR = lorawan.MHDR{
		MType: lorawan.ConfirmedDataUp,
		Major: lorawan.LoRaWANR1,
	}
	payload.MACPayload = macPayload

	if err := payload.SetMIC(nwkSKey); err != nil {
		panic(err)
	}

	return payload
}

func genCorePacket() core.Packet {
	return core.Packet{
		Payload:  genPHYPayload("myData", [4]byte{0x1, 0x2, 0x3, 0x4}),
		Metadata: core.Metadata{Rssi: pointer.Int(-20), Modu: pointer.String("LORA")},
	}
}

func genJSONPayload(p core.Packet) string {
	raw, err := json.Marshal(p)
	if err != nil {
		panic(err)
	}
	return string(raw)
}

type client struct {
	http.Client
	adapter string
}

// Operate utilities
// send is a convinient helper to send HTTP from a handler to the adapter
func (c *client) send(payload string) http.Response {
	buf := new(bytes.Buffer)
	if _, err := buf.WriteString(payload); err != nil {
		panic(err)
	}
	request, err := http.NewRequest("POST", fmt.Sprintf("http://%s/packets/", c.adapter), buf)
	if err != nil {
		panic(err)
	}
	request.Header.Set("Content-Type", "application/json")
	resp, err := c.Do(request)
	if err != nil {
		panic(err)
	}
	return *resp
}
<|endoftext|>


<commit_before>// gitbot project gitbot.go
package gitbot

import (
	"encoding/json"
	"fmt"
	"github.com/aarondl/gitio"
	"github.com/aarondl/ultimateq/data"
	"log"
	"net/http"
	"strings"
)

var (
	Endpoint *data.DataEndpoint
	Port     string
	Chan     string
)

type Payload struct {
	Before      string
	After       string
	Ref         string
	Compare     string
	Created     bool
	Deleted     bool
	Forced      bool
	Commits     []*Commit
	Head_commit *Commit
	Pusher      *Person //may not have Username, beware
	Repository  *Repository
}

type Commit struct {
	Added     []string
	Modified  []string
	Removed   []string
	Author    *Person
	Committer *Person
	Distinct  bool
	Id        string
	Message   string
	Timestamp string //Might be able to use time here
	Url       string
}

type Person struct {
	Email    string
	Name     string
	Username string
}

type Repository struct {
	Created_at    uint64
	Description   string
	Fork          bool
	Forks         uint
	Has_downloads bool
	Has_issues    bool
	Has_wiki      bool
	Homepage      string
	Id            uint
	Language      string
	Master_branch string
	Name          string
	Open_issues   uint
	Owner         *Person
	Private       bool
	Pushed_at     uint64
	Size          uint
	Stargazers    uint
	Url           string
	Watchers      uint
}

func alertChan(pl Payload) {
	name := pl.Repository.Name
	num := len(pl.Commits)
	who := pl.Pusher.Name
	refs := strings.Split(pl.Ref, "/")
	branch := refs[len(refs)-1]
	comp, err := gitio.Shorten(pl.Compare)
	if err != nil {
		comp = pl.Compare
	}

	msg := fmt.Sprintf("[%s] %s pushed %v commits to %s %s", name, who, num, branch, comp)
	Endpoint.Privmsg(Chan, msg)

	var c *Commit
	for i := 0; i < num; i++ {
		c = pl.Commits[i]
		msg = fmt.Sprintf("[%s/%s] %s: %s: %s", name, branch, c.Id[:7], c.Committer.Username, c.Message)
		Endpoint.Privmsg(Chan, msg)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	payload := r.FormValue("payload")
	var Pl Payload
	err := json.Unmarshal([]byte(payload), &Pl)
	if err != nil {
		log.Println(err)
	}
}

//Start the http listener
func Listen() (err error) {
	http.HandleFunc("/", handler)
	err = http.ListenAndServe(":"+Port, nil)
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>changing things of course<commit_after>// gitbot project gitbot.go
package gitbot

import (
	"encoding/json"
	"fmt"
	"github.com/aarondl/gitio"
	"github.com/aarondl/ultimateq/data"
	"log"
	"net/http"
	"strings"
)

var (
	Endpoint *data.DataEndpoint
	Channel  string
)

const (
	MSG1 = "[%s] %s pushed %v commits to %s %s"
	MSG2 = "[%s/%s] %s: %s: %s"
)

type Commit struct {
	Added     []string
	Modified  []string
	Removed   []string
	Author    *Person
	Committer *Person
	Distinct  bool
	Id        string
	Message   string
	Timestamp string //Might be able to use time here
	Url       string
}

func (c Commit) User() string {
	if c.Committer == nil || c.Committer.Username == "" {
		return "\x02Unknown\x02"
	}
	return c.Committer.Username
}

func (c Commit) ShortId() string {
	if c.Id == "" {
		return "\x02Unknown\x02"
	}
	if len(c.Id) < 7 {
		return c.Id
	}
	return c.Id[:7]
}

func (c Commit) Msg() string {
	if c.Message == "" {
		return "No message"
	}
	return c.Message
}

type Person struct {
	Email    string
	Name     string
	Username string
}

type Repository struct {
	Created_at    uint64
	Description   string
	Fork          bool
	Forks         uint
	Has_downloads bool
	Has_issues    bool
	Has_wiki      bool
	Homepage      string
	Id            uint
	Language      string
	Master_branch string
	Name          string
	Open_issues   uint
	Owner         *Person
	Private       bool
	Pushed_at     uint64
	Size          uint
	Stargazers    uint
	Url           string
	Watchers      uint
}

type Payload struct {
	Before      string
	After       string
	Ref         string
	Compare     string
	Created     bool
	Deleted     bool
	Forced      bool
	Commits     []*Commit
	Head_commit *Commit
	Pusher      *Person //may not have Username, beware
	Repository  *Repository
}

func (pl Payload) Branch() string {
	refs := strings.Split(pl.Ref, "/")
	return refs[len(refs)-1]
}

func (pl Payload) Name() string {
	if pl.Repository == nil || pl.Repository.Name == "" {
		return "\x02Unknown\x02"
	}
	return pl.Repository.Name
}

func (pl Payload) NumCommits() int {
	if pl.Commits == nil {
		return 0
	}
	return len(pl.Commits)
}

func (pl Payload) PusherName() string {
	if pl.Pusher == nil || pl.Pusher.Name == "" {
		return "\x02Unknown\x02"
	}
	return pl.Pusher.Name
}

func alertChan(pl Payload) {
	name := pl.Name()
	num := pl.NumCommits()
	who := pl.PusherName()
	branch := pl.Branch()
	comp, err := gitio.Shorten(pl.Compare)
	if err != nil {
		comp = pl.Compare
	}

	msg := fmt.Sprintf(MSG1, name, who, num, branch, comp)
	Endpoint.Privmsg(Channel, msg)

	var c *Commit
	for i := 0; i < num; i++ {
		c = pl.Commits[i]
		msg = fmt.Sprintf(MSG2, name, branch, c.ShortId(), c.User(), c.Message)
		Endpoint.Privmsg(Channel, msg)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	payload := r.FormValue("payload")
	var Pl Payload
	err := json.Unmarshal([]byte(payload), &Pl)
	if err != nil {
		log.Println(err)
		return
	}
	alertChan(Pl)
}

//Start the http listener
func Listen(port, channel string, endpoint *data.DataEndpoint) (err error) {
	Channel = channel
	Endpoint = endpoint
	http.HandleFunc("/", handler)
	err = http.ListenAndServe(":"+port, nil)
	return
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/coreos/go-systemd/unit"
	"github.com/urfave/cli"
)

type FourGState struct {
	Enabled bool   `json:"enabled"`
	Configg *FourG `json:"config"`
}

type FourG struct {
	Network
}

//ToSystemdUnit implement UnitFile interface
func (f FourG) ToSystemdUnit() ([]*unit.UnitOption, error) {
	if f.Interface == "" {
		f.Interface = "eth1"
	}
	return f.Network.ToSystemdUnit()
}

func fourGState(i string) (*FourGState, error) {
	dir := os.Getenv("FCONF_CONFIGDIR")
	if dir == "" {
		dir = fconfConfigDir
	}
	b, err := ioutil.ReadFile(filepath.Join(dir,
		fmt.Sprintf(defaultFougGConfig, i)))
	if err != nil {
		return nil, err
	}
	f := &FourGState{}
	err = json.Unmarshal(b, f)
	if err != nil {
		return nil, err
	}
	if f.Configg == nil {
		return nil, ErrWrongStateFile
	}
	return f, nil
}

func FourgCMD(ctx *cli.Context) error {
	if ctx.IsSet(enableFlag) {
		return EnableFourg(ctx)
	}
	if ctx.IsSet(disableFlag) {
		return DisableFourg(ctx)
	}
	if ctx.IsSet(removeFlag) {
		return RemoveFourg(ctx)
	}
	if ctx.IsSet(configFlag) {
		return configFourgCMD(ctx)
	}
	return nil
}
func RemoveFourg(ctx *cli.Context) error {
	err := DisableFourg(ctx)
	if err != nil {
		return err
	}
	var i string
	if ctx.IsSet("interface") {
		i = ctx.String("interface")
	} else {
		i = ctx.Args().First()
	}
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	f, err := fourGState(i)
	if err != nil {
		return err
	}

	// removestate file
	stateFile := filepath.Join(stateDir(),
		fmt.Sprintf(defaultFougGConfig, i))
	err = removeFile(stateFile)
	if err != nil {
		return err
	}
	// remove systemd file
	unit := filepath.Join(networkBase,
		fmt.Sprintf(fourgService, i))
	err = removeFile(unit)
	if err != nil {
		return err
	}

	err = FlushInterface(f.Configg.Interface)
	if err != nil {
		return err
	}

	// reload systemd-networkd
	return restartService("systemd-networkd")
}
func EnableFourg(ctx *cli.Context) error {
	if ctx.IsSet(configFlag) {
		err := configFourgCMD(ctx)
		if err != nil {
			return err
		}
	}
	var i string
	if ctx.IsSet("interface") {
		i = ctx.String("interface")
	} else {
		i = ctx.Args().First()
	}
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	e, err := fourGState(i)
	if err != nil {
		return err
	}
	unit := filepath.Join(networkBase,
		fmt.Sprintf(fourgService, e.Configg.Interface))
	_, err = os.Stat(unit)
	if os.IsNotExist(err) {
		err = CreateSystemdFile(e.Configg, unit, 0644)
		if err != nil {
			return err
		}
	}
	_, err = exec.Command("ip", "link", "set", "up", e.Configg.Interface).Output()
	if err != nil {
		return fmt.Errorf("ERROR: runnin ip link set up %s %v",
			e.Configg.Interface, err,
		)
	}
	err = restartService("systemd-networkd")
	if err != nil {
		return fmt.Errorf("ERROR: restarting systemd %v ", err)
	}
	e.Enabled = true
	data, err := json.Marshal(e)
	if err != nil {
		return err
	}
	return keepState(
		fmt.Sprintf(defaultFougGConfig, i), data)
}

func DisableFourg(ctx *cli.Context) error {
	var i string
	if ctx.IsSet("interface") {
		i = ctx.String("interface")
	} else {
		i = ctx.Args().First()
	}
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	e, err := fourGState(i)
	if err != nil {
		return err
	}
	_, err = exec.Command("ip", "link", "set", "down", "dev", e.Configg.Interface).Output()
	if err != nil {
		return err
	}
	unit := filepath.Join(networkBase,
		fmt.Sprintf(fourgService, e.Configg.Interface))
	err = removeFile(unit)
	if err != nil {
		return err
	}
	fmt.Println("successfully disabled 4G")
	e.Enabled = false
	data, err := json.Marshal(e)
	if err != nil {
		return err
	}
	ctx.Set("interface", i)
	return keepState(
		fmt.Sprintf(defaultFougGConfig, i), data)
}

func configFourgCMD(ctx *cli.Context) error {
	base := ctx.String("dir")
	name := ctx.String("name")
	src := ctx.String("config")
	if src == "" {
		return errors.New("fconf: missing configuration source file")
	}
	var b []byte
	var err error
	if src == "stdin" {
		b, err = ReadFromStdin()
		if err != nil {
			return err
		}
	} else {
		b, err = ioutil.ReadFile(src)
		if err != nil {
			return err
		}
	}
	e := FourG{}
	err = json.Unmarshal(b, &e)
	if err != nil {
		return err
	}
	if e.Interface == "" {
		e.Interface = "eth1"
	}
	err = checkDir(base)
	if err != nil {
		return err
	}
	if strings.Contains(name, "%s") {
		name = fmt.Sprintf(name, e.Interface)
	}
	filename := filepath.Join(base, name)
	err = CreateSystemdFile(e, filename, 0644)
	if err != nil {
		return err
	}
	fmt.Printf("successful written 4G configuration to %s \n", filename)
	state := &FourGState{Configg: &e}
	b, _ = json.Marshal(state)
	return keepState(
		fmt.Sprintf(defaultFougGConfig, e.Interface), b)
}
<commit_msg>4g : Fix getting interface<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/coreos/go-systemd/unit"
	"github.com/urfave/cli"
)

type FourGState struct {
	Enabled bool   `json:"enabled"`
	Configg *FourG `json:"config"`
}

type FourG struct {
	Network
}

//ToSystemdUnit implement UnitFile interface
func (f FourG) ToSystemdUnit() ([]*unit.UnitOption, error) {
	if f.Interface == "" {
		f.Interface = "eth1"
	}
	return f.Network.ToSystemdUnit()
}

func fourGState(i string) (*FourGState, error) {
	dir := os.Getenv("FCONF_CONFIGDIR")
	if dir == "" {
		dir = fconfConfigDir
	}
	b, err := ioutil.ReadFile(filepath.Join(dir,
		fmt.Sprintf(defaultFougGConfig, i)))
	if err != nil {
		return nil, err
	}
	f := &FourGState{}
	err = json.Unmarshal(b, f)
	if err != nil {
		return nil, err
	}
	if f.Configg == nil {
		return nil, ErrWrongStateFile
	}
	return f, nil
}

func FourgCMD(ctx *cli.Context) error {
	if ctx.IsSet(enableFlag) {
		return EnableFourg(ctx)
	}
	if ctx.IsSet(disableFlag) {
		return DisableFourg(ctx)
	}
	if ctx.IsSet(removeFlag) {
		return RemoveFourg(ctx)
	}
	if ctx.IsSet(configFlag) {
		return configFourgCMD(ctx)
	}
	return nil
}

func getInterface(ctx *cli.Context) string {
	var i string
	if ctx.GlobalIsSet("interface") {
		i = ctx.GlobalString("interface")
	} else {
		i = ctx.Args().First()
	}
	return i
}
func RemoveFourg(ctx *cli.Context) error {
	err := DisableFourg(ctx)
	if err != nil {
		return err
	}
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	f, err := fourGState(i)
	if err != nil {
		return err
	}

	// removestate file
	stateFile := filepath.Join(stateDir(),
		fmt.Sprintf(defaultFougGConfig, i))
	err = removeFile(stateFile)
	if err != nil {
		return err
	}
	// remove systemd file
	unit := filepath.Join(networkBase,
		fmt.Sprintf(fourgService, i))
	err = removeFile(unit)
	if err != nil {
		return err
	}

	err = FlushInterface(f.Configg.Interface)
	if err != nil {
		return err
	}

	// reload systemd-networkd
	return restartService("systemd-networkd")
}
func EnableFourg(ctx *cli.Context) error {
	if ctx.IsSet(configFlag) {
		err := configFourgCMD(ctx)
		if err != nil {
			return err
		}
	}
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	e, err := fourGState(i)
	if err != nil {
		return err
	}
	unit := filepath.Join(networkBase,
		fmt.Sprintf(fourgService, e.Configg.Interface))
	_, err = os.Stat(unit)
	if os.IsNotExist(err) {
		err = CreateSystemdFile(e.Configg, unit, 0644)
		if err != nil {
			return err
		}
	}
	_, err = exec.Command("ip", "link", "set", "up", e.Configg.Interface).Output()
	if err != nil {
		return fmt.Errorf("ERROR: runnin ip link set up %s %v",
			e.Configg.Interface, err,
		)
	}
	err = restartService("systemd-networkd")
	if err != nil {
		return fmt.Errorf("ERROR: restarting systemd %v ", err)
	}
	e.Enabled = true
	data, err := json.Marshal(e)
	if err != nil {
		return err
	}
	return keepState(
		fmt.Sprintf(defaultFougGConfig, i), data)
}

func DisableFourg(ctx *cli.Context) error {
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	e, err := fourGState(i)
	if err != nil {
		return err
	}
	_, err = exec.Command("ip", "link", "set", "down", "dev", e.Configg.Interface).Output()
	if err != nil {
		return err
	}
	unit := filepath.Join(networkBase,
		fmt.Sprintf(fourgService, e.Configg.Interface))
	err = removeFile(unit)
	if err != nil {
		return err
	}
	fmt.Println("successfully disabled 4G")
	e.Enabled = false
	data, err := json.Marshal(e)
	if err != nil {
		return err
	}
	return keepState(
		fmt.Sprintf(defaultFougGConfig, i), data)
}

func configFourgCMD(ctx *cli.Context) error {
	base := ctx.String("dir")
	name := ctx.String("name")
	src := ctx.String("config")
	if src == "" {
		return errors.New("fconf: missing configuration source file")
	}
	var b []byte
	var err error
	if src == "stdin" {
		b, err = ReadFromStdin()
		if err != nil {
			return err
		}
	} else {
		b, err = ioutil.ReadFile(src)
		if err != nil {
			return err
		}
	}
	e := FourG{}
	err = json.Unmarshal(b, &e)
	if err != nil {
		return err
	}
	if e.Interface == "" {
		e.Interface = "eth1"
	}
	err = checkDir(base)
	if err != nil {
		return err
	}
	if strings.Contains(name, "%s") {
		name = fmt.Sprintf(name, e.Interface)
	}
	filename := filepath.Join(base, name)
	err = CreateSystemdFile(e, filename, 0644)
	if err != nil {
		return err
	}
	fmt.Printf("successful written 4G configuration to %s \n", filename)
	state := &FourGState{Configg: &e}
	ctx.GlobalSet("interface", e.Interface)
	b, _ = json.Marshal(state)
	return keepState(
		fmt.Sprintf(defaultFougGConfig, e.Interface), b)
}
<|endoftext|>


<commit_before>package mongo

import (
  "gopkg.in/mgo.v2"
  "log"
)

type Mongo struct {
  database  *mgo.Database
  session   *mgo.Session
}

func NewMongo(cs string, db string) *Mongo {
  session, err := mgo.Dial(cs)
  if err != nil {
    panic(err)
  }

  database := session.DB(db)

  return &Mongo {
    database : database,
    session  : session,
  }
}

func (this *Mongo) Exists(collectionName string, id interface{}) bool {
  collection := this.database.C(collectionName)
  count, err := collection.FindId(id).Limit(1).Count()
  if err != nil {
      log.Print(err)
  }
  if count > 0 {
      return true
  }
  return false
}

func (this *Mongo) Create(collectionName string, document ...interface{}) {
  collection := this.database.C(collectionName)
  err := collection.Insert(document)
  if err != nil {
    log.Print(err)
  }
}

func (this *Mongo) Close() {
  this.session.Close()
}<commit_msg>Add FindAll and FindById<commit_after>package mongo

import (
  "gopkg.in/mgo.v2"
  "log"
)

type Mongo struct {
  database  *mgo.Database
  session   *mgo.Session
}

func NewMongo(cs string, db string) *Mongo {
  session, err := mgo.Dial(cs)
  if err != nil {
    panic(err)
  }

  database := session.DB(db)

  return &Mongo {
    database : database,
    session  : session,
  }
}

func (this *Mongo) FindAll(collectionName string, result interface{})  {
  err := this.database.C(collectionName).Find(nil).All(result)

  if err != nil {
    log.Print(err)
  }
}

func (this *Mongo) FindById(collectionName string, id interface{}, result interface{})  {
  err := this.database.C(collectionName).FindId(id).One(result)
  if err != nil {
    log.Print(err)
  }
}

func (this *Mongo) Exists(collectionName string, id interface{}) bool {
  collection := this.database.C(collectionName)
  count, err := collection.FindId(id).Limit(1).Count()
  if err != nil {
      log.Print(err)
  }
  if count > 0 {
      return true
  }
  return false
}

func (this *Mongo) Create(collectionName string, document ...interface{}) {
  collection := this.database.C(collectionName)
  err := collection.Insert(document)
  if err != nil {
    log.Print(err)
  }
}

func (this *Mongo) Close() {
  this.session.Close()
}<|endoftext|>


<commit_before>/*
	The mongo package is a very simple wrapper around the labix.org/v2/mgo
	package. It's purpose is to allow you to do CRUD operations with very
	little code. It's not exhaustive and not meant to do everything for you.
*/
package mongo

import (
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"

	"errors"
	"fmt"
	"reflect"
	"time"
)

var (
	mgoSession *mgo.Session
	servers    string
	database   string
	NoPtr      = errors.New("You must pass in a pointer")
)

// Set the mongo servers and the database
func SetServers(servers, db string) error {
	var err error

	database = db

	mgoSession, err = mgo.Dial(servers)
	return err
}

// Insert one or more structs. Must pass in a pointer to a struct. The struct must
// contain an Id field of type bson.ObjectId with a tag of `bson:"_id"`.
func Insert(records ...interface{}) error {
	for _, rec := range records {
		if !isPtr(rec) {
			return NoPtr
		}

		if err := addNewFields(rec); err != nil {
			return err
		}

		s, err := GetSession()
		if err != nil {
			return err
		}
		defer s.Close()

		coll := GetColl(s, typeName(rec))
		err = coll.Insert(rec)
		if err != nil {
			return err
		}
	}

	return nil
}

// Find one or more records. If a single struct is passed in we'll return one record.
// If a slice is passed in all records will be returned. Must pass in a pointer to a
// struct or slice of structs.
func Find(i interface{}, q bson.M) error {
	if !isPtr(i) {
		return NoPtr
	}

	s, err := GetSession()
	if err != nil {
		return err
	}
	defer s.Close()

	coll := GetColl(s, typeName(i))

	query := coll.Find(q)

	if isSlice(reflect.TypeOf(i)) {
		err = query.All(i)
	} else {
		err = query.One(i)
	}
	return err
}

// Find a single record by id. Must pass a pointer to a struct.
func FindById(i interface{}, id string) error {
	return Find(i, bson.M{"_id": id})
}

// Updates a record. Uses the Id to identify the record to update. Must pass in a pointer
// to a struct.
func Update(i interface{}) error {
	if !isPtr(i) {
		return NoPtr
	}

	err := addCurrentDateTime(i, "UpdatedAt")
	if err != nil {
		return err
	}

	s, err := GetSession()
	if err != nil {
		return err
	}
	defer s.Close()

	id, err := getObjIdFromStruct(i)
	if err != nil {
		return err
	}

	return GetColl(s, typeName(i)).Update(bson.M{"_id": id}, i)
}

// Deletes a record. Uses the Id to identify the record to delete. Must pass in a pointer
// to a struct.
func Delete(i interface{}) error {
	if !isPtr(i) {
		return NoPtr
	}

	s, err := GetSession()
	if err != nil {
		return err
	}
	defer s.Close()

	id, err := getObjIdFromStruct(i)
	if err != nil {
		return err
	}

	return GetColl(s, typeName(i)).RemoveId(id)
}

// Returns a Mongo session. You must call Session.Close() when you're done.
func GetSession() (*mgo.Session, error) {
	var err error

	if mgoSession == nil {
		mgoSession, err = mgo.Dial(servers)
		if err != nil {
			return nil, err
		}
	}

	return mgoSession.Clone(), nil
}

// We pass in the session because that is a clone of the original and the
// caller will need to close it when finished.
func GetColl(session *mgo.Session, coll string) *mgo.Collection {
	return session.DB(database).C(coll)
}

func getObjIdFromStruct(i interface{}) (bson.ObjectId, error) {
	v := reflect.ValueOf(i)

	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Struct {
		return bson.ObjectId(""), errors.New("Can't delete record. Type must be a struct.")
	}

	f := v.FieldByName("Id")
	if f.Kind() == reflect.Ptr {
		f = f.Elem()
	}

	return f.Interface().(bson.ObjectId), nil
}

func isPtr(i interface{}) bool {
	return reflect.ValueOf(i).Kind() == reflect.Ptr
}

func typeName(i interface{}) string {
	t := reflect.TypeOf(i)

	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	if isSlice(t) {
		t = t.Elem()

		if t.Kind() == reflect.Ptr {
			t = t.Elem()
		}
	}

	return t.Name()
}

// returns true if the interface is a slice
func isSlice(t reflect.Type) bool {
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	return t.Kind() == reflect.Slice
}

func addNewFields(i interface{}) error {
	err := addId(i)
	if err != nil {
		return err
	}

	if err := addCurrentDateTime(i, "CreatedAt"); err != nil {
		return err
	}

	return addCurrentDateTime(i, "UpdatedAt")
}

func addCurrentDateTime(i interface{}, name string) error {
	if !hasStructField(i, name) {
		return nil
	}

	now := time.Now()

	v := reflect.ValueOf(i)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	f := v.FieldByName(name)
	if f.Kind() == reflect.Ptr {
		f = f.Elem()
	}

	if reflect.TypeOf(now) != f.Type() {
		return fmt.Errorf("%v must be time.Time type.", name)
	}

	if !f.CanSet() {
		return fmt.Errorf("Couldn't set time for field: %v", name)
	}

	f.Set(reflect.ValueOf(now))

	return nil
}

func hasStructField(i interface{}, field string) bool {
	t := reflect.TypeOf(i)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	if t.Kind() != reflect.Struct {
		return false
	}

	_, found := t.FieldByName(field)
	return found
}

func addId(i interface{}) error {
	v := reflect.ValueOf(i)

	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Struct {
		return errors.New("Record must be a struct")
	}

	f := v.FieldByName("Id")
	if f.Kind() == reflect.Ptr {
		f = f.Elem()
	}

	if f.Kind() == reflect.String {
		if !f.Interface().(bson.ObjectId).Valid() {
			id := reflect.ValueOf(bson.NewObjectId())
			f.Set(id)
		}
	}

	return nil
}
<commit_msg>Fix problem with FindbyId()<commit_after>/*
	The mongo package is a very simple wrapper around the labix.org/v2/mgo
	package. It's purpose is to allow you to do CRUD operations with very
	little code. It's not exhaustive and not meant to do everything for you.
*/
package mongo

import (
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"

	"errors"
	"fmt"
	"reflect"
	"time"
)

var (
	mgoSession *mgo.Session
	servers    string
	database   string
	NoPtr      = errors.New("You must pass in a pointer")
)

// Set the mongo servers and the database
func SetServers(servers, db string) error {
	var err error

	database = db

	mgoSession, err = mgo.Dial(servers)
	return err
}

// Insert one or more structs. Must pass in a pointer to a struct. The struct must
// contain an Id field of type bson.ObjectId with a tag of `bson:"_id"`.
func Insert(records ...interface{}) error {
	for _, rec := range records {
		if !isPtr(rec) {
			return NoPtr
		}

		if err := addNewFields(rec); err != nil {
			return err
		}

		s, err := GetSession()
		if err != nil {
			return err
		}
		defer s.Close()

		coll := GetColl(s, typeName(rec))
		err = coll.Insert(rec)
		if err != nil {
			return err
		}
	}

	return nil
}

// Find one or more records. If a single struct is passed in we'll return one record.
// If a slice is passed in all records will be returned. Must pass in a pointer to a
// struct or slice of structs.
func Find(i interface{}, q bson.M) error {
	if !isPtr(i) {
		return NoPtr
	}

	s, err := GetSession()
	if err != nil {
		return err
	}
	defer s.Close()

	coll := GetColl(s, typeName(i))

	query := coll.Find(q)

	if isSlice(reflect.TypeOf(i)) {
		err = query.All(i)
	} else {
		err = query.One(i)
	}
	return err
}

// Find a single record by id. Must pass a pointer to a struct.
func FindById(i interface{}, id string) error {
	return Find(i, bson.M{"_id": bson.ObjectIdHex(id)})
}

// Updates a record. Uses the Id to identify the record to update. Must pass in a pointer
// to a struct.
func Update(i interface{}) error {
	if !isPtr(i) {
		return NoPtr
	}

	err := addCurrentDateTime(i, "UpdatedAt")
	if err != nil {
		return err
	}

	s, err := GetSession()
	if err != nil {
		return err
	}
	defer s.Close()

	id, err := getObjIdFromStruct(i)
	if err != nil {
		return err
	}

	return GetColl(s, typeName(i)).Update(bson.M{"_id": id}, i)
}

// Deletes a record. Uses the Id to identify the record to delete. Must pass in a pointer
// to a struct.
func Delete(i interface{}) error {
	if !isPtr(i) {
		return NoPtr
	}

	s, err := GetSession()
	if err != nil {
		return err
	}
	defer s.Close()

	id, err := getObjIdFromStruct(i)
	if err != nil {
		return err
	}

	return GetColl(s, typeName(i)).RemoveId(id)
}

// Returns a Mongo session. You must call Session.Close() when you're done.
func GetSession() (*mgo.Session, error) {
	var err error

	if mgoSession == nil {
		mgoSession, err = mgo.Dial(servers)
		if err != nil {
			return nil, err
		}
	}

	return mgoSession.Clone(), nil
}

// We pass in the session because that is a clone of the original and the
// caller will need to close it when finished.
func GetColl(session *mgo.Session, coll string) *mgo.Collection {
	return session.DB(database).C(coll)
}

func getObjIdFromStruct(i interface{}) (bson.ObjectId, error) {
	v := reflect.ValueOf(i)

	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Struct {
		return bson.ObjectId(""), errors.New("Can't delete record. Type must be a struct.")
	}

	f := v.FieldByName("Id")
	if f.Kind() == reflect.Ptr {
		f = f.Elem()
	}

	return f.Interface().(bson.ObjectId), nil
}

func isPtr(i interface{}) bool {
	return reflect.ValueOf(i).Kind() == reflect.Ptr
}

func typeName(i interface{}) string {
	t := reflect.TypeOf(i)

	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	if isSlice(t) {
		t = t.Elem()

		if t.Kind() == reflect.Ptr {
			t = t.Elem()
		}
	}

	return t.Name()
}

// returns true if the interface is a slice
func isSlice(t reflect.Type) bool {
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	return t.Kind() == reflect.Slice
}

func addNewFields(i interface{}) error {
	err := addId(i)
	if err != nil {
		return err
	}

	if err := addCurrentDateTime(i, "CreatedAt"); err != nil {
		return err
	}

	return addCurrentDateTime(i, "UpdatedAt")
}

func addCurrentDateTime(i interface{}, name string) error {
	if !hasStructField(i, name) {
		return nil
	}

	now := time.Now()

	v := reflect.ValueOf(i)
	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	f := v.FieldByName(name)
	if f.Kind() == reflect.Ptr {
		f = f.Elem()
	}

	if reflect.TypeOf(now) != f.Type() {
		return fmt.Errorf("%v must be time.Time type.", name)
	}

	if !f.CanSet() {
		return fmt.Errorf("Couldn't set time for field: %v", name)
	}

	f.Set(reflect.ValueOf(now))

	return nil
}

func hasStructField(i interface{}, field string) bool {
	t := reflect.TypeOf(i)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	if t.Kind() != reflect.Struct {
		return false
	}

	_, found := t.FieldByName(field)
	return found
}

func addId(i interface{}) error {
	v := reflect.ValueOf(i)

	if v.Kind() == reflect.Ptr {
		v = v.Elem()
	}

	if v.Kind() != reflect.Struct {
		return errors.New("Record must be a struct")
	}

	f := v.FieldByName("Id")
	if f.Kind() == reflect.Ptr {
		f = f.Elem()
	}

	if f.Kind() == reflect.String {
		if !f.Interface().(bson.ObjectId).Valid() {
			id := reflect.ValueOf(bson.NewObjectId())
			f.Set(id)
		}
	}

	return nil
}
<|endoftext|>