<commit_before>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package module

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

	"github.com/pkg/errors"
)

// moduleType enum defines whether a ModuleClass is a singleton or contains
// multiple directories with multiple configurations
type classType int

const (
	// SingleModule defines a module class type that has 1 directory
	SingleModule classType = iota
	// MultiModule defines a module class type with multiple nested directories
	MultiModule classType = iota
)

const configSuffix = "-config.json"

// NewSystem returns a new module system
func NewSystem() *System {
	return &System{
		classes:    map[string]*Class{},
		classOrder: []string{},
	}
}

// System defines the module classes and their type generators
type System struct {
	classes    map[string]*Class
	classOrder []string
}

// RegisterClass defines a class of module in the module system
// For example, an "Endpoint" class or a "Client" class
func (moduleSystem *System) RegisterClass(name string, class Class) error {
	if name == "" {
		return errors.Errorf("A module class name must not be empty")
	}

	if moduleSystem.classes[name] != nil {
		return errors.Errorf(
			"The module class %s is already defined",
			name,
		)
	}

	// Validate the module class dependencies
	// (this validation ensures that circular deps cannot exist)
	for _, moduleType := range class.ClassDependencies {
		if moduleSystem.classes[moduleType] == nil {
			return errors.Errorf(
				"The module class %s depends on class type %s,"+
					"which is not yet defined",
				name,
				moduleType,
			)
		}
	}

	class.Directory = filepath.Clean(class.Directory)

	if strings.HasPrefix(class.Directory, "..") {
		return errors.Errorf(
			"The module class %s must map to an internal directory but was %s",
			name,
			class.Directory,
		)
	}

	// Validate the module class directory name is unique
	for moduleClassName, moduleClass := range moduleSystem.classes {
		if class.Directory == moduleClass.Directory {
			return errors.Errorf(
				"The module class %s conflicts with directory %s from class %s",
				name,
				class.Directory,
				moduleClassName,
			)
		}
	}

	class.types = map[string]BuildGenerator{}
	moduleSystem.classes[name] = &class
	moduleSystem.classOrder = append(moduleSystem.classOrder, name)

	return nil
}

// RegisterClassType registers a type generator for a specific module class
// For example, the "http"" type generator for the "Endpoint"" class
func (moduleSystem *System) RegisterClassType(
	className string,
	classType string,
	generator BuildGenerator,
) error {
	moduleClass := moduleSystem.classes[className]

	if moduleClass == nil {
		return errors.Errorf(
			"Cannot set class type %s for undefined class %s",
			classType,
			className,
		)
	}

	if moduleClass.types[classType] != nil {
		return errors.Errorf(
			"The class type %s is already defined for class %s",
			classType,
			className,
		)
	}

	moduleClass.types[classType] = generator

	return nil
}

// ResolveModules resolves the module instances from the config on disk
// Using the system class and type definitions, the class directories are
// walked, and a module instance is initialized for each identified module in
// the target directory.
func (moduleSystem *System) ResolveModules(
	baseDirectory string,
) (map[string][]*Instance, error) {

	resolvedModules := map[string][]*Instance{}

	for _, className := range moduleSystem.classOrder {
		class := moduleSystem.classes[className]
		fullInstanceDirectory := filepath.Join(baseDirectory, class.Directory)

		classInstances := []*Instance{}

		if class.ClassType == SingleModule {
			instance, instanceErr := readInstance(
				className,
				baseDirectory,
				class.Directory,
			)
			if instanceErr != nil {
				return nil, errors.Wrapf(
					instanceErr,
					"Error reading single instance %s in %s",
					className,
					class.Directory,
				)
			}
			classInstances = append(classInstances, instance)
		} else {

			files, err := ioutil.ReadDir(fullInstanceDirectory)

			if err != nil {
				// TODO: We should accumulate errors and list them all here
				// Expected $path to be a class directory
				return nil, errors.Wrapf(
					err,
					"Error reading module instance directory %s",
					fullInstanceDirectory,
				)
			}

			for _, file := range files {
				if file.IsDir() {
					instance, instanceErr := readInstance(
						className,
						baseDirectory,
						filepath.Join(class.Directory, file.Name()),
					)
					if instanceErr != nil {
						return nil, errors.Wrapf(
							instanceErr,
							"Error reading multi instance %s in %s",
							className,
							filepath.Join(class.Directory, file.Name()),
						)
					}
					classInstances = append(classInstances, instance)
				}
			}
		}

		resolvedModules[className] = classInstances
	}

	return resolvedModules, nil
}

func readInstance(
	className string,
	baseDirectory string,
	instanceDirectory string,
) (*Instance, error) {

	jsonFileName := className + configSuffix
	classConfigPath := filepath.Join(
		baseDirectory,
		instanceDirectory,
		jsonFileName,
	)

	jsonConfig := JSONClassConfig{}
	raw, err := jsonConfig.Read(classConfigPath)

	if err != nil {
		// TODO: We should accumulate errors and list them all here
		// Expected $class-config.json to exist in ...
		return nil, errors.Wrapf(
			err,
			"Error reading JSON Config %s",
			classConfigPath,
		)
	}

	return &Instance{
		ClassName:     className,
		ClassType:     jsonConfig.Type,
		BaseDirectory: baseDirectory,
		Directory:     instanceDirectory,
		InstanceName:  jsonConfig.Name,
		Dependencies:  readDeps(jsonConfig.Dependencies),
		JSONFileName:  jsonFileName,
		JSONFileRaw:   raw,
	}, nil
}

func readDeps(jsonDeps map[string][]string) []Dependency {
	depCount := 0

	for _, depsList := range jsonDeps {
		depCount += len(depsList)
	}

	deps := make([]Dependency, depCount)
	depIndex := 0

	for className, depsList := range jsonDeps {
		for _, instanceName := range depsList {
			deps[depIndex] = Dependency{
				ClassName:    className,
				InstanceName: instanceName,
			}
			depIndex++
		}
	}

	return deps
}

// GenerateBuild will, given a module system configuration directory and a
// target build directory, run the generators assigned to each type of module
// and write the generated output to the module build directory
func (moduleSystem *System) GenerateBuild(
	baseDirectory string,
	targetGenDir string,
) error {
	resolvedModules, err := moduleSystem.ResolveModules(baseDirectory)

	if err != nil {
		return err
	}

	moduleCount := 0
	for _, moduleList := range resolvedModules {
		moduleCount += len(moduleList)
	}

	moduleIndex := 0
	for _, className := range moduleSystem.classOrder {
		classInstances := resolvedModules[className]

		for _, classInstance := range classInstances {
			moduleIndex++
			buildPath := filepath.Join(
				targetGenDir,
				classInstance.Directory,
			)
			fmt.Printf(
				"Generating %s %s %s in %s %d/%d\n",
				classInstance.ClassType,
				classInstance.ClassName,
				classInstance.InstanceName,
				buildPath,
				moduleIndex,
				moduleCount,
			)

			classGenerators := moduleSystem.classes[classInstance.ClassName]
			generator := classGenerators.types[classInstance.ClassType]

			if generator == nil {
				fmt.Printf(
					"Skipping generation of %s %s class of type %s"+
						"as generator is not defined\n",
					classInstance.InstanceName,
					classInstance.ClassName,
					classInstance.ClassType,
				)
				continue
			}

			files, err := generator.Generate(classInstance)

			if err != nil {
				fmt.Printf(
					"Error generating %s %s class of type %s"+
						"as generator is not defined\n%s\n",
					classInstance.InstanceName,
					classInstance.ClassName,
					classInstance.ClassType,
					err.Error(),
				)
				return err
			}

			for filePath, content := range files {
				filePath = filepath.Clean(filePath)

				if strings.HasPrefix(filePath, "..") {
					return errors.Errorf(
						"Module %s generated a file outside the build dir %s",
						classInstance.Directory,
						filePath,
					)
				}

				resolvedPath := filepath.Join(
					buildPath,
					filePath,
				)

				if err := writeFile(resolvedPath, content); err != nil {
					return errors.Wrapf(
						err,
						"Error writing to file %s",
						resolvedPath,
					)
				}

				// HACK: The module system writer shouldn't
				// assume that we want to format the files in
				// this way, but we don't have these formatters
				// as a library or a custom post build script
				// for the generators yet.
				if filepath.Ext(filePath) == ".go" {
					if err := formatGoFile(resolvedPath); err != nil {
						return err
					}
				}
			}
		}
	}

	print("\nDone.\n")
	return nil
}

func formatGoFile(filePath string) error {
	gofmtCmd := exec.Command("gofmt", "-s", "-w", "-e", filePath)
	gofmtCmd.Stdout = os.Stdout
	gofmtCmd.Stderr = os.Stderr

	if err := gofmtCmd.Run(); err != nil {
		return errors.Wrapf(err, "failed to gofmt file: %s", filePath)
	}

	goimportsCmd := exec.Command("goimports", "-w", "-e", filePath)
	goimportsCmd.Stdout = os.Stdout
	goimportsCmd.Stderr = os.Stderr

	if err := goimportsCmd.Run(); err != nil {
		return errors.Wrapf(err, "failed to goimports file: %s", filePath)
	}

	return nil
}

// Class defines a module class in the build configuration directory. This
// coud be something like an Endpoint class which contains multiple endpoint
// configurations, or a Lib class, that is itself a module instance
type Class struct {
	ClassType         classType
	Directory         string
	ClassDependencies []string
	types             map[string]BuildGenerator
}

// BuildGenerator provides a function to generate a module instance build
// artifact from its configuration as part of a build step. For example, an
// Endpoint module instance may generate endpoint handler code
type BuildGenerator interface {
	Generate(
		instance *Instance,
	) (map[string][]byte, error)
}

// Instance is a configured module on disk inside a module class directory.
// For example, this could be
//     ClassName:    "Endpoint,
//     ClassType:    "http",
//     BaseDirectory "/path/to/service/base/"
//     Directory:    "clients/health/"
//     InstanceName: "health",
type Instance struct {
	// ClassName is the name of the class as defined in the module system
	ClassName string
	// ClassType is the type of the class as defined in the module system
	ClassType string
	// BaseDirectory is the absolute path to module system system top level
	// directory
	BaseDirectory string
	// Directory is the relative instance directory
	Directory string
	// InstanceName is the name of the instance as configured in the instance's
	// json file
	InstanceName string
	// Config is a reference to the instance "config" key in the instances json
	//file
	Config interface{}
	// Dependency is a list of dependent modules as defined in the instances
	// json file
	Dependencies []Dependency
	// Resolved dependencies is a list of dependent modules after procesing
	// (fully resolved)
	ResolvedDependencies []Dependency
	// The JSONFileName is the absolute path to the instance json file
	JSONFileName string
	// JSONFileRaw is the raw JSON file read as bytes used for future parsing
	JSONFileRaw []byte
}

// Dependency defines a module instance required by another module instance
type Dependency struct {
	ClassName    string
	InstanceName string
}

// JSONClassConfig maps onto a json configuration for a class type
type JSONClassConfig struct {
	Name         string              `json:"name"`
	Config       interface{}         `json:"config"`
	Dependencies map[string][]string `json:"deps"`
	Type         string              `json:"type"`
}

// Read will read a class configuration json file into a jsonClassConfig struct
// or return an error if it cannot be unmarshaled into the struct
func (jsonConfig *JSONClassConfig) Read(
	classConfigPath string,
) ([]byte, error) {
	configFile, readErr := ioutil.ReadFile(classConfigPath)
	if readErr != nil {
		return nil, errors.Wrapf(
			readErr,
			"Error reading class config %s",
			classConfigPath,
		)
	}

	parseErr := json.Unmarshal(configFile, &jsonConfig)

	if parseErr != nil {
		return nil, errors.Wrapf(
			parseErr,
			"Error JSON parsing clss config %s",
			configFile,
		)
	}

	if jsonConfig.Name == "" {
		return nil, errors.Errorf(
			"Error reading instance name from %s",
			classConfigPath,
		)
	}

	if jsonConfig.Type == "" {
		return nil, errors.Errorf(
			"Error reading instance type from %s",
			classConfigPath,
		)
	}

	if jsonConfig.Dependencies == nil {
		jsonConfig.Dependencies = map[string][]string{}
	}

	return configFile, nil
}

func writeFile(filePath string, bytes []byte) error {
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
			return errors.Wrapf(
				err, "could not make directory: %s", filePath,
			)
		}
	}

	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
	defer closeFile(file)
	if err != nil {
		return errors.Wrapf(
			err, "Could not open file for writing: %s", filePath,
		)
	}

	n, err := file.Write(bytes)

	if err != nil {
		return errors.Wrapf(err, "Error writing to file %s", filePath)
	}

	if n != len(bytes) {
		return errors.Wrapf(
			err,
			"Error writing full contents to file: %s",
			filePath,
		)
	}

	return nil
}

func closeFile(file *os.File) {
	_ = file.Close()
}
<commit_msg>format errors with spaces<commit_after>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package module

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

	"github.com/pkg/errors"
)

// moduleType enum defines whether a ModuleClass is a singleton or contains
// multiple directories with multiple configurations
type classType int

const (
	// SingleModule defines a module class type that has 1 directory
	SingleModule classType = iota
	// MultiModule defines a module class type with multiple nested directories
	MultiModule classType = iota
)

const configSuffix = "-config.json"

// NewSystem returns a new module system
func NewSystem() *System {
	return &System{
		classes:    map[string]*Class{},
		classOrder: []string{},
	}
}

// System defines the module classes and their type generators
type System struct {
	classes    map[string]*Class
	classOrder []string
}

// RegisterClass defines a class of module in the module system
// For example, an "Endpoint" class or a "Client" class
func (moduleSystem *System) RegisterClass(name string, class Class) error {
	if name == "" {
		return errors.Errorf("A module class name must not be empty")
	}

	if moduleSystem.classes[name] != nil {
		return errors.Errorf(
			"The module class %s is already defined",
			name,
		)
	}

	// Validate the module class dependencies
	// (this validation ensures that circular deps cannot exist)
	for _, moduleType := range class.ClassDependencies {
		if moduleSystem.classes[moduleType] == nil {
			return errors.Errorf(
				"The module class %s depends on class type %s, "+
					"which is not yet defined",
				name,
				moduleType,
			)
		}
	}

	class.Directory = filepath.Clean(class.Directory)

	if strings.HasPrefix(class.Directory, "..") {
		return errors.Errorf(
			"The module class %s must map to an internal directory but was %s",
			name,
			class.Directory,
		)
	}

	// Validate the module class directory name is unique
	for moduleClassName, moduleClass := range moduleSystem.classes {
		if class.Directory == moduleClass.Directory {
			return errors.Errorf(
				"The module class %s conflicts with directory %s from class %s",
				name,
				class.Directory,
				moduleClassName,
			)
		}
	}

	class.types = map[string]BuildGenerator{}
	moduleSystem.classes[name] = &class
	moduleSystem.classOrder = append(moduleSystem.classOrder, name)

	return nil
}

// RegisterClassType registers a type generator for a specific module class
// For example, the "http"" type generator for the "Endpoint"" class
func (moduleSystem *System) RegisterClassType(
	className string,
	classType string,
	generator BuildGenerator,
) error {
	moduleClass := moduleSystem.classes[className]

	if moduleClass == nil {
		return errors.Errorf(
			"Cannot set class type %s for undefined class %s",
			classType,
			className,
		)
	}

	if moduleClass.types[classType] != nil {
		return errors.Errorf(
			"The class type %s is already defined for class %s",
			classType,
			className,
		)
	}

	moduleClass.types[classType] = generator

	return nil
}

// ResolveModules resolves the module instances from the config on disk
// Using the system class and type definitions, the class directories are
// walked, and a module instance is initialized for each identified module in
// the target directory.
func (moduleSystem *System) ResolveModules(
	baseDirectory string,
) (map[string][]*Instance, error) {

	resolvedModules := map[string][]*Instance{}

	for _, className := range moduleSystem.classOrder {
		class := moduleSystem.classes[className]
		fullInstanceDirectory := filepath.Join(baseDirectory, class.Directory)

		classInstances := []*Instance{}

		if class.ClassType == SingleModule {
			instance, instanceErr := readInstance(
				className,
				baseDirectory,
				class.Directory,
			)
			if instanceErr != nil {
				return nil, errors.Wrapf(
					instanceErr,
					"Error reading single instance %s in %s",
					className,
					class.Directory,
				)
			}
			classInstances = append(classInstances, instance)
		} else {

			files, err := ioutil.ReadDir(fullInstanceDirectory)

			if err != nil {
				// TODO: We should accumulate errors and list them all here
				// Expected $path to be a class directory
				return nil, errors.Wrapf(
					err,
					"Error reading module instance directory %s",
					fullInstanceDirectory,
				)
			}

			for _, file := range files {
				if file.IsDir() {
					instance, instanceErr := readInstance(
						className,
						baseDirectory,
						filepath.Join(class.Directory, file.Name()),
					)
					if instanceErr != nil {
						return nil, errors.Wrapf(
							instanceErr,
							"Error reading multi instance %s in %s",
							className,
							filepath.Join(class.Directory, file.Name()),
						)
					}
					classInstances = append(classInstances, instance)
				}
			}
		}

		resolvedModules[className] = classInstances
	}

	return resolvedModules, nil
}

func readInstance(
	className string,
	baseDirectory string,
	instanceDirectory string,
) (*Instance, error) {

	jsonFileName := className + configSuffix
	classConfigPath := filepath.Join(
		baseDirectory,
		instanceDirectory,
		jsonFileName,
	)

	jsonConfig := JSONClassConfig{}
	raw, err := jsonConfig.Read(classConfigPath)

	if err != nil {
		// TODO: We should accumulate errors and list them all here
		// Expected $class-config.json to exist in ...
		return nil, errors.Wrapf(
			err,
			"Error reading JSON Config %s",
			classConfigPath,
		)
	}

	return &Instance{
		ClassName:     className,
		ClassType:     jsonConfig.Type,
		BaseDirectory: baseDirectory,
		Directory:     instanceDirectory,
		InstanceName:  jsonConfig.Name,
		Dependencies:  readDeps(jsonConfig.Dependencies),
		JSONFileName:  jsonFileName,
		JSONFileRaw:   raw,
	}, nil
}

func readDeps(jsonDeps map[string][]string) []Dependency {
	depCount := 0

	for _, depsList := range jsonDeps {
		depCount += len(depsList)
	}

	deps := make([]Dependency, depCount)
	depIndex := 0

	for className, depsList := range jsonDeps {
		for _, instanceName := range depsList {
			deps[depIndex] = Dependency{
				ClassName:    className,
				InstanceName: instanceName,
			}
			depIndex++
		}
	}

	return deps
}

// GenerateBuild will, given a module system configuration directory and a
// target build directory, run the generators assigned to each type of module
// and write the generated output to the module build directory
func (moduleSystem *System) GenerateBuild(
	baseDirectory string,
	targetGenDir string,
) error {
	resolvedModules, err := moduleSystem.ResolveModules(baseDirectory)

	if err != nil {
		return err
	}

	moduleCount := 0
	for _, moduleList := range resolvedModules {
		moduleCount += len(moduleList)
	}

	moduleIndex := 0
	for _, className := range moduleSystem.classOrder {
		classInstances := resolvedModules[className]

		for _, classInstance := range classInstances {
			moduleIndex++
			buildPath := filepath.Join(
				targetGenDir,
				classInstance.Directory,
			)
			fmt.Printf(
				"Generating %s %s %s in %s %d/%d\n",
				classInstance.ClassType,
				classInstance.ClassName,
				classInstance.InstanceName,
				buildPath,
				moduleIndex,
				moduleCount,
			)

			classGenerators := moduleSystem.classes[classInstance.ClassName]
			generator := classGenerators.types[classInstance.ClassType]

			if generator == nil {
				fmt.Printf(
					"Skipping generation of %s %s class of type %s "+
						"as generator is not defined\n",
					classInstance.InstanceName,
					classInstance.ClassName,
					classInstance.ClassType,
				)
				continue
			}

			files, err := generator.Generate(classInstance)

			if err != nil {
				fmt.Printf(
					"Error generating %s %s class of type %s "+
						"as generator is not defined\n%s\n",
					classInstance.InstanceName,
					classInstance.ClassName,
					classInstance.ClassType,
					err.Error(),
				)
				return err
			}

			for filePath, content := range files {
				filePath = filepath.Clean(filePath)

				if strings.HasPrefix(filePath, "..") {
					return errors.Errorf(
						"Module %s generated a file outside the build dir %s",
						classInstance.Directory,
						filePath,
					)
				}

				resolvedPath := filepath.Join(
					buildPath,
					filePath,
				)

				if err := writeFile(resolvedPath, content); err != nil {
					return errors.Wrapf(
						err,
						"Error writing to file %s",
						resolvedPath,
					)
				}

				// HACK: The module system writer shouldn't
				// assume that we want to format the files in
				// this way, but we don't have these formatters
				// as a library or a custom post build script
				// for the generators yet.
				if filepath.Ext(filePath) == ".go" {
					if err := formatGoFile(resolvedPath); err != nil {
						return err
					}
				}
			}
		}
	}

	print("\nDone.\n")
	return nil
}

func formatGoFile(filePath string) error {
	gofmtCmd := exec.Command("gofmt", "-s", "-w", "-e", filePath)
	gofmtCmd.Stdout = os.Stdout
	gofmtCmd.Stderr = os.Stderr

	if err := gofmtCmd.Run(); err != nil {
		return errors.Wrapf(err, "failed to gofmt file: %s", filePath)
	}

	goimportsCmd := exec.Command("goimports", "-w", "-e", filePath)
	goimportsCmd.Stdout = os.Stdout
	goimportsCmd.Stderr = os.Stderr

	if err := goimportsCmd.Run(); err != nil {
		return errors.Wrapf(err, "failed to goimports file: %s", filePath)
	}

	return nil
}

// Class defines a module class in the build configuration directory. This
// coud be something like an Endpoint class which contains multiple endpoint
// configurations, or a Lib class, that is itself a module instance
type Class struct {
	ClassType         classType
	Directory         string
	ClassDependencies []string
	types             map[string]BuildGenerator
}

// BuildGenerator provides a function to generate a module instance build
// artifact from its configuration as part of a build step. For example, an
// Endpoint module instance may generate endpoint handler code
type BuildGenerator interface {
	Generate(
		instance *Instance,
	) (map[string][]byte, error)
}

// Instance is a configured module on disk inside a module class directory.
// For example, this could be
//     ClassName:    "Endpoint,
//     ClassType:    "http",
//     BaseDirectory "/path/to/service/base/"
//     Directory:    "clients/health/"
//     InstanceName: "health",
type Instance struct {
	// ClassName is the name of the class as defined in the module system
	ClassName string
	// ClassType is the type of the class as defined in the module system
	ClassType string
	// BaseDirectory is the absolute path to module system system top level
	// directory
	BaseDirectory string
	// Directory is the relative instance directory
	Directory string
	// InstanceName is the name of the instance as configured in the instance's
	// json file
	InstanceName string
	// Config is a reference to the instance "config" key in the instances json
	//file
	Config interface{}
	// Dependency is a list of dependent modules as defined in the instances
	// json file
	Dependencies []Dependency
	// Resolved dependencies is a list of dependent modules after procesing
	// (fully resolved)
	ResolvedDependencies []Dependency
	// The JSONFileName is the absolute path to the instance json file
	JSONFileName string
	// JSONFileRaw is the raw JSON file read as bytes used for future parsing
	JSONFileRaw []byte
}

// Dependency defines a module instance required by another module instance
type Dependency struct {
	ClassName    string
	InstanceName string
}

// JSONClassConfig maps onto a json configuration for a class type
type JSONClassConfig struct {
	Name         string              `json:"name"`
	Config       interface{}         `json:"config"`
	Dependencies map[string][]string `json:"deps"`
	Type         string              `json:"type"`
}

// Read will read a class configuration json file into a jsonClassConfig struct
// or return an error if it cannot be unmarshaled into the struct
func (jsonConfig *JSONClassConfig) Read(
	classConfigPath string,
) ([]byte, error) {
	configFile, readErr := ioutil.ReadFile(classConfigPath)
	if readErr != nil {
		return nil, errors.Wrapf(
			readErr,
			"Error reading class config %s",
			classConfigPath,
		)
	}

	parseErr := json.Unmarshal(configFile, &jsonConfig)

	if parseErr != nil {
		return nil, errors.Wrapf(
			parseErr,
			"Error JSON parsing clss config %s",
			configFile,
		)
	}

	if jsonConfig.Name == "" {
		return nil, errors.Errorf(
			"Error reading instance name from %s",
			classConfigPath,
		)
	}

	if jsonConfig.Type == "" {
		return nil, errors.Errorf(
			"Error reading instance type from %s",
			classConfigPath,
		)
	}

	if jsonConfig.Dependencies == nil {
		jsonConfig.Dependencies = map[string][]string{}
	}

	return configFile, nil
}

func writeFile(filePath string, bytes []byte) error {
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
			return errors.Wrapf(
				err, "could not make directory: %s", filePath,
			)
		}
	}

	file, err := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
	defer closeFile(file)
	if err != nil {
		return errors.Wrapf(
			err, "Could not open file for writing: %s", filePath,
		)
	}

	n, err := file.Write(bytes)

	if err != nil {
		return errors.Wrapf(err, "Error writing to file %s", filePath)
	}

	if n != len(bytes) {
		return errors.Wrapf(
			err,
			"Error writing full contents to file: %s",
			filePath,
		)
	}

	return nil
}

func closeFile(file *os.File) {
	_ = file.Close()
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

import(`bytes`)

var tree [1024]Position
var node int

type Flags struct {
        enpassant     int       // En-passant square caused by previous move.
        irreversible  bool      // Is this position reversible?
}

type Position struct {
        game      *Game
        flags     Flags         // Flags set by last move leading to this position.
        pieces    [64]Piece     // Array of 64 squares with pieces on them.
        board     Bitmask       // Bitmask of all pieces on the board.
        outposts  [14]Bitmask   // Bitmasks of each piece on the board; [0] all white, [1] all black.
        count     [16]int       // counts of each piece on the board, ex. white pawns: 6, etc.
        color     int           // Side to make next move.
        hash      uint64        // Polyglot hash value.
        castles   uint8         // Castle rights mask.
}

func NewPosition(game *Game, pieces [64]Piece, color int, flags Flags) *Position {
        tree[node] = Position{ game: game, pieces: pieces, color: color }
        p := &tree[node]

        p.castles = castleKingside[White] | castleQueenside[White] |
                    castleKingside[Black] | castleQueenside[Black]

        if p.pieces[E1] != King || p.pieces[H1] != Rook {
                p.castles &= ^castleKingside[White]
        }
        if p.pieces[E1] != King || p.pieces[A1] != Rook {
                p.castles &= ^castleQueenside[White]
        }

        if p.pieces[E8] != BlackKing || p.pieces[H8] != BlackRook {
                p.castles &= ^castleKingside[Black]
        }
        if p.pieces[E8] != BlackKing || p.pieces[A8] != BlackRook {
                p.castles &= ^castleQueenside[Black]
        }

        for square, piece := range p.pieces {
                if piece != 0 {
                        p.outposts[piece].set(square)
                        p.outposts[piece.color()].set(square)
                        p.count[piece]++
                }
        }

        p.hash = p.polyglot()
        p.board = p.outposts[White] | p.outposts[Black]

        return p
}

func (p *Position) movePiece(from, to int) *Position {
        piece, color := p.pieces[from], p.pieces[from].color()

        p.pieces[from], p.pieces[to] = 0, piece
        p.outposts[piece] ^= bit[from] | bit[to]
        p.outposts[color] ^= bit[from] | bit[to]

        return p
}

func (p *Position) promotePawn(from, to int, promo Piece) *Position {
        piece, color := p.pieces[from], p.pieces[from].color()

        p.pieces[from], p.pieces[to] = 0, promo
        p.outposts[piece] ^= bit[from]
        p.outposts[promo] ^= bit[to]
        p.outposts[color] ^= bit[from] | bit[to]
        p.count[piece]--
        p.count[promo]++

        return p
}

func (p *Position) capturePiece(from, to int) *Position {
        capture, enemy := p.pieces[to], p.pieces[to].color()

        p.outposts[capture] ^= bit[to]
        p.outposts[enemy] ^= bit[to]
        p.count[capture]--

        return p
}

func (p *Position) captureEnpassant(from, to int) *Position {
        color := p.pieces[from].color()
        enemy := color^1
        capture := pawn(enemy)
        enpassant := to - eight[color]

        p.pieces[enpassant] = 0
        p.outposts[capture] ^= bit[enpassant]
        p.outposts[enemy] ^= bit[enpassant]
        p.count[capture]--

        return p
}

func (p *Position) MakeMove(move Move) *Position {
        color := move.color()
        flags := Flags{}

        from, to, piece, capture := move.split()
        //
        // Copy over the contents of previous tree node to the current one.
        //
        node++
        tree[node] = tree[node - 1] // Faster that tree[node] = *p ?!

        hash := tree[node].hash ^ hashCastle[tree[node].castles]
        if tree[node].flags.enpassant != 0 {
                hash ^= hashEnpassant[Col(tree[node].flags.enpassant)]
        }
        //
        // Castle rights for current node are based on the castle rights from
        // the previous node.
        //
        tree[node].castles &= castleRights[from] & castleRights[to]
        hash ^= hashCastle[tree[node].castles]

        if capture != 0 {
                flags.irreversible = true
                if to != 0 && to == tree[node].flags.enpassant {
                        hash ^= polyglotRandom[64 * pawn(color^1).polyglot() + to - eight[color]]
                        tree[node].captureEnpassant(from, to)
                } else {
                        hash ^= polyglotRandom[64 * p.pieces[to].polyglot() + to]
                        tree[node].capturePiece(from, to)
                }
        }

        if promo := move.promo(); promo == 0 {
                poly := 64 * p.pieces[from].polyglot()
                hash ^= polyglotRandom[poly + from] ^ polyglotRandom[poly + to]
                tree[node].movePiece(from, to)
                if move.isCastle() {
                        flags.irreversible = true
                        switch to {
                        case G1:
                                poly = 64 * Piece(Rook).polyglot()
                                hash ^= polyglotRandom[poly + H1] ^ polyglotRandom[poly + F1]
                                tree[node].movePiece(H1, F1)
                        case C1:
                                poly = 64 * Piece(Rook).polyglot()
                                hash ^= polyglotRandom[poly + A1] ^ polyglotRandom[poly + D1]
                                tree[node].movePiece(A1, D1)
                        case G8:
                                poly = 64 * Piece(BlackRook).polyglot()
                                hash ^= polyglotRandom[poly + H8] ^ polyglotRandom[poly + F8]
                                tree[node].movePiece(H8, F8)
                        case C8:
                                poly = 64 * Piece(BlackRook).polyglot()
                                hash ^= polyglotRandom[poly + A8] ^ polyglotRandom[poly + D8]
                                tree[node].movePiece(A8, D8)
                        }
                } else if piece.isPawn() {
                        flags.irreversible = true
                        if move.isEnpassant() {
                                flags.enpassant = from + eight[color] // Save the en-passant square.
                                hash ^= hashEnpassant[Col(flags.enpassant)]
                        }
                }
        } else {
                flags.irreversible = true
                hash ^= polyglotRandom[64 * pawn(color).polyglot() + from]
                hash ^= polyglotRandom[64 * promo.polyglot() + to]
                tree[node].promotePawn(from, to, promo)
        }

	if color == White {
                hash ^= polyglotRandomWhite
	}

	tree[node].color = color^1
	tree[node].flags = flags
	tree[node].hash = hash
	tree[node].board = tree[node].outposts[White] | tree[node].outposts[Black]

	if tree[node].isInCheck(color) {
		node--
		return nil
	}
	return &tree[node]

}

func (p *Position) TakeBack(move Move) *Position {
        node--
        return &tree[node]
}

func (p *Position) isInCheck(color int) bool {
        return p.isAttacked(p.outposts[king(color)].first(), color^1)
}

func (p *Position) isRepetition() bool {
        if p.flags.irreversible {
                return false
        }

        for reps, prevNode := 1, node - 1; prevNode >= 0; prevNode-- {
                if tree[prevNode].flags.irreversible {
                        return false
                }
                if tree[prevNode].color == p.color && tree[prevNode].hash == p.hash {
                        reps++
                        if reps == 3 {
                                return true
                        }
                }
        }

        return false
}

func (p *Position) saveBest(ply int, move Move) {
        p.game.bestLine[ply][ply] = move
        p.game.bestLength[ply] = ply + 1
        for i := ply + 1; i < p.game.bestLength[ply + 1]; i++ {
                p.game.bestLine[ply][i] = p.game.bestLine[ply + 1][i]
                p.game.bestLength[ply]++
        }
}

func (p *Position) canCastle(color int) (kingside, queenside bool) {
        attacks := p.attacks(color^1)
        kingside = p.castles & castleKingside[color] != 0 &&
                   (gapKing[color] & p.board == 0) &&
                   (castleKing[color] & attacks == 0)

        queenside = p.castles & castleQueenside[color] != 0 &&
                    (gapQueen[color] & p.board == 0) &&
                    (castleQueen[color] & attacks == 0)
        return
}

// Calculates position stage based on what pieces are on the board (256 for
// the initial position, 0 for bare kings).
func (p *Position) stage() int {
        return 2 * (p.count[Pawn]   + p.count[BlackPawn])   +
               6 * (p.count[Knight] + p.count[BlackKnight]) +
              12 * (p.count[Bishop] + p.count[BlackBishop]) +
              16 * (p.count[Rook]   + p.count[BlackRook])   +
              44 * (p.count[Queen]  + p.count[BlackQueen])
}

// Calculates normalized position score based on position stage and given
// midgame/endgame values.
func (p *Position) score(midgame, endgame int) int {
        stage := p.stage()
        return (midgame * stage + endgame * (256 - stage)) / 256
}

// Compute position's polyglot hash.
func (p *Position) polyglot() (key uint64) {
        board := p.board
        for board != 0 {
                square := board.pop() // Inline polyhash() is at lest 10% faster.
                key ^= polyglotRandom[64 * p.pieces[square].polyglot() + square]
        }

	key ^= hashCastle[p.castles]

	if p.flags.enpassant != 0 {
                key ^= hashEnpassant[Col(p.flags.enpassant)]
	}
	if p.color == White {
                key ^= polyglotRandomWhite
	}

	return
}

func (p *Position) polyhash (square int) uint64 {
       return polyglotRandom[64 * p.pieces[square].polyglot() + square]
}

func (p *Position) String() string {
	buffer := bytes.NewBufferString("  a b c d e f g h")
        if !p.isInCheck(p.color) {
                buffer.WriteString("\n")
        } else {
                buffer.WriteString("  Check to " + C(p.color) + "\n")
        }
	for row := 7;  row >= 0;  row-- {
		buffer.WriteByte('1' + byte(row))
		for col := 0;  col <= 7; col++ {
			square := Square(row, col)
			buffer.WriteByte(' ')
			if piece := p.pieces[square]; piece != 0 {
				buffer.WriteString(piece.String())
			} else {
				buffer.WriteString("\u22C5")
			}
		}
		buffer.WriteByte('\n')
	}
	return buffer.String()
}
<commit_msg>Slight optimization<commit_after>// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

import(`bytes`)

var tree [1024]Position
var node int

type Flags struct {
        enpassant     int       // En-passant square caused by previous move.
        irreversible  bool      // Is this position reversible?
}

type Position struct {
        game      *Game
        flags     Flags         // Flags set by last move leading to this position.
        pieces    [64]Piece     // Array of 64 squares with pieces on them.
        board     Bitmask       // Bitmask of all pieces on the board.
        outposts  [14]Bitmask   // Bitmasks of each piece on the board; [0] all white, [1] all black.
        count     [16]int       // counts of each piece on the board, ex. white pawns: 6, etc.
        color     int           // Side to make next move.
        hash      uint64        // Polyglot hash value.
        castles   uint8         // Castle rights mask.
}

func NewPosition(game *Game, pieces [64]Piece, color int, flags Flags) *Position {
        tree[node] = Position{ game: game, pieces: pieces, color: color }
        p := &tree[node]

        p.castles = castleKingside[White] | castleQueenside[White] |
                    castleKingside[Black] | castleQueenside[Black]

        if p.pieces[E1] != King || p.pieces[H1] != Rook {
                p.castles &= ^castleKingside[White]
        }
        if p.pieces[E1] != King || p.pieces[A1] != Rook {
                p.castles &= ^castleQueenside[White]
        }

        if p.pieces[E8] != BlackKing || p.pieces[H8] != BlackRook {
                p.castles &= ^castleKingside[Black]
        }
        if p.pieces[E8] != BlackKing || p.pieces[A8] != BlackRook {
                p.castles &= ^castleQueenside[Black]
        }

        for square, piece := range p.pieces {
                if piece != 0 {
                        p.outposts[piece].set(square)
                        p.outposts[piece.color()].set(square)
                        p.count[piece]++
                }
        }

        p.hash = p.polyglot()
        p.board = p.outposts[White] | p.outposts[Black]

        return p
}

func (p *Position) movePiece(from, to int) *Position {
        piece, color := p.pieces[from], p.pieces[from].color()

        p.pieces[from], p.pieces[to] = 0, piece
        p.outposts[piece] ^= bit[from] | bit[to]
        p.outposts[color] ^= bit[from] | bit[to]

        return p
}

func (p *Position) promotePawn(from, to int, promo Piece) *Position {
        piece, color := p.pieces[from], p.pieces[from].color()

        p.pieces[from], p.pieces[to] = 0, promo
        p.outposts[piece] ^= bit[from]
        p.outposts[promo] ^= bit[to]
        p.outposts[color] ^= bit[from] | bit[to]
        p.count[piece]--
        p.count[promo]++

        return p
}

func (p *Position) capturePiece(from, to int) *Position {
        capture, enemy := p.pieces[to], p.pieces[to].color()

        p.outposts[capture] ^= bit[to]
        p.outposts[enemy] ^= bit[to]
        p.count[capture]--

        return p
}

func (p *Position) captureEnpassant(from, to int) *Position {
        color := p.pieces[from].color()
        enemy := color^1
        capture := pawn(enemy)
        enpassant := to - eight[color]

        p.pieces[enpassant] = 0
        p.outposts[capture] ^= bit[enpassant]
        p.outposts[enemy] ^= bit[enpassant]
        p.count[capture]--

        return p
}

func (p *Position) MakeMove(move Move) *Position {
        color := move.color()
        flags := Flags{}

        from, to, piece, capture := move.split()
        //
        // Copy over the contents of previous tree node to the current one.
        //
        node++
        tree[node] = *p // tree[node - 1]
        p = &tree[node]

        hash := p.hash ^ hashCastle[p.castles]
        if p.flags.enpassant != 0 {
                hash ^= hashEnpassant[Col(p.flags.enpassant)]
        }
        //
        // Castle rights for current node are based on the castle rights from
        // the previous node.
        //
        p.castles &= castleRights[from] & castleRights[to]
        hash ^= hashCastle[p.castles]

        if capture != 0 {
                flags.irreversible = true
                if to != 0 && to == p.flags.enpassant {
                        hash ^= polyglotRandom[64 * pawn(color^1).polyglot() + to - eight[color]]
                        p.captureEnpassant(from, to)
                } else {
                        hash ^= polyglotRandom[64 * tree[node - 1].pieces[to].polyglot() + to]
                        p.capturePiece(from, to)
                }
        }

        if promo := move.promo(); promo == 0 {
                poly := 64 * tree[node - 1].pieces[from].polyglot()
                hash ^= polyglotRandom[poly + from] ^ polyglotRandom[poly + to]
                p.movePiece(from, to)
                if move.isCastle() {
                        flags.irreversible = true
                        switch to {
                        case G1:
                                poly = 64 * Piece(Rook).polyglot()
                                hash ^= polyglotRandom[poly + H1] ^ polyglotRandom[poly + F1]
                                p.movePiece(H1, F1)
                        case C1:
                                poly = 64 * Piece(Rook).polyglot()
                                hash ^= polyglotRandom[poly + A1] ^ polyglotRandom[poly + D1]
                                p.movePiece(A1, D1)
                        case G8:
                                poly = 64 * Piece(BlackRook).polyglot()
                                hash ^= polyglotRandom[poly + H8] ^ polyglotRandom[poly + F8]
                                p.movePiece(H8, F8)
                        case C8:
                                poly = 64 * Piece(BlackRook).polyglot()
                                hash ^= polyglotRandom[poly + A8] ^ polyglotRandom[poly + D8]
                                p.movePiece(A8, D8)
                        }
                } else if piece.isPawn() {
                        flags.irreversible = true
                        if move.isEnpassant() {
                                flags.enpassant = from + eight[color] // Save the en-passant square.
                                hash ^= hashEnpassant[Col(flags.enpassant)]
                        }
                }
        } else {
                flags.irreversible = true
                hash ^= polyglotRandom[64 * pawn(color).polyglot() + from]
                hash ^= polyglotRandom[64 * promo.polyglot() + to]
                p.promotePawn(from, to, promo)
        }

	if color == White {
                hash ^= polyglotRandomWhite
	}

	p.color = color^1
	p.flags = flags
	p.hash = hash
	p.board = p.outposts[White] | p.outposts[Black]

	if p.isInCheck(color) {
		node--
		return nil
	}
	return p // &tree[node]

}

func (p *Position) TakeBack(move Move) *Position {
        node--
        return &tree[node]
}

func (p *Position) isInCheck(color int) bool {
        return p.isAttacked(p.outposts[king(color)].first(), color^1)
}

func (p *Position) isRepetition() bool {
        if p.flags.irreversible {
                return false
        }

        for reps, prevNode := 1, node - 1; prevNode >= 0; prevNode-- {
                if tree[prevNode].flags.irreversible {
                        return false
                }
                if tree[prevNode].color == p.color && tree[prevNode].hash == p.hash {
                        reps++
                        if reps == 3 {
                                return true
                        }
                }
        }

        return false
}

func (p *Position) saveBest(ply int, move Move) {
        p.game.bestLine[ply][ply] = move
        p.game.bestLength[ply] = ply + 1
        for i := ply + 1; i < p.game.bestLength[ply + 1]; i++ {
                p.game.bestLine[ply][i] = p.game.bestLine[ply + 1][i]
                p.game.bestLength[ply]++
        }
}

func (p *Position) canCastle(color int) (kingside, queenside bool) {
        attacks := p.attacks(color^1)
        kingside = p.castles & castleKingside[color] != 0 &&
                   (gapKing[color] & p.board == 0) &&
                   (castleKing[color] & attacks == 0)

        queenside = p.castles & castleQueenside[color] != 0 &&
                    (gapQueen[color] & p.board == 0) &&
                    (castleQueen[color] & attacks == 0)
        return
}

// Calculates position stage based on what pieces are on the board (256 for
// the initial position, 0 for bare kings).
func (p *Position) stage() int {
        return 2 * (p.count[Pawn]   + p.count[BlackPawn])   +
               6 * (p.count[Knight] + p.count[BlackKnight]) +
              12 * (p.count[Bishop] + p.count[BlackBishop]) +
              16 * (p.count[Rook]   + p.count[BlackRook])   +
              44 * (p.count[Queen]  + p.count[BlackQueen])
}

// Calculates normalized position score based on position stage and given
// midgame/endgame values.
func (p *Position) score(midgame, endgame int) int {
        stage := p.stage()
        return (midgame * stage + endgame * (256 - stage)) / 256
}

// Compute position's polyglot hash.
func (p *Position) polyglot() (key uint64) {
        board := p.board
        for board != 0 {
                square := board.pop() // Inline polyhash() is at lest 10% faster.
                key ^= polyglotRandom[64 * p.pieces[square].polyglot() + square]
        }

	key ^= hashCastle[p.castles]

	if p.flags.enpassant != 0 {
                key ^= hashEnpassant[Col(p.flags.enpassant)]
	}
	if p.color == White {
                key ^= polyglotRandomWhite
	}

	return
}

func (p *Position) polyhash (square int) uint64 {
       return polyglotRandom[64 * p.pieces[square].polyglot() + square]
}

func (p *Position) String() string {
	buffer := bytes.NewBufferString("  a b c d e f g h")
        if !p.isInCheck(p.color) {
                buffer.WriteString("\n")
        } else {
                buffer.WriteString("  Check to " + C(p.color) + "\n")
        }
	for row := 7;  row >= 0;  row-- {
		buffer.WriteByte('1' + byte(row))
		for col := 0;  col <= 7; col++ {
			square := Square(row, col)
			buffer.WriteByte(' ')
			if piece := p.pieces[square]; piece != 0 {
				buffer.WriteString(piece.String())
			} else {
				buffer.WriteString("\u22C5")
			}
		}
		buffer.WriteByte('\n')
	}
	return buffer.String()
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/lib/pq"
	"github.com/samuel/go-librato/librato"
)

func postgresQuery(db *sql.DB, qf QueryFile, queryTimeout int) ([]interface{}, error) {
	Log("postgres.query.start name=%s", qf.Name)
	_, err := db.Exec(fmt.Sprintf("set application_name TO 'pg2librato - %s'", qf.Name))
	if err != nil {
		return nil, err
	}
	_, err = db.Exec(fmt.Sprintf("set statement_timeout TO %d", queryTimeout*1000))
	if err != nil {
		return nil, err
	}
	rows, err := db.Query(qf.Sql)
	if err != nil {
		return nil, err
	}
	cols, err := rows.Columns()
	if err != nil {
		return nil, err
	}
	numCols := len(cols)
	if numCols != 3 {
		return nil, errors.New("Must return result set with exactly 3 rows")
	}
	Log("postgres.query.finish name=%s", qf.Name)
	metrics := []interface{}{}
	for rows.Next() {
		var name string
		var nullSource sql.NullString
		var source string
		var value float64
		err = rows.Scan(&name, &nullSource, &value)
		if err != nil {
			return nil, err
		}
		if nullSource.Valid {
			source = nullSource.String
		}
		Log("postgres.result name=%s source=%s value=%f", name, source, value)
		metric := librato.Metric{
			Name:   name,
			Source: source,
			Value:  value,
		}
		metrics = append(metrics, metric)
	}
	return metrics, nil
}

func postgresWorkerStart(db *sql.DB, queryTicks <-chan QueryFile, queryTimeout int, metricBatches chan<- []interface{}, stop chan bool) {
	Log("postgres.worker.start")
	for {
		select {
		case queryFile := <-queryTicks:
			metricBatch, err := postgresQuery(db, queryFile, queryTimeout)
			if err != nil {
				Error(err)
			}
			metricBatches <- metricBatch
		default:
			select {
			case <-stop:
				Log("postgres.worker.exit")
				stop <- true
				return
			default:
			}
		}
	}
}

func PostgresStart(databaseUrl string, queryTicks <-chan QueryFile, queryTimeout int, metricBatches chan<- []interface{}, stop chan bool) {
	Log("postgres.start")
	db, err := sql.Open("postgres", databaseUrl)
	if err != nil {
		Error(err)
	}

	postgresWorkerStops := make([]chan bool, PostgresWorkers)
	for w := 0; w < PostgresWorkers; w++ {
		postgresWorkerStops[w] = make(chan bool)
		go postgresWorkerStart(db, queryTicks, queryTimeout, metricBatches, postgresWorkerStops[w])
	}

	<-stop
	Log("postgres.stop")
	for w := 0; w < PostgresWorkers; w++ {
		postgresWorkerStops[w] <- true
		<-postgresWorkerStops[w]
	}
	err = db.Close()
	if err != nil {
		Error(err)
	}
	stop <- true

	Log("postgres.exit")
}
<commit_msg>Shorter name<commit_after>package main

import (
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/lib/pq"
	"github.com/samuel/go-librato/librato"
)

func postgresQuery(db *sql.DB, qf QueryFile, timeout int) ([]interface{}, error) {
	Log("postgres.query.start name=%s", qf.Name)
	_, err := db.Exec(fmt.Sprintf("set application_name TO 'pg2librato - %s'", qf.Name))
	if err != nil {
		return nil, err
	}
	_, err = db.Exec(fmt.Sprintf("set statement_timeout TO %d", timeout*1000))
	if err != nil {
		return nil, err
	}
	rows, err := db.Query(qf.Sql)
	if err != nil {
		return nil, err
	}
	cols, err := rows.Columns()
	if err != nil {
		return nil, err
	}
	numCols := len(cols)
	if numCols != 3 {
		return nil, errors.New("Must return result set with exactly 3 rows")
	}
	Log("postgres.query.finish name=%s", qf.Name)
	metrics := []interface{}{}
	for rows.Next() {
		var name string
		var nullSource sql.NullString
		var source string
		var value float64
		err = rows.Scan(&name, &nullSource, &value)
		if err != nil {
			return nil, err
		}
		if nullSource.Valid {
			source = nullSource.String
		}
		Log("postgres.result name=%s source=%s value=%f", name, source, value)
		metric := librato.Metric{
			Name:   name,
			Source: source,
			Value:  value,
		}
		metrics = append(metrics, metric)
	}
	return metrics, nil
}

func postgresWorkerStart(db *sql.DB, queryTicks <-chan QueryFile, queryTimeout int, metricBatches chan<- []interface{}, stop chan bool) {
	Log("postgres.worker.start")
	for {
		select {
		case queryFile := <-queryTicks:
			metricBatch, err := postgresQuery(db, queryFile, queryTimeout)
			if err != nil {
				Error(err)
			}
			metricBatches <- metricBatch
		default:
			select {
			case <-stop:
				Log("postgres.worker.exit")
				stop <- true
				return
			default:
			}
		}
	}
}

func PostgresStart(databaseUrl string, queryTicks <-chan QueryFile, queryTimeout int, metricBatches chan<- []interface{}, stop chan bool) {
	Log("postgres.start")
	db, err := sql.Open("postgres", databaseUrl)
	if err != nil {
		Error(err)
	}

	postgresWorkerStops := make([]chan bool, PostgresWorkers)
	for w := 0; w < PostgresWorkers; w++ {
		postgresWorkerStops[w] = make(chan bool)
		go postgresWorkerStart(db, queryTicks, queryTimeout, metricBatches, postgresWorkerStops[w])
	}

	<-stop
	Log("postgres.stop")
	for w := 0; w < PostgresWorkers; w++ {
		postgresWorkerStops[w] <- true
		<-postgresWorkerStops[w]
	}
	err = db.Close()
	if err != nil {
		Error(err)
	}
	stop <- true

	Log("postgres.exit")
}
<|endoftext|>


<commit_before>package postmark

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"path"

	"golang.org/x/net/context"
)

const (
	rootEndpoint = "https://api.postmarkapp.com"

	serverTokenHeader  = "X-Postmark-Server-Token"
	accountTokenHeader = "X-Postmark-Account-Token"
)

// Postmark defines methods to interace with the Postmark API
type Postmark interface {
	SetClient(client *http.Client) Postmark

	// Templates returns a resource root object handling template interactions with Postmark
	Templates() Templates

	// Templates returns a resource root object handling template interactions with Postmark
	Emails() Emails
}

type postmark struct {
	serverToken  string
	accountToken string
	client       *http.Client
}

// Request is an general container for requests sent with Postmark
type Request struct {
	Method  string
	Path    string
	Payload interface{}
	Target  interface{}

	// Set this to true in order to use the account-wide API token
	AccountAuth bool
}

// New returns an initialized Postmark client
func New(serverToken, accountToken string) Postmark {
	return &postmark{
		serverToken:  serverToken,
		accountToken: accountToken,
	}
}

func (p *postmark) Templates() Templates {
	return &templates{pm: p}
}

func (p *postmark) Emails() Emails {
	return &emails{pm: p}
}

func (p *postmark) Exec(ctx context.Context, req *Request) (*http.Response, error) {
	var payload io.Reader
	if req.Payload != nil {
		data, err := json.Marshal(req.Payload)
		if err != nil {
			return nil, err
		}

		payload = bytes.NewReader(data)
	}

	r, err := http.NewRequest(req.Method, path.Join(rootEndpoint, req.Path), payload)
	if err != nil {
		return nil, err
	}

	r.Header.Set("Accept", "application/json")
	r.Header.Set("Content-Type", "application/json")

	if req.AccountAuth {
		r.Header.Set(accountTokenHeader, p.accountToken)
	} else {
		r.Header.Set(serverTokenHeader, p.serverToken)
	}

	resp, err := p.httpclient().Do(r)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// for unsuccessful http status codes, unmarshal an error
	if resp.StatusCode/100 != 2 {
		pmerr := &Error{StatusCode: resp.StatusCode}
		if err := json.NewDecoder(resp.Body).Decode(pmerr); err != nil {
			return resp, err
		}
		if pmerr.IsError() {
			return resp, pmerr
		}
		return resp, fmt.Errorf("postmark call errored with status: %d", resp.StatusCode)
	}

	if req.Target != nil {
		if err := json.NewDecoder(resp.Body).Decode(req.Target); err != nil {
			return nil, err
		}
	}

	return resp, nil
}

func (p *postmark) httpclient() *http.Client {
	if p.client != nil {
		return p.client
	}
	return http.DefaultClient
}

func (p *postmark) SetClient(client *http.Client) Postmark {
	p.client = client
	return p
}

// Error defines an error from the Postmark API
type Error struct {
	ErrorCode int
	Message   string

	// the HTTP status code of the response itself
	StatusCode int `json:"-"`
}

// IsError returns whether or not the response indicated an error
func (e *Error) IsError() bool {
	return e.ErrorCode != 0
}

func (e *Error) Error() string {
	codeMeaning := "unknown"
	if meaning, ok := ErrorLookup[e.ErrorCode]; ok {
		codeMeaning = meaning
	}
	return fmt.Sprintf("postmark error %d %s: %s", e.ErrorCode, e.Message, codeMeaning)
}
<commit_msg>use explicit url building in Exec helper<commit_after>package postmark

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

	"golang.org/x/net/context"
)

const (
	apiHost = "api.postmarkapp.com"

	serverTokenHeader  = "X-Postmark-Server-Token"
	accountTokenHeader = "X-Postmark-Account-Token"
)

// Postmark defines methods to interace with the Postmark API
type Postmark interface {
	SetClient(client *http.Client) Postmark

	// Templates returns a resource root object handling template interactions with Postmark
	Templates() Templates

	// Templates returns a resource root object handling template interactions with Postmark
	Emails() Emails
}

type postmark struct {
	serverToken  string
	accountToken string

	scheme string
	host   string

	client *http.Client
}

// Request is an general container for requests sent with Postmark
type Request struct {
	Method  string
	Path    string
	Params  url.Values
	Payload interface{}
	Target  interface{}

	// Set this to true in order to use the account-wide API token
	AccountAuth bool
}

// New returns an initialized Postmark client
func New(serverToken, accountToken string) Postmark {
	return &postmark{
		serverToken:  serverToken,
		accountToken: accountToken,
		scheme:       "https",
		host:         apiHost,
	}
}

func (p *postmark) Templates() Templates {
	return &templates{pm: p}
}

func (p *postmark) Emails() Emails {
	return &emails{pm: p}
}

func (p *postmark) Exec(ctx context.Context, req *Request) (*http.Response, error) {
	var payload io.Reader
	if req.Payload != nil {
		data, err := json.Marshal(req.Payload)
		if err != nil {
			return nil, err
		}

		payload = bytes.NewReader(data)
	}

	urlBuilder := url.URL{
		Scheme:   p.scheme,
		Host:     p.host,
		Path:     req.Path,
		RawQuery: req.Params.Encode(), // returns "" if nil
	}

	r, err := http.NewRequest(req.Method, urlBuilder.String(), payload)
	if err != nil {
		return nil, err
	}

	r.Header.Set("Accept", "application/json")
	r.Header.Set("Content-Type", "application/json")

	if req.AccountAuth {
		r.Header.Set(accountTokenHeader, p.accountToken)
	} else {
		r.Header.Set(serverTokenHeader, p.serverToken)
	}

	resp, err := p.httpclient().Do(r)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	// for unsuccessful http status codes, unmarshal an error
	if resp.StatusCode/100 != 2 {
		pmerr := &Error{StatusCode: resp.StatusCode}
		if err := json.NewDecoder(resp.Body).Decode(pmerr); err != nil {
			return resp, err
		}
		if pmerr.IsError() {
			return resp, pmerr
		}
		return resp, fmt.Errorf("postmark call errored with status: %d", resp.StatusCode)
	}

	if req.Target != nil {
		if err := json.NewDecoder(resp.Body).Decode(req.Target); err != nil {
			return nil, err
		}
	}

	return resp, nil
}

func (p *postmark) httpclient() *http.Client {
	if p.client != nil {
		return p.client
	}
	return http.DefaultClient
}

func (p *postmark) SetClient(client *http.Client) Postmark {
	p.client = client
	return p
}

// Error defines an error from the Postmark API
type Error struct {
	ErrorCode int
	Message   string

	// the HTTP status code of the response itself
	StatusCode int `json:"-"`
}

// IsError returns whether or not the response indicated an error
func (e *Error) IsError() bool {
	return e.ErrorCode != 0
}

func (e *Error) Error() string {
	codeMeaning := "unknown"
	if meaning, ok := ErrorLookup[e.ErrorCode]; ok {
		codeMeaning = meaning
	}
	return fmt.Sprintf("postmark error %d %s: %s", e.ErrorCode, e.Message, codeMeaning)
}
<|endoftext|>


<commit_before>
package main

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

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type poe struct {
	Name string
	Hash string
	Version string
	Owner string
	hashType string
}

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

/*

func printAsHex(buf []byte, ct int) {
	for i := 0; i + 8 < ct; i += 8 {
 		fmt.Printf("0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
	}
}

*/

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
/*
	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}
*/
	return nil, nil
}

func  (t *SimpleChaincode) addDoc(stub shim.ChaincodeStubInterface, key string, arg string) ([]byte, error) {
	var err error
	var proof poe

	fmt.Printf("addDoc: key = %s value = %s\n", key, arg)
	_, err = stub.GetState(key)
	if err == nil {
		jsonResp := "{\"Error\":\"File already exists for key: " + key + "\"}"
		return nil, errors.New(jsonResp)
	}
	err = json.Unmarshal([]byte(arg), &proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT Unmarshal arg")
	}
	fmt.Println(proof)
	proof.Version = "1.0"
	proof.Hash = key;
	b, err := json.Marshal(proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT Marshal arg")
	}
	fmt.Printf("addDoc: arg after Marshal: %s\n", b)

	// Write the state to the ledger
	err = stub.PutState(key, b)
	if err != nil {
		return nil, err
	}
	return nil, nil
}

func  (t *SimpleChaincode) transferDoc(stub shim.ChaincodeStubInterface, key string, arg string) ([]byte, error) {
	var err error
	var proof poe

	fmt.Printf("transferDoc: key = %s newowner = %s\n", key, arg)
	value, err := stub.GetState(key)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
		return nil, errors.New(jsonResp)
	}
	err = json.Unmarshal(value, &proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT unMarshal arg")
	}
	fmt.Println(proof)
	proof.Owner = arg
	b, err := json.Marshal(proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT Marshal arg")
	}
	fmt.Printf("addDoc: arg after Marshal: %s\n", b)

	// Write the state to the ledger
	err = stub.PutState(key, b)
	if err != nil {
		return nil, err
	}
	return nil, nil
}

func  (t *SimpleChaincode) readDoc(stub shim.ChaincodeStubInterface, key string) ([]byte, error) {
	var err error

	fmt.Printf("readDoc: key = %s\n", key)
	value, err := stub.GetState(key)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
		return nil, errors.New(jsonResp)
	}
	return value, nil
}

func (t *SimpleChaincode) listDoc(stub shim.ChaincodeStubInterface) ([]byte, error) {
	//  This code was copied from the map.go chaincode
	keysIter, err := stub.RangeQueryState("", "")
	if err != nil {
		return nil, fmt.Errorf("keys operation failed. Error accessing state: %s", err)
	}
	defer keysIter.Close()
	keys := map[string]string{}
	for keysIter.HasNext() {
		key, _, iterErr := keysIter.Next()
		if iterErr != nil {
			return nil, fmt.Errorf("keys operation failed. Error accessing state: %s", err)
		}
		value, err := stub.GetState(key)
		if err != nil {
			jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		if value == nil {
			jsonResp := "{\"Error\":\"Nil amount for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		keys[key] = string(value)
	}
	jsonKeys, err := json.Marshal(keys)
	if err != nil {
		return nil, fmt.Errorf("keys operation failed. Error marshaling JSON: %s", err)
	}
	fmt.Printf("Keys operation succeeded. marshaled JSON: %s", jsonKeys)
	return jsonKeys, nil
}

func (t *SimpleChaincode) delDoc(stub shim.ChaincodeStubInterface, key string) ([]byte, error) {
	fmt.Printf("delDoc: key = %s\n", key)
	err := stub.DelState(key)
	if err != nil {
		return nil, errors.New("delDoc:Failed to delete state")
	}
	return nil, nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	switch  function {
	case "addDoc":
		if len(args) != 2 {
			return nil, errors.New("addDoc: Incorrect number of arguments. Expecting 2")
		}
		return t.addDoc(stub, args[0], args[1])
	case "delDoc":
		if len(args) != 1 {
			return nil, errors.New("delDoc: Incorrect number of arguments. Expecting 1")
		}
		return t.delDoc(stub, args[0])
	case "transferDoc":
		if len(args) != 2 {
			return nil, errors.New("transferDoc: Incorrect number of arguments. Expecting 2")
		}
		return t.transferDoc(stub, args[0], args[1])
	default:
		return nil, fmt.Errorf("Invalid Invoke function name: %s",function)
	}
	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {

	switch  function {
	case "listDoc":
		if len(args) != 0 {
			return nil, errors.New("listDoc: Incorrect number of arguments. Expecting 0")
		}
		return t.listDoc(stub)
	case "readDoc":
		if len(args) != 1 {
			return nil, errors.New("readDoc: Incorrect number of arguments. Expecting 1")
		}
		return t.readDoc(stub, args[0])
	default:
		return nil, fmt.Errorf("Invalid Query function name: %s",function)
	}
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

<commit_msg>Check fro value fromGetState instead of checking for err<commit_after>
package main

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

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

type poe struct {
	Name string
	Hash string
	Version string
	Owner string
	hashType string
}

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

/*

func printAsHex(buf []byte, ct int) {
	for i := 0; i + 8 < ct; i += 8 {
 		fmt.Printf("0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X 0x%2.2X\n", buf[i], buf[i+1], buf[i+2], buf[i+3], buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
	}
}

*/

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
/*
	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var err error

	if len(args) != 4 {
		return nil, errors.New("Incorrect number of arguments. Expecting 4")
	}

	// Initialize the chaincode
	A = args[0]
	Aval, err = strconv.Atoi(args[1])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	B = args[2]
	Bval, err = strconv.Atoi(args[3])
	if err != nil {
		return nil, errors.New("Expecting integer value for asset holding")
	}
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

	// Write the state to the ledger
	err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
	if err != nil {
		return nil, err
	}

	err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
	if err != nil {
		return nil, err
	}
*/
	return nil, nil
}

func  (t *SimpleChaincode) addDoc(stub shim.ChaincodeStubInterface, key string, arg string) ([]byte, error) {
	var err error
	var proof poe

	fmt.Printf("addDoc: key = %s value = %s\n", key, arg)
	value , err = stub.GetState(key)
	if value != nil {
		jsonResp := "{\"Error\":\"File already exists for key: " + key + "\"}"
		return nil, errors.New(jsonResp)
	}
	err = json.Unmarshal([]byte(arg), &proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT Unmarshal arg")
	}
	fmt.Println(proof)
	proof.Version = "1.0"
	proof.Hash = key;
	b, err := json.Marshal(proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT Marshal arg")
	}
	fmt.Printf("addDoc: arg after Marshal: %s\n", b)

	// Write the state to the ledger
	err = stub.PutState(key, b)
	if err != nil {
		return nil, err
	}
	return nil, nil
}

func  (t *SimpleChaincode) transferDoc(stub shim.ChaincodeStubInterface, key string, arg string) ([]byte, error) {
	var err error
	var proof poe

	fmt.Printf("transferDoc: key = %s newowner = %s\n", key, arg)
	value, err := stub.GetState(key)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
		return nil, errors.New(jsonResp)
	}
	err = json.Unmarshal(value, &proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT unMarshal arg")
	}
	fmt.Println(proof)
	proof.Owner = arg
	b, err := json.Marshal(proof)
	if err != nil {
		return nil, errors.New("addDoc: Can NOT Marshal arg")
	}
	fmt.Printf("addDoc: arg after Marshal: %s\n", b)

	// Write the state to the ledger
	err = stub.PutState(key, b)
	if err != nil {
		return nil, err
	}
	return nil, nil
}

func  (t *SimpleChaincode) readDoc(stub shim.ChaincodeStubInterface, key string) ([]byte, error) {
	var err error

	fmt.Printf("readDoc: key = %s\n", key)
	value, err := stub.GetState(key)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
		return nil, errors.New(jsonResp)
	}
	return value, nil
}

func (t *SimpleChaincode) listDoc(stub shim.ChaincodeStubInterface) ([]byte, error) {
	//  This code was copied from the map.go chaincode
	keysIter, err := stub.RangeQueryState("", "")
	if err != nil {
		return nil, fmt.Errorf("keys operation failed. Error accessing state: %s", err)
	}
	defer keysIter.Close()
	keys := map[string]string{}
	for keysIter.HasNext() {
		key, _, iterErr := keysIter.Next()
		if iterErr != nil {
			return nil, fmt.Errorf("keys operation failed. Error accessing state: %s", err)
		}
		value, err := stub.GetState(key)
		if err != nil {
			jsonResp := "{\"Error\":\"Failed to get state for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		if value == nil {
			jsonResp := "{\"Error\":\"Nil amount for " + key + "\"}"
			return nil, errors.New(jsonResp)
		}
		keys[key] = string(value)
	}
	jsonKeys, err := json.Marshal(keys)
	if err != nil {
		return nil, fmt.Errorf("keys operation failed. Error marshaling JSON: %s", err)
	}
	fmt.Printf("Keys operation succeeded. marshaled JSON: %s", jsonKeys)
	return jsonKeys, nil
}

func (t *SimpleChaincode) delDoc(stub shim.ChaincodeStubInterface, key string) ([]byte, error) {
	fmt.Printf("delDoc: key = %s\n", key)
	err := stub.DelState(key)
	if err != nil {
		return nil, errors.New("delDoc:Failed to delete state")
	}
	return nil, nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	switch  function {
	case "addDoc":
		if len(args) != 2 {
			return nil, errors.New("addDoc: Incorrect number of arguments. Expecting 2")
		}
		return t.addDoc(stub, args[0], args[1])
	case "delDoc":
		if len(args) != 1 {
			return nil, errors.New("delDoc: Incorrect number of arguments. Expecting 1")
		}
		return t.delDoc(stub, args[0])
	case "transferDoc":
		if len(args) != 2 {
			return nil, errors.New("transferDoc: Incorrect number of arguments. Expecting 2")
		}
		return t.transferDoc(stub, args[0], args[1])
	default:
		return nil, fmt.Errorf("Invalid Invoke function name: %s",function)
	}
	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {

	switch  function {
	case "listDoc":
		if len(args) != 0 {
			return nil, errors.New("listDoc: Incorrect number of arguments. Expecting 0")
		}
		return t.listDoc(stub)
	case "readDoc":
		if len(args) != 1 {
			return nil, errors.New("readDoc: Incorrect number of arguments. Expecting 1")
		}
		return t.readDoc(stub, args[0])
	default:
		return nil, fmt.Errorf("Invalid Query function name: %s",function)
	}
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

<|endoftext|>


<commit_before>package oneandone_cloudserver_api

import (
	log "github.com/Sirupsen/logrus"
)

type Server struct {
	withId
	withName
	withDescription
	Password string        `json:"first_password"`
	Status   Status        `json:"status"`
	Hardware Hardware      `json:"hardware"`
	Image    ImageInServer `json:"image"`
	withApi
}

type Hardware struct {
	Vcores            int   `json:"vcore"`
	CoresPerProcessor int   `json:"cores_per_processor"`
	Ram               int   `json:"ram"`
	Hdds              []Hdd `json:"hdds"`
}

type Hdd struct {
	withId
	Size   int  `json:"size"`
	IsMain bool `json:"is_main"`
}

type ImageInServer struct {
	withId
	withName
}

type IpInServer struct {
	withId
	withType
	Ip         string `json:"ip"`
	ReverseDns string `json:"reverse_dns"`
	FirewallId string `json:"firewall"`
}

type ServerCreateData struct {
	withName
	withDescription
	Hardware           Hardware `json:"appliance_id"`
	ApplianceId        string   `json:"password"`
	Password           string   `json:"password"`
	PowerOn            bool     `json:"power_on"`
	FirewallPolicyId   string   `json:"firewall_policy_id"`
	IpId               string   `json:"ip_id"`
	LoadBalancerId     string   `json:"load_balancer_id"`
	MonitoringPolicyId string   `json:"monitoring_policy_id"`
	PrivateNetworkId   string   `json:"private_network_id"`
}

// GET /servers
func (api *API) GetServers() []Server {
	log.Debug("requesting information about servers")
	session := api.prepareSession()
	res := []Server{}
	resp, _ := session.Get(createUrl(api, "servers"), nil, &res, nil)
	logResult(resp, 200)
	for index, _ := range res {
		res[index].api = api
	}
	return res
}

// POST /servers
func (api *API) CreateServer(configuration ServerCreateData) Server {
	log.Debug("requesting to create a new server")
	s := api.prepareSession()
	res := Server{}
	resp, _ := s.Post(createUrl(api, "servers"), configuration, &res, nil)
	logResult(resp, 200)
	res.api = api
	return res
}

// GET /servers/{id}
func (api *API) GetServer(Id string) Server {
	log.Debug("requesting to start server ", Id)
	session := api.prepareSession()
	res := Server{}
	resp, _ := session.Get(createUrl(api, "servers", Id), nil, &res, nil)
	logResult(resp, 200)
	res.api = api
	return res
}

// DELETE /servers/{id}
func (server *Server) Delete() Server {
	log.Debug("Requested to delete VM ", server.Id)
	session := server.api.prepareSession()
	res := Server{}
	resp, _ := session.Delete(createUrl(server.api, "servers", server.Id), &res, nil)
	logResult(resp, 200)
	res.api = server.api
	return res
}

// PUT /servers/{id}

// GET /servers/{id}/size

// PUT /servers/{id}/size

// GET /servers/{id}/size/hdds

// POST /servers/{id}/size/hdds

// GET /servers/{id}/size/hdds/{id}

// DELETE /servers/{id}/size/hdds/{id}

// PUT /servers/{id}/size/hdds/{id}

// GET /servers/{id}/image

// PUT /servers/{id}/image

// GET /servers/{id}/ips

// POST /servers/{id}/ips

// GET /servers/{id}/ips/{id}

// DELETE /servers/{id}/ips/{id}

// PUT /servers/{id}/ips/{id}

// GET /servers/{id}/status

// PUT /servers/{id}/status

// GET /servers/{id}/dvd

// DELETE /servers/{id}/dvd

// PUT /servers/{id}/dvd

// GET /servers/{id}/private_networks

// PUT /servers/{id}/private_networks

// GET /servers/{id}/private_networks/{id}

// DELETE /servers/{id}/private_networks/{id}

// GET /servers/{id}/snapshots

// POST /servers/{id}/snapshots

// GET /servers/{id}/snapshots/{id}

// DELETE /servers/{id}/snapshots/{id}

// PUT /servers/{id}/snapshots/{id}

// POST /servers/{server_id}/clone
func (server *Server) Clone(NewName string) Server {
	return Server{}
}
<commit_msg>fixed bugs regarding server creation and queriing<commit_after>package oneandone_cloudserver_api

import (
	log "github.com/Sirupsen/logrus"
)

type Server struct {
	withId
	withName
	withDescription
	Password string        `json:"first_password"`
	Status   Status        `json:"status"`
	Hardware Hardware      `json:"hardware"`
	Image    ImageInServer `json:"image"`
	withApi
}

type Hardware struct {
	Vcores            int   `json:"vcore"`
	CoresPerProcessor int   `json:"cores_per_processor"`
	Ram               int   `json:"ram"`
	Hdds              []Hdd `json:"hdds"`
}

type Hdd struct {
	withId
	Size   int  `json:"size"`
	IsMain bool `json:"is_main"`
}

type ImageInServer struct {
	withId
	withName
}

type IpInServer struct {
	withId
	withType
	Ip         string `json:"ip"`
	ReverseDns string `json:"reverse_dns"`
	FirewallId string `json:"firewall"`
}

type ServerCreateData struct {
	Name               string   `json:"name"`
	Description        string   `json:"description"`
	Hardware           Hardware `json:"hardware"`
	ApplianceId        string   `json:"appliance_id"`
	Password           string   `json:"password"`
	PowerOn            bool     `json:"power_on"`
	FirewallPolicyId   string   `json:"firewall_policy_id"`
	IpId               string   `json:"ip_id"`
	LoadBalancerId     string   `json:"load_balancer_id"`
	MonitoringPolicyId string   `json:"monitoring_policy_id"`
	PrivateNetworkId   string   `json:"private_network_id"`
}

// GET /servers
func (api *API) GetServers() []Server {
	log.Debug("requesting information about servers")
	session := api.prepareSession()
	res := []Server{}
	resp, _ := session.Get(createUrl(api, "servers"), nil, &res, nil)
	logResult(resp, 200)
	for index, _ := range res {
		res[index].api = api
	}
	return res
}

// POST /servers
func (api *API) CreateServer(configuration ServerCreateData) Server {
	log.Debug("requesting to create a new server")
	s := api.prepareSession()
	res := Server{}
	resp, _ := s.Post(createUrl(api, "servers"), configuration, &res, nil)
	logResult(resp, 201)
	res.api = api
	return res
}

// GET /servers/{id}
func (api *API) GetServer(Id string) Server {
	log.Debug("requesting to about server ", Id)
	session := api.prepareSession()
	res := Server{}
	resp, _ := session.Get(createUrl(api, "servers", Id), nil, &res, nil)
	logResult(resp, 200)
	res.api = api
	return res
}

// DELETE /servers/{id}
func (server *Server) Delete() Server {
	log.Debug("Requested to delete VM ", server.Id)
	session := server.api.prepareSession()
	res := Server{}
	resp, _ := session.Delete(createUrl(server.api, "servers", server.Id), &res, nil)
	logResult(resp, 200)
	res.api = server.api
	return res
}

// PUT /servers/{id}

// GET /servers/{id}/size

// PUT /servers/{id}/size

// GET /servers/{id}/size/hdds

// POST /servers/{id}/size/hdds

// GET /servers/{id}/size/hdds/{id}

// DELETE /servers/{id}/size/hdds/{id}

// PUT /servers/{id}/size/hdds/{id}

// GET /servers/{id}/image

// PUT /servers/{id}/image

// GET /servers/{id}/ips

// POST /servers/{id}/ips

// GET /servers/{id}/ips/{id}

// DELETE /servers/{id}/ips/{id}

// PUT /servers/{id}/ips/{id}

// GET /servers/{id}/status

// PUT /servers/{id}/status

// GET /servers/{id}/dvd

// DELETE /servers/{id}/dvd

// PUT /servers/{id}/dvd

// GET /servers/{id}/private_networks

// PUT /servers/{id}/private_networks

// GET /servers/{id}/private_networks/{id}

// DELETE /servers/{id}/private_networks/{id}

// GET /servers/{id}/snapshots

// POST /servers/{id}/snapshots

// GET /servers/{id}/snapshots/{id}

// DELETE /servers/{id}/snapshots/{id}

// PUT /servers/{id}/snapshots/{id}

// POST /servers/{server_id}/clone
func (server *Server) Clone(NewName string) Server {
	return Server{}
}
<|endoftext|>


<commit_before>package cfwrapper

import (
	"github.com/venicegeo/pzsvc-exec/pzsvc"
)

type Factory interface {
	GetSession() (CFSession, error)
	RefreshCachedClient() error
}

// DefaultFactory encapsulates functionality to lazily generate CFSession objects
type DefaultFactory struct {
	pzSession     *pzsvc.Session
	config        *FactoryConfig
	cachedSession CFSession
	createSession createSessionFunc
}

// NewFactory creates a new factory object for lazily creating cfclient.Client objects
func NewFactory(pzSession *pzsvc.Session, config *FactoryConfig) *DefaultFactory {
	return &DefaultFactory{
		pzSession:     pzSession,
		config:        config,
		createSession: config.createSessionFunc,
	}
}

// GetSession returns a lazily generated CFSession, verified for validity
func (f *DefaultFactory) GetSession() (CFSession, error) {
	refreshSession := false

	if f.cachedSession == nil {
		refreshSession = true
	} else if valid, err := f.cachedSession.IsValid(); err != nil {
		return nil, err
	} else if !valid {
		refreshSession = true
	}

	if refreshSession {
		err := f.RefreshCachedClient()
		if err != nil {
			return nil, err
		}
	}

	return f.cachedSession, nil
}

// RefreshCachedClient replaces the cached client with a new one based on the
// factory's stored cfclient.Config and expiration duration
func (f *DefaultFactory) RefreshCachedClient() error {
	pzsvc.LogInfo(*f.pzSession, "Regenerating Cloud Foundry Client.")

	session, err := f.createSession(f.pzSession, f.config)
	if err == nil {
		f.cachedSession = session
	}
	return err
}
<commit_msg>Debug print for nil creation function<commit_after>package cfwrapper

import (
	"fmt"

	"github.com/venicegeo/pzsvc-exec/pzsvc"
)

type Factory interface {
	GetSession() (CFSession, error)
	RefreshCachedClient() error
}

// DefaultFactory encapsulates functionality to lazily generate CFSession objects
type DefaultFactory struct {
	pzSession     *pzsvc.Session
	config        *FactoryConfig
	cachedSession CFSession
	createSession createSessionFunc
}

// NewFactory creates a new factory object for lazily creating cfclient.Client objects
func NewFactory(pzSession *pzsvc.Session, config *FactoryConfig) *DefaultFactory {
	return &DefaultFactory{
		pzSession:     pzSession,
		config:        config,
		createSession: config.createSessionFunc,
	}
}

// GetSession returns a lazily generated CFSession, verified for validity
func (f *DefaultFactory) GetSession() (CFSession, error) {
	refreshSession := false

	if f.cachedSession == nil {
		refreshSession = true
	} else if valid, err := f.cachedSession.IsValid(); err != nil {
		return nil, err
	} else if !valid {
		refreshSession = true
	}

	if refreshSession {
		err := f.RefreshCachedClient()
		if err != nil {
			return nil, err
		}
	}

	return f.cachedSession, nil
}

// RefreshCachedClient replaces the cached client with a new one based on the
// factory's stored cfclient.Config and expiration duration
func (f *DefaultFactory) RefreshCachedClient() error {
	pzsvc.LogInfo(*f.pzSession, fmt.Sprintf("Regenerating Cloud Foundry Client with create function: %v", f.createSession))

	session, err := f.createSession(f.pzSession, f.config)
	if err == nil {
		f.cachedSession = session
	}
	return err
}
<|endoftext|>


<commit_before>package Golf

import (
	"fmt"
)

// Session is an interface for session instance, a session instance contains
// data needed.
type Session interface {
	Set(key string, value interface{}) error
	Get(key string) interface{}
	Delete(key interface{}) error
	SessionID() string
}

// MemorySession is an memory based implementaion of Session.
type MemorySession struct {
	sid  string
	data map[string]interface{}
}

// Set method sets the key value pair in the session.
func (s *MemorySession) Set(key string, value interface{}) error {
	s.data[key] = value
	return nil
}

// Get method gets the value by given a key in the session.
func (s *MemorySession) Get(key string) (interface{}, error) {
	if value, ok := s.data[key]; ok {
		return value, nil
	}
	return nil, fmt.Errorf("key %q in session (id %d) not found", key, s.sid)
}

// Delete method deletes the value by given a key in the session.
func (s *MemorySession) Delete(key string) error {
	delete(s.data, key)
	return nil
}

// SessionID returns the current ID of the session.
func (s *MemorySession) SessionID() string {
	return s.sid
}
<commit_msg>[feat] Implemented memory-based session control.<commit_after>package Golf

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
)

const sessionIDLength = 64

// MemorySessionManager manages a map of sessions.
type MemorySessionManager struct {
	sessions map[string]*MemorySession
}

// NewMemorySessionManager creates a new session manager.
func NewMemorySessionManager() *MemorySessionManager {
	mgr := new(MemorySessionManager)
	mgr.sessions = make(map[string]*MemorySession)
	return mgr
}

func (mgr *MemorySessionManager) sessionID() (string, error) {
	b := make([]byte, sessionIDLength)
	n, err := rand.Read(b)
	if n != len(b) || err != nil {
		return "", fmt.Errorf("Could not successfully read from the system CSPRNG.")
	}
	return hex.EncodeToString(b), nil
}

// Session gets the session instance by indicating a session id.
func (mgr *MemorySessionManager) Session(sid string) (Session, error) {
	if s, ok := mgr.sessions[sid]; ok {
		return s, nil
	}
	return nil, fmt.Errorf("Can not retrieve session with id %s.", sid)
}

// NewSession creates and returns a new session.
func (mgr *MemorySessionManager) NewSession() (Session, error) {
	sid, err := mgr.sessionID()
	if err != nil {
		return nil, err
	}
	s := MemorySession{sid: sid, data: make(map[string]interface{})}
	mgr.sessions[sid] = &s
	return &s, nil
}

// Session is an interface for session instance, a session instance contains
// data needed.
type Session interface {
	Set(key string, value interface{}) error
	Get(key string) (interface{}, error)
	Delete(key string) error
	SessionID() string
}

// MemorySession is an memory based implementaion of Session.
type MemorySession struct {
	sid  string
	data map[string]interface{}
}

// Set method sets the key value pair in the session.
func (s *MemorySession) Set(key string, value interface{}) error {
	s.data[key] = value
	return nil
}

// Get method gets the value by given a key in the session.
func (s *MemorySession) Get(key string) (interface{}, error) {
	if value, ok := s.data[key]; ok {
		return value, nil
	}
	return nil, fmt.Errorf("key %q in session (id %d) not found", key, s.sid)
}

// Delete method deletes the value by given a key in the session.
func (s *MemorySession) Delete(key string) error {
	delete(s.data, key)
	return nil
}

// SessionID returns the current ID of the session.
func (s *MemorySession) SessionID() string {
	return s.sid
}
<|endoftext|>