<commit_before>package docker

import (
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"sync"
	"testing"
	"time"
)

// FIXME: this is no longer needed
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
const unitTestImageName string = "docker-ut"

var unitTestStoreBase string
var srv *Server

func nuke(runtime *Runtime) error {
	var wg sync.WaitGroup
	for _, container := range runtime.List() {
		wg.Add(1)
		go func(c *Container) {
			c.Kill()
			wg.Done()
		}(container)
	}
	wg.Wait()
	return os.RemoveAll(runtime.root)
}

func CopyDirectory(source, dest string) error {
	if _, err := exec.Command("cp", "-ra", source, dest).Output(); err != nil {
		return err
	}
	return nil
}

func layerArchive(tarfile string) (io.Reader, error) {
	// FIXME: need to close f somewhere
	f, err := os.Open(tarfile)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func init() {
	// Hack to run sys init during unit testing
	if SelfPath() == "/sbin/init" {
		SysInit()
		return
	}

	if usr, err := user.Current(); err != nil {
		panic(err)
	} else if usr.Uid != "0" {
		panic("docker tests needs to be run as root")
	}

	// Create a temp directory
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		panic(err)
	}
	unitTestStoreBase = root

	// Make it our Store root
	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		panic(err)
	}
	// Create the "Server"
	srv := &Server{
		runtime: runtime,
	}
	// Retrieve the Image
	if err := srv.CmdPull(os.Stdin, os.Stdout, unitTestImageName); err != nil {
		panic(err)
	}
}

func newTestRuntime() (*Runtime, error) {
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		return nil, err
	}
	if err := os.Remove(root); err != nil {
		return nil, err
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		return nil, err
	}

	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		return nil, err
	}

	return runtime, nil
}

func GetTestImage(runtime *Runtime) *Image {
	imgs, err := runtime.graph.All()
	if err != nil {
		panic(err)
	} else if len(imgs) < 1 {
		panic("GASP")
	}
	return imgs[0]
}

func TestRuntimeCreate(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)

	// Make sure we start we 0 containers
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
	}
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := runtime.Destroy(container); err != nil {
			t.Error(err)
		}
	}()

	// Make sure we can find the newly created container with List()
	if len(runtime.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime.List()))
	}

	// Make sure the container List() returns is the right one
	if runtime.List()[0].Id != container.Id {
		t.Errorf("Unexpected container %v returned by List", runtime.List()[0])
	}

	// Make sure we can get the container with Get()
	if runtime.Get(container.Id) == nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure it is the right container
	if runtime.Get(container.Id) != container {
		t.Errorf("Get() returned the wrong container")
	}

	// Make sure Exists returns it as existing
	if !runtime.Exists(container.Id) {
		t.Errorf("Exists() returned false for a newly created container")
	}
}

func TestDestroy(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	// Destroy
	if err := runtime.Destroy(container); err != nil {
		t.Error(err)
	}

	// Make sure runtime.Exists() behaves correctly
	if runtime.Exists("test_destroy") {
		t.Errorf("Exists() returned true")
	}

	// Make sure runtime.List() doesn't list the destroyed container
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 container, %v found", len(runtime.List()))
	}

	// Make sure runtime.Get() refuses to return the unexisting container
	if runtime.Get(container.Id) != nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure the container root directory does not exist anymore
	_, err = os.Stat(container.root)
	if err == nil || !os.IsNotExist(err) {
		t.Errorf("Container root directory still exists after destroy")
	}

	// Test double destroy
	if err := runtime.Destroy(container); err == nil {
		// It should have failed
		t.Errorf("Double destroy did not fail")
	}
}

func TestGet(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container1, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container1)

	container2, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container2)

	container3, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container3)

	if runtime.Get(container1.Id) != container1 {
		t.Errorf("Get(test1) returned %v while expecting %v", runtime.Get(container1.Id), container1)
	}

	if runtime.Get(container2.Id) != container2 {
		t.Errorf("Get(test2) returned %v while expecting %v", runtime.Get(container2.Id), container2)
	}

	if runtime.Get(container3.Id) != container3 {
		t.Errorf("Get(test3) returned %v while expecting %v", runtime.Get(container3.Id), container3)
	}

}

func TestRestore(t *testing.T) {

	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		t.Fatal(err)
	}
	if err := os.Remove(root); err != nil {
		t.Fatal(err)
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		t.Fatal(err)
	}

	runtime1, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}

	// Create a container with one instance of docker
	container1, err := runtime1.Create(&Config{
		Image: GetTestImage(runtime1).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime1.Destroy(container1)

	// Create a second container meant to be killed
	container2, err := runtime1.Create(&Config{
		Image:     GetTestImage(runtime1).Id,
		Cmd:       []string{"/bin/cat"},
		OpenStdin: true,
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime1.Destroy(container2)

	// Start the container non blocking
	if err := container2.Start(); err != nil {
		t.Fatal(err)
	}

	if !container2.State.Running {
		t.Fatalf("Container %v should appear as running but isn't", container2.Id)
	}

	// Simulate a crash/manual quit of dockerd: process dies, states stays 'Running'
	cStdin, _ := container2.StdinPipe()
	cStdin.Close()
	if err := container2.WaitTimeout(time.Second); err != nil {
		t.Fatal(err)
	}
	container2.State.Running = true
	container2.ToDisk()

	if len(runtime1.List()) != 2 {
		t.Errorf("Expected 2 container, %v found", len(runtime1.List()))
	}
	if err := container1.Run(); err != nil {
		t.Fatal(err)
	}

	if !container2.State.Running {
		t.Fatalf("Container %v should appear as running but isn't", container2.Id)
	}

	// Here are are simulating a docker restart - that is, reloading all containers
	// from scratch
	runtime2, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime2)
	if len(runtime2.List()) != 2 {
		t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
	}
	runningCount := 0
	for _, c := range runtime2.List() {
		if c.State.Running {
			t.Errorf("Running container found: %v (%v)", c.Id, c.Path)
			runningCount++
		}
	}
	if runningCount != 0 {
		t.Fatalf("Expected 0 container alive, %d found", runningCount)
	}
	container3 := runtime2.Get(container1.Id)
	if container3 == nil {
		t.Fatal("Unable to Get container")
	}
	if err := container3.Run(); err != nil {
		t.Fatal(err)
	}
}
<commit_msg>Increase the timeout of TestRestore() to avoid unwanted timeout error<commit_after>package docker

import (
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"sync"
	"testing"
	"time"
)

// FIXME: this is no longer needed
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
const unitTestImageName string = "docker-ut"

var unitTestStoreBase string
var srv *Server

func nuke(runtime *Runtime) error {
	var wg sync.WaitGroup
	for _, container := range runtime.List() {
		wg.Add(1)
		go func(c *Container) {
			c.Kill()
			wg.Done()
		}(container)
	}
	wg.Wait()
	return os.RemoveAll(runtime.root)
}

func CopyDirectory(source, dest string) error {
	if _, err := exec.Command("cp", "-ra", source, dest).Output(); err != nil {
		return err
	}
	return nil
}

func layerArchive(tarfile string) (io.Reader, error) {
	// FIXME: need to close f somewhere
	f, err := os.Open(tarfile)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func init() {
	// Hack to run sys init during unit testing
	if SelfPath() == "/sbin/init" {
		SysInit()
		return
	}

	if usr, err := user.Current(); err != nil {
		panic(err)
	} else if usr.Uid != "0" {
		panic("docker tests needs to be run as root")
	}

	// Create a temp directory
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		panic(err)
	}
	unitTestStoreBase = root

	// Make it our Store root
	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		panic(err)
	}
	// Create the "Server"
	srv := &Server{
		runtime: runtime,
	}
	// Retrieve the Image
	if err := srv.CmdPull(os.Stdin, os.Stdout, unitTestImageName); err != nil {
		panic(err)
	}
}

func newTestRuntime() (*Runtime, error) {
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		return nil, err
	}
	if err := os.Remove(root); err != nil {
		return nil, err
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		return nil, err
	}

	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		return nil, err
	}

	return runtime, nil
}

func GetTestImage(runtime *Runtime) *Image {
	imgs, err := runtime.graph.All()
	if err != nil {
		panic(err)
	} else if len(imgs) < 1 {
		panic("GASP")
	}
	return imgs[0]
}

func TestRuntimeCreate(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)

	// Make sure we start we 0 containers
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
	}
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := runtime.Destroy(container); err != nil {
			t.Error(err)
		}
	}()

	// Make sure we can find the newly created container with List()
	if len(runtime.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime.List()))
	}

	// Make sure the container List() returns is the right one
	if runtime.List()[0].Id != container.Id {
		t.Errorf("Unexpected container %v returned by List", runtime.List()[0])
	}

	// Make sure we can get the container with Get()
	if runtime.Get(container.Id) == nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure it is the right container
	if runtime.Get(container.Id) != container {
		t.Errorf("Get() returned the wrong container")
	}

	// Make sure Exists returns it as existing
	if !runtime.Exists(container.Id) {
		t.Errorf("Exists() returned false for a newly created container")
	}
}

func TestDestroy(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	// Destroy
	if err := runtime.Destroy(container); err != nil {
		t.Error(err)
	}

	// Make sure runtime.Exists() behaves correctly
	if runtime.Exists("test_destroy") {
		t.Errorf("Exists() returned true")
	}

	// Make sure runtime.List() doesn't list the destroyed container
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 container, %v found", len(runtime.List()))
	}

	// Make sure runtime.Get() refuses to return the unexisting container
	if runtime.Get(container.Id) != nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure the container root directory does not exist anymore
	_, err = os.Stat(container.root)
	if err == nil || !os.IsNotExist(err) {
		t.Errorf("Container root directory still exists after destroy")
	}

	// Test double destroy
	if err := runtime.Destroy(container); err == nil {
		// It should have failed
		t.Errorf("Double destroy did not fail")
	}
}

func TestGet(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container1, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container1)

	container2, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container2)

	container3, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container3)

	if runtime.Get(container1.Id) != container1 {
		t.Errorf("Get(test1) returned %v while expecting %v", runtime.Get(container1.Id), container1)
	}

	if runtime.Get(container2.Id) != container2 {
		t.Errorf("Get(test2) returned %v while expecting %v", runtime.Get(container2.Id), container2)
	}

	if runtime.Get(container3.Id) != container3 {
		t.Errorf("Get(test3) returned %v while expecting %v", runtime.Get(container3.Id), container3)
	}

}

func TestRestore(t *testing.T) {

	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		t.Fatal(err)
	}
	if err := os.Remove(root); err != nil {
		t.Fatal(err)
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		t.Fatal(err)
	}

	runtime1, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}

	// Create a container with one instance of docker
	container1, err := runtime1.Create(&Config{
		Image: GetTestImage(runtime1).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime1.Destroy(container1)

	// Create a second container meant to be killed
	container2, err := runtime1.Create(&Config{
		Image:     GetTestImage(runtime1).Id,
		Cmd:       []string{"/bin/cat"},
		OpenStdin: true,
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime1.Destroy(container2)

	// Start the container non blocking
	if err := container2.Start(); err != nil {
		t.Fatal(err)
	}

	if !container2.State.Running {
		t.Fatalf("Container %v should appear as running but isn't", container2.Id)
	}

	// Simulate a crash/manual quit of dockerd: process dies, states stays 'Running'
	cStdin, _ := container2.StdinPipe()
	cStdin.Close()
	if err := container2.WaitTimeout(2 * time.Second); err != nil {
		t.Fatal(err)
	}
	container2.State.Running = true
	container2.ToDisk()

	if len(runtime1.List()) != 2 {
		t.Errorf("Expected 2 container, %v found", len(runtime1.List()))
	}
	if err := container1.Run(); err != nil {
		t.Fatal(err)
	}

	if !container2.State.Running {
		t.Fatalf("Container %v should appear as running but isn't", container2.Id)
	}

	// Here are are simulating a docker restart - that is, reloading all containers
	// from scratch
	runtime2, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime2)
	if len(runtime2.List()) != 2 {
		t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
	}
	runningCount := 0
	for _, c := range runtime2.List() {
		if c.State.Running {
			t.Errorf("Running container found: %v (%v)", c.Id, c.Path)
			runningCount++
		}
	}
	if runningCount != 0 {
		t.Fatalf("Expected 0 container alive, %d found", runningCount)
	}
	container3 := runtime2.Get(container1.Id)
	if container3 == nil {
		t.Fatal("Unable to Get container")
	}
	if err := container3.Run(); err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package docker

import (
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"sync"
	"testing"
)

// FIXME: this is no longer needed
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
const unitTestImageName string = "docker-ut"

var unitTestStoreBase string
var srv *Server

func nuke(runtime *Runtime) error {
	var wg sync.WaitGroup
	for _, container := range runtime.List() {
		wg.Add(1)
		go func(c *Container) {
			c.Kill()
			wg.Add(-1)
		}(container)
	}
	wg.Wait()
	return os.RemoveAll(runtime.root)
}

func CopyDirectory(source, dest string) error {
	if _, err := exec.Command("cp", "-ra", source, dest).Output(); err != nil {
		return err
	}
	return nil
}

func layerArchive(tarfile string) (io.Reader, error) {
	// FIXME: need to close f somewhere
	f, err := os.Open(tarfile)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func init() {
	// Hack to run sys init during unit testing
	if SelfPath() == "/sbin/init" {
		SysInit()
		return
	}

	if usr, err := user.Current(); err != nil {
		panic(err)
	} else if usr.Uid != "0" {
		panic("docker tests needs to be run as root")
	}

	// Create a temp directory
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		panic(err)
	}
	unitTestStoreBase = root

	// Make it our Store root
	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		panic(err)
	}
	// Create the "Server"
	srv := &Server{
		runtime: runtime,
	}
	// Retrieve the Image
	if err := srv.CmdPull(os.Stdin, os.Stdout, unitTestImageName); err != nil {
		panic(err)
	}
}

func newTestRuntime() (*Runtime, error) {
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		return nil, err
	}
	if err := os.Remove(root); err != nil {
		return nil, err
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		panic(err)
		return nil, err
	}

	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		return nil, err
	}

	return runtime, nil
}

func GetTestImage(runtime *Runtime) *Image {
	imgs, err := runtime.graph.All()
	if err != nil {
		panic(err)
	} else if len(imgs) < 1 {
		panic("GASP")
	}
	return imgs[0]
}

func TestRuntimeCreate(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)

	// Make sure we start we 0 containers
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
	}
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := runtime.Destroy(container); err != nil {
			t.Error(err)
		}
	}()

	// Make sure we can find the newly created container with List()
	if len(runtime.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime.List()))
	}

	// Make sure the container List() returns is the right one
	if runtime.List()[0].Id != container.Id {
		t.Errorf("Unexpected container %v returned by List", runtime.List()[0])
	}

	// Make sure we can get the container with Get()
	if runtime.Get(container.Id) == nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure it is the right container
	if runtime.Get(container.Id) != container {
		t.Errorf("Get() returned the wrong container")
	}

	// Make sure Exists returns it as existing
	if !runtime.Exists(container.Id) {
		t.Errorf("Exists() returned false for a newly created container")
	}
}

func TestDestroy(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	// Destroy
	if err := runtime.Destroy(container); err != nil {
		t.Error(err)
	}

	// Make sure runtime.Exists() behaves correctly
	if runtime.Exists("test_destroy") {
		t.Errorf("Exists() returned true")
	}

	// Make sure runtime.List() doesn't list the destroyed container
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 container, %v found", len(runtime.List()))
	}

	// Make sure runtime.Get() refuses to return the unexisting container
	if runtime.Get(container.Id) != nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure the container root directory does not exist anymore
	_, err = os.Stat(container.root)
	if err == nil || !os.IsNotExist(err) {
		t.Errorf("Container root directory still exists after destroy")
	}

	// Test double destroy
	if err := runtime.Destroy(container); err == nil {
		// It should have failed
		t.Errorf("Double destroy did not fail")
	}
}

func TestGet(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container1, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container1)

	container2, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container2)

	container3, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container3)

	if runtime.Get(container1.Id) != container1 {
		t.Errorf("Get(test1) returned %v while expecting %v", runtime.Get(container1.Id), container1)
	}

	if runtime.Get(container2.Id) != container2 {
		t.Errorf("Get(test2) returned %v while expecting %v", runtime.Get(container2.Id), container2)
	}

	if runtime.Get(container3.Id) != container3 {
		t.Errorf("Get(test3) returned %v while expecting %v", runtime.Get(container3.Id), container3)
	}

}

func TestRestore(t *testing.T) {

	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		t.Fatal(err)
	}
	if err := os.Remove(root); err != nil {
		t.Fatal(err)
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		t.Fatal(err)
	}

	runtime1, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}

	// Create a container with one instance of docker
	container1, err := runtime1.Create(&Config{
		Image: GetTestImage(runtime1).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime1.Destroy(container1)
	if len(runtime1.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime1.List()))
	}
	if err := container1.Run(); err != nil {
		t.Fatal(err)
	}

	// Here are are simulating a docker restart - that is, reloading all containers
	// from scratch
	runtime2, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime2)
	if len(runtime2.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime2.List()))
	}
	container2 := runtime2.Get(container1.Id)
	if container2 == nil {
		t.Fatal("Unable to Get container")
	}
	if err := container2.Run(); err != nil {
		t.Fatal(err)
	}
}
<commit_msg>use wg.Done() isntead of wg.Add(-1)<commit_after>package docker

import (
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"os/user"
	"sync"
	"testing"
)

// FIXME: this is no longer needed
const testLayerPath string = "/var/lib/docker/docker-ut.tar"
const unitTestImageName string = "docker-ut"

var unitTestStoreBase string
var srv *Server

func nuke(runtime *Runtime) error {
	var wg sync.WaitGroup
	for _, container := range runtime.List() {
		wg.Add(1)
		go func(c *Container) {
			c.Kill()
			wg.Done()
		}(container)
	}
	wg.Wait()
	return os.RemoveAll(runtime.root)
}

func CopyDirectory(source, dest string) error {
	if _, err := exec.Command("cp", "-ra", source, dest).Output(); err != nil {
		return err
	}
	return nil
}

func layerArchive(tarfile string) (io.Reader, error) {
	// FIXME: need to close f somewhere
	f, err := os.Open(tarfile)
	if err != nil {
		return nil, err
	}
	return f, nil
}

func init() {
	// Hack to run sys init during unit testing
	if SelfPath() == "/sbin/init" {
		SysInit()
		return
	}

	if usr, err := user.Current(); err != nil {
		panic(err)
	} else if usr.Uid != "0" {
		panic("docker tests needs to be run as root")
	}

	// Create a temp directory
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		panic(err)
	}
	unitTestStoreBase = root

	// Make it our Store root
	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		panic(err)
	}
	// Create the "Server"
	srv := &Server{
		runtime: runtime,
	}
	// Retrieve the Image
	if err := srv.CmdPull(os.Stdin, os.Stdout, unitTestImageName); err != nil {
		panic(err)
	}
}

func newTestRuntime() (*Runtime, error) {
	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		return nil, err
	}
	if err := os.Remove(root); err != nil {
		return nil, err
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		panic(err)
		return nil, err
	}

	runtime, err := NewRuntimeFromDirectory(root)
	if err != nil {
		return nil, err
	}

	return runtime, nil
}

func GetTestImage(runtime *Runtime) *Image {
	imgs, err := runtime.graph.All()
	if err != nil {
		panic(err)
	} else if len(imgs) < 1 {
		panic("GASP")
	}
	return imgs[0]
}

func TestRuntimeCreate(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)

	// Make sure we start we 0 containers
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 containers, %v found", len(runtime.List()))
	}
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		if err := runtime.Destroy(container); err != nil {
			t.Error(err)
		}
	}()

	// Make sure we can find the newly created container with List()
	if len(runtime.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime.List()))
	}

	// Make sure the container List() returns is the right one
	if runtime.List()[0].Id != container.Id {
		t.Errorf("Unexpected container %v returned by List", runtime.List()[0])
	}

	// Make sure we can get the container with Get()
	if runtime.Get(container.Id) == nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure it is the right container
	if runtime.Get(container.Id) != container {
		t.Errorf("Get() returned the wrong container")
	}

	// Make sure Exists returns it as existing
	if !runtime.Exists(container.Id) {
		t.Errorf("Exists() returned false for a newly created container")
	}
}

func TestDestroy(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	// Destroy
	if err := runtime.Destroy(container); err != nil {
		t.Error(err)
	}

	// Make sure runtime.Exists() behaves correctly
	if runtime.Exists("test_destroy") {
		t.Errorf("Exists() returned true")
	}

	// Make sure runtime.List() doesn't list the destroyed container
	if len(runtime.List()) != 0 {
		t.Errorf("Expected 0 container, %v found", len(runtime.List()))
	}

	// Make sure runtime.Get() refuses to return the unexisting container
	if runtime.Get(container.Id) != nil {
		t.Errorf("Unable to get newly created container")
	}

	// Make sure the container root directory does not exist anymore
	_, err = os.Stat(container.root)
	if err == nil || !os.IsNotExist(err) {
		t.Errorf("Container root directory still exists after destroy")
	}

	// Test double destroy
	if err := runtime.Destroy(container); err == nil {
		// It should have failed
		t.Errorf("Double destroy did not fail")
	}
}

func TestGet(t *testing.T) {
	runtime, err := newTestRuntime()
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime)
	container1, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container1)

	container2, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container2)

	container3, err := runtime.Create(&Config{
		Image: GetTestImage(runtime).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime.Destroy(container3)

	if runtime.Get(container1.Id) != container1 {
		t.Errorf("Get(test1) returned %v while expecting %v", runtime.Get(container1.Id), container1)
	}

	if runtime.Get(container2.Id) != container2 {
		t.Errorf("Get(test2) returned %v while expecting %v", runtime.Get(container2.Id), container2)
	}

	if runtime.Get(container3.Id) != container3 {
		t.Errorf("Get(test3) returned %v while expecting %v", runtime.Get(container3.Id), container3)
	}

}

func TestRestore(t *testing.T) {

	root, err := ioutil.TempDir("", "docker-test")
	if err != nil {
		t.Fatal(err)
	}
	if err := os.Remove(root); err != nil {
		t.Fatal(err)
	}
	if err := CopyDirectory(unitTestStoreBase, root); err != nil {
		t.Fatal(err)
	}

	runtime1, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}

	// Create a container with one instance of docker
	container1, err := runtime1.Create(&Config{
		Image: GetTestImage(runtime1).Id,
		Cmd:   []string{"ls", "-al"},
	},
	)
	if err != nil {
		t.Fatal(err)
	}
	defer runtime1.Destroy(container1)
	if len(runtime1.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime1.List()))
	}
	if err := container1.Run(); err != nil {
		t.Fatal(err)
	}

	// Here are are simulating a docker restart - that is, reloading all containers
	// from scratch
	runtime2, err := NewRuntimeFromDirectory(root)
	if err != nil {
		t.Fatal(err)
	}
	defer nuke(runtime2)
	if len(runtime2.List()) != 1 {
		t.Errorf("Expected 1 container, %v found", len(runtime2.List()))
	}
	container2 := runtime2.Get(container1.Id)
	if container2 == nil {
		t.Fatal("Unable to Get container")
	}
	if err := container2.Run(); err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package webgo

import (
	"encoding/json"
	"fmt"
	"html/template"
	"net/http"
)

// ErrorData used to render the error page
type ErrorData struct {
	ErrCode        int
	ErrDescription string
}

// dOutput is the standard/valid output wrapped in `{data: <payload>, status: <http response status>}`
type dOutput struct {
	Data   interface{} `json:"data"`
	Status int         `json:"status"`
}

// errOutput is the error output wrapped in `{errors:<errors>, status: <http response status>}`
type errOutput struct {
	Errors interface{} `json:"errors"`
	Status int         `json:"status"`
}

const (
	// HeaderContentType is the key for mentioning the response header content type
	HeaderContentType = "Content-Type"
	// JSONContentType is the MIME type when the response is JSON
	JSONContentType = "application/json"
	// HTMLContentType is the MIME type when the response is HTML
	HTMLContentType = "text/html; charset=UTF-8"

	// ErrInternalServer to send when there's an internal server error
	ErrInternalServer = "Internal server error."
)

// SendHeader is used to send only a response header, i.e no response body
func SendHeader(w http.ResponseWriter, rCode int) {
	w.WriteHeader(rCode)
}

// Send sends a completely custom response without wrapping in the
// `{data: <data>, status: <int>` struct
func Send(w http.ResponseWriter, contentType string, data interface{}, rCode int) {
	w.Header().Set(HeaderContentType, contentType)
	w.WriteHeader(rCode)
	_, err := fmt.Fprint(w, data)
	if err != nil {
		R500(w, ErrInternalServer)
	}
}

// SendResponse is used to respond to any request (JSON response) based on the code, data etc.
func SendResponse(w http.ResponseWriter, data interface{}, rCode int) {
	w.Header().Set(HeaderContentType, JSONContentType)
	w.WriteHeader(rCode)

	err := json.NewEncoder(w).Encode(dOutput{Data: data, Status: rCode})
	if err != nil {
		/*
			In case of encoding error, send "internal server error" after
			logging the actual error.
		*/
		errLogger.Println(err)
		R500(w, ErrInternalServer)
		return
	}
}

// SendError is used to respond to any request with an error
func SendError(w http.ResponseWriter, data interface{}, rCode int) {
	w.Header().Set(HeaderContentType, JSONContentType)
	w.WriteHeader(rCode)

	err := json.NewEncoder(w).Encode(errOutput{data, rCode})
	if err != nil {
		/*
			In case of encoding error, send "internal server error" after
			logging the actual error.
		*/
		errLogger.Println(err)
		R500(w, ErrInternalServer)
		return
	}
}

// Render is used for rendering templates (HTML)
func Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Template) {
	// In case of HTML response, setting appropriate header type for text/HTML response
	w.Header().Set(HeaderContentType, HTMLContentType)

	w.WriteHeader(rCode)

	// Rendering an HTML template with appropriate data
	tpl.Execute(w, data)
}

// Render404 - used to render a 404 page
func Render404(w http.ResponseWriter, tpl *template.Template) {
	Render(w, ErrorData{
		404,
		"Sorry, the URL you requested was not found on this server... Or you're lost :-/",
	},
		404,
		tpl,
	)
}

// R200 - Successful/OK response
func R200(w http.ResponseWriter, data interface{}) {
	SendResponse(w, data, 200)
}

// R201 - New item created
func R201(w http.ResponseWriter, data interface{}) {
	SendResponse(w, data, 201)
}

// R204 - empty, no content
func R204(w http.ResponseWriter) {
	SendHeader(w, 204)
}

// R302 - Temporary redirect
func R302(w http.ResponseWriter, data interface{}) {
	SendResponse(w, data, 302)
}

// R400 - Invalid request, any incorrect/erraneous value in the request body
func R400(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 400)
}

// R403 - Unauthorized access
func R403(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 403)
}

// R404 - Resource not found
func R404(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 404)
}

// R406 - Unacceptable header. For any error related to values set in header
func R406(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 406)
}

// R451 - Resource taken down because of a legal request
func R451(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 451)
}

// R500 - Internal server error
func R500(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 500)
}
<commit_msg>removed unnecessary return and minor formatting<commit_after>package webgo

import (
	"encoding/json"
	"fmt"
	"html/template"
	"net/http"
)

// ErrorData used to render the error page
type ErrorData struct {
	ErrCode        int
	ErrDescription string
}

// dOutput is the standard/valid output wrapped in `{data: <payload>, status: <http response status>}`
type dOutput struct {
	Data   interface{} `json:"data"`
	Status int         `json:"status"`
}

// errOutput is the error output wrapped in `{errors:<errors>, status: <http response status>}`
type errOutput struct {
	Errors interface{} `json:"errors"`
	Status int         `json:"status"`
}

const (
	// HeaderContentType is the key for mentioning the response header content type
	HeaderContentType = "Content-Type"
	// JSONContentType is the MIME type when the response is JSON
	JSONContentType = "application/json"
	// HTMLContentType is the MIME type when the response is HTML
	HTMLContentType = "text/html; charset=UTF-8"

	// ErrInternalServer to send when there's an internal server error
	ErrInternalServer = "Internal server error."
)

// SendHeader is used to send only a response header, i.e no response body
func SendHeader(w http.ResponseWriter, rCode int) {
	w.WriteHeader(rCode)
}

// Send sends a completely custom response without wrapping in the
// `{data: <data>, status: <int>` struct
func Send(w http.ResponseWriter, contentType string, data interface{}, rCode int) {
	w.Header().Set(HeaderContentType, contentType)
	w.WriteHeader(rCode)
	_, err := fmt.Fprint(w, data)
	if err != nil {
		R500(w, ErrInternalServer)
	}
}

// SendResponse is used to respond to any request (JSON response) based on the code, data etc.
func SendResponse(w http.ResponseWriter, data interface{}, rCode int) {
	w.Header().Set(HeaderContentType, JSONContentType)
	w.WriteHeader(rCode)

	err := json.NewEncoder(w).Encode(dOutput{Data: data, Status: rCode})
	if err != nil {
		/*
			In case of encoding error, send "internal server error" after
			logging the actual error.
		*/
		errLogger.Println(err)
		R500(w, ErrInternalServer)
	}
}

// SendError is used to respond to any request with an error
func SendError(w http.ResponseWriter, data interface{}, rCode int) {
	w.Header().Set(HeaderContentType, JSONContentType)
	w.WriteHeader(rCode)

	err := json.NewEncoder(w).Encode(errOutput{data, rCode})
	if err != nil {
		/*
			In case of encoding error, send "internal server error" after
			logging the actual error.
		*/
		errLogger.Println(err)
		R500(w, ErrInternalServer)
	}
}

// Render is used for rendering templates (HTML)
func Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Template) {
	// In case of HTML response, setting appropriate header type for text/HTML response
	w.Header().Set(HeaderContentType, HTMLContentType)
	w.WriteHeader(rCode)

	// Rendering an HTML template with appropriate data
	tpl.Execute(w, data)
}

// Render404 - used to render a 404 page
func Render404(w http.ResponseWriter, tpl *template.Template) {
	Render(w, ErrorData{
		404,
		"Sorry, the URL you requested was not found on this server... Or you're lost :-/",
	},
		404,
		tpl,
	)
}

// R200 - Successful/OK response
func R200(w http.ResponseWriter, data interface{}) {
	SendResponse(w, data, 200)
}

// R201 - New item created
func R201(w http.ResponseWriter, data interface{}) {
	SendResponse(w, data, 201)
}

// R204 - empty, no content
func R204(w http.ResponseWriter) {
	SendHeader(w, 204)
}

// R302 - Temporary redirect
func R302(w http.ResponseWriter, data interface{}) {
	SendResponse(w, data, 302)
}

// R400 - Invalid request, any incorrect/erraneous value in the request body
func R400(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 400)
}

// R403 - Unauthorized access
func R403(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 403)
}

// R404 - Resource not found
func R404(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 404)
}

// R406 - Unacceptable header. For any error related to values set in header
func R406(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 406)
}

// R451 - Resource taken down because of a legal request
func R451(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 451)
}

// R500 - Internal server error
func R500(w http.ResponseWriter, data interface{}) {
	SendError(w, data, 500)
}
<|endoftext|>


<commit_before>package rest

import (
	"github.com/lfq7413/tomato/utils"
	"gopkg.in/mgo.v2/bson"
)

// Auth 保存当前请求的用户权限信息
type Auth struct {
	IsMaster       bool
	InstallationID string
	User           map[string]interface{}
	UserRoles      []string
	FetchedRoles   bool
	RolePromise    []string
}

// Master 生成 Master 级别用户
func Master() *Auth {
	return &Auth{IsMaster: true}
}

// Nobody 生成空用户
func Nobody() *Auth {
	return &Auth{IsMaster: false}
}

// GetAuthForSessionToken 返回 sessionToken 对应的用户权限信息
func GetAuthForSessionToken(sessionToken string, installationID string) *Auth {
	// 从缓存获取用户信息
	cachedUser := usersCache.get(sessionToken)
	if cachedUser != nil {
		return &Auth{
			IsMaster:       false,
			InstallationID: installationID,
			User:           cachedUser.(map[string]interface{}),
		}
	}
	// 缓存中不存在时，从数据库中查询
	restOptions := bson.M{
		"limit":   1,
		"include": "user",
	}
	restWhere := bson.M{
		"_session_token": sessionToken,
	}
	response := NewQuery(Master(), "_Session", restWhere, restOptions).Execute()

	if response == nil || response["results"] == nil {
		return Nobody()
	}
	results := utils.SliceInterface(response["results"])
	if results == nil || len(results) != 1 {
		return Nobody()
	}
	result := utils.MapInterface(results[0])
	if result == nil || result["user"] == nil {
		return Nobody()
	}

	user := utils.MapInterface(result["user"])
	delete(user, "password")
	user["className"] = "_User"
	user["sessionToken"] = sessionToken
	// 写入缓存
	usersCache.set(sessionToken, user)

	return &Auth{
		IsMaster:       false,
		InstallationID: installationID,
		User:           user,
	}
}

// CouldUpdateUserID Master 与当前用户可进行修改
func (a *Auth) CouldUpdateUserID(objectID string) bool {
	if a.IsMaster {
		return true
	}
	if a.User != nil && a.User["objectId"].(string) == objectID {
		return true
	}
	return false
}

// GetUserRoles ...
func (a *Auth) GetUserRoles() []string {
	if a.IsMaster || a.User == nil {
		return []string{}
	}
	if a.FetchedRoles {
		return a.UserRoles
	}
	if a.RolePromise != nil {
		return a.RolePromise
	}
	a.RolePromise = a.loadRoles()
	return a.RolePromise
}

func (a *Auth) loadRoles() []string {

	users := map[string]interface{}{
		"__type":    "Pointer",
		"className": "_User",
		"objectId":  a.User["objectId"],
	}
	where := map[string]interface{}{
		"users": users,
	}
	// 取出当前用户直接对应的所有角色
	response := Find(Master(), "_Role", where, map[string]interface{}{})
	if utils.HasResults(response) == false {
		a.UserRoles = []string{}
		a.FetchedRoles = true
		a.RolePromise = nil
		return a.UserRoles
	}
	results := utils.SliceInterface(response["results"])
	roleIDs := []string{}
	for _, v := range results {
		roleObj := utils.MapInterface(v)
		roleIDs = append(roleIDs, utils.String(roleObj["objectId"]))
	}
	// 取出角色对应的父角色
	for _, v := range roleIDs {
		roleIDs = append(roleIDs, a.getAllRoleNamesForID(v)...)
	}

	objectID := map[string]interface{}{
		"$in": roleIDs,
	}
	where = map[string]interface{}{
		"objectId": objectID,
	}
	// 取出所有角色名称
	response = Find(Master(), "_Role", where, map[string]interface{}{})
	results = utils.SliceInterface(response["results"])
	a.UserRoles = []string{}
	for _, v := range results {
		roleObj := utils.MapInterface(v)
		a.UserRoles = append(a.UserRoles, "role:"+utils.String(roleObj["name"]))
	}
	a.FetchedRoles = true
	a.RolePromise = nil

	return a.UserRoles
}

func (a *Auth) getAllRoleNamesForID(roleID string) []string {
	rolePointer := map[string]interface{}{
		"__type":    "Pointer",
		"className": "_Role",
		"objectId":  roleID,
	}
	where := map[string]interface{}{
		"roles": rolePointer,
	}
	// 取出当前角色对应的直接父角色
	response := Find(Master(), "_Role", where, map[string]interface{}{})
	if utils.HasResults(response) == false {
		return []string{}
	}
	results := utils.SliceInterface(response["results"])
	roleIDs := []string{}
	for _, v := range results {
		roleObj := utils.MapInterface(v)
		roleIDs = append(roleIDs, utils.String(roleObj["objectId"]))
	}
	// 递归取出角色对应的父角色
	for _, v := range roleIDs {
		roleIDs = append(roleIDs, a.getAllRoleNamesForID(v)...)
	}
	return roleIDs
}
<commit_msg>使用 $relatedTo 去查询角色<commit_after>package rest

import (
	"github.com/lfq7413/tomato/utils"
	"gopkg.in/mgo.v2/bson"
)

// Auth 保存当前请求的用户权限信息
type Auth struct {
	IsMaster       bool
	InstallationID string
	User           map[string]interface{}
	UserRoles      []string
	FetchedRoles   bool
	RolePromise    []string
}

// Master 生成 Master 级别用户
func Master() *Auth {
	return &Auth{IsMaster: true}
}

// Nobody 生成空用户
func Nobody() *Auth {
	return &Auth{IsMaster: false}
}

// GetAuthForSessionToken 返回 sessionToken 对应的用户权限信息
func GetAuthForSessionToken(sessionToken string, installationID string) *Auth {
	// 从缓存获取用户信息
	cachedUser := usersCache.get(sessionToken)
	if cachedUser != nil {
		return &Auth{
			IsMaster:       false,
			InstallationID: installationID,
			User:           cachedUser.(map[string]interface{}),
		}
	}
	// 缓存中不存在时，从数据库中查询
	restOptions := bson.M{
		"limit":   1,
		"include": "user",
	}
	restWhere := bson.M{
		"_session_token": sessionToken,
	}
	response := NewQuery(Master(), "_Session", restWhere, restOptions).Execute()

	if response == nil || response["results"] == nil {
		return Nobody()
	}
	results := utils.SliceInterface(response["results"])
	if results == nil || len(results) != 1 {
		return Nobody()
	}
	result := utils.MapInterface(results[0])
	if result == nil || result["user"] == nil {
		return Nobody()
	}

	user := utils.MapInterface(result["user"])
	delete(user, "password")
	user["className"] = "_User"
	user["sessionToken"] = sessionToken
	// 写入缓存
	usersCache.set(sessionToken, user)

	return &Auth{
		IsMaster:       false,
		InstallationID: installationID,
		User:           user,
	}
}

// CouldUpdateUserID Master 与当前用户可进行修改
func (a *Auth) CouldUpdateUserID(objectID string) bool {
	if a.IsMaster {
		return true
	}
	if a.User != nil && a.User["objectId"].(string) == objectID {
		return true
	}
	return false
}

// GetUserRoles 获取用户所属的角色列表
func (a *Auth) GetUserRoles() []string {
	if a.IsMaster || a.User == nil {
		return []string{}
	}
	if a.FetchedRoles {
		return a.UserRoles
	}
	if a.RolePromise != nil {
		return a.RolePromise
	}
	a.RolePromise = a.loadRoles()
	return a.RolePromise
}

// loadRoles 从数据库加载用户角色列表
func (a *Auth) loadRoles() []string {
	// _Role 表中的 users 字段为 Relation 类型，应该使用 $relatedTo 去查询
	users := map[string]interface{}{
		"__type":    "Pointer",
		"className": "_User",
		"objectId":  a.User["objectId"],
	}
	relatedTo := bson.M{
		"object": users,
		"key":    "users",
	}
	where := map[string]interface{}{
		"$relatedTo": relatedTo,
	}
	// 取出当前用户直接对应的所有角色
	response := Find(Master(), "_Role", where, map[string]interface{}{})
	if utils.HasResults(response) == false {
		a.UserRoles = []string{}
		a.FetchedRoles = true
		a.RolePromise = nil
		return a.UserRoles
	}
	results := utils.SliceInterface(response["results"])
	roleIDs := []string{}
	for _, v := range results {
		roleObj := utils.MapInterface(v)
		roleIDs = append(roleIDs, utils.String(roleObj["objectId"]))
	}
	// 取出角色对应的父角色
	for _, v := range roleIDs {
		roleIDs = append(roleIDs, a.getAllRoleNamesForID(v)...)
	}

	objectID := map[string]interface{}{
		"$in": roleIDs,
	}
	where = map[string]interface{}{
		"objectId": objectID,
	}
	// 取出所有角色名称
	response = Find(Master(), "_Role", where, map[string]interface{}{})
	results = utils.SliceInterface(response["results"])
	a.UserRoles = []string{}
	for _, v := range results {
		roleObj := utils.MapInterface(v)
		a.UserRoles = append(a.UserRoles, "role:"+utils.String(roleObj["name"]))
	}
	a.FetchedRoles = true
	a.RolePromise = nil

	return a.UserRoles
}

// getAllRoleNamesForID 取出角色 id 对应的父角色
func (a *Auth) getAllRoleNamesForID(roleID string) []string {
	// _Role 表中的 roles 字段为 Relation 类型，应该使用 $relatedTo 去查询
	rolePointer := map[string]interface{}{
		"__type":    "Pointer",
		"className": "_Role",
		"objectId":  roleID,
	}
	relatedTo := bson.M{
		"object": rolePointer,
		"key":    "roles",
	}
	where := map[string]interface{}{
		"$relatedTo": relatedTo,
	}
	// 取出当前角色对应的直接父角色
	response := Find(Master(), "_Role", where, map[string]interface{}{})
	if utils.HasResults(response) == false {
		return []string{}
	}
	results := utils.SliceInterface(response["results"])
	roleIDs := []string{}
	for _, v := range results {
		roleObj := utils.MapInterface(v)
		roleIDs = append(roleIDs, utils.String(roleObj["objectId"]))
	}
	// 递归取出角色对应的父角色
	for _, v := range roleIDs {
		roleIDs = append(roleIDs, a.getAllRoleNamesForID(v)...)
	}
	return roleIDs
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
	"github.com/gocql/gocql"
	"github.com/gorilla/mux"
	"io/ioutil"
	//"log"
	"encoding/json"
	//"fmt"
	"net/http"
	"time"
)

// Get all active endpoints from Kubernetes API
func getEndpoints(pod string) []string {
	resp, _ := http.Get("http://172.17.8.101:8080/api/v1beta1/endpoints/" + pod + "?namespace=default")
	body, _ := ioutil.ReadAll(resp.Body)
	var endpoints v1beta1.Endpoints
	json.Unmarshal(body, &endpoints)
	return (endpoints.Endpoints)
}

var session *gocql.Session

func main() {
	// connect to the cluster
	endpoints := getEndpoints("cassandra")
	cluster := gocql.NewCluster(endpoints...)
	cluster.Keyspace = "bakery"
	cluster.Consistency = gocql.Quorum
	session, _ = cluster.CreateSession()
	defer session.Close()

	r := mux.NewRouter()
	r.HandleFunc("/sensors", SensorsHandler)
	http.ListenAndServe(":9090", r)
}

type Sensor struct {
	SensorId  string    `json:"sensor_id"`
	State     string    `json:"state"`
	EventTime time.Time `json:"event_time"`
}

type Sensors struct {
	Sensors []Sensor `json:"sensors"`
}

func SensorHandler(rw http.ResponseWriter, r *http.Request) {

	sensor := Sensor{}

	q := session.Query(`SELECT sensor_id, state, event_time FROM sensor_states LIMIT 1`)
	q.Scan(&sensor.SensorId, &sensor.State, &sensor.EventTime)

	js, _ := json.Marshal(sensor)
	rw.Write(js)
}

func SensorsHandler(rw http.ResponseWriter, r *http.Request) {

	sensors := make([]Sensor, 0)

	q := session.Query(`SELECT sensor_id, state, event_time FROM sensor_states LIMIT 100`).Iter()
	for {
		sensor := Sensor{}
		if q.Scan(&sensor.SensorId, &sensor.State, &sensor.EventTime) {
			sensors = append(sensors, sensor)
		} else {
			break
		}
	}
	var sensorsList Sensors
	sensorsList.Sensors = sensors
	js, _ := json.Marshal(sensorsList)
	rw.Write(js)
}

<commit_msg>remove single sensor endpoint from rest for now<commit_after>package main

import (
	"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
	"github.com/gocql/gocql"
	"github.com/gorilla/mux"
	"io/ioutil"
	//"log"
	"encoding/json"
	//"fmt"
	"net/http"
	"time"
)

// Get all active endpoints from Kubernetes API
func getEndpoints(pod string) []string {
	resp, _ := http.Get("http://172.17.8.101:8080/api/v1beta1/endpoints/" + pod + "?namespace=default")
	body, _ := ioutil.ReadAll(resp.Body)
	var endpoints v1beta1.Endpoints
	json.Unmarshal(body, &endpoints)
	return (endpoints.Endpoints)
}

var session *gocql.Session

func main() {
	// connect to the cluster
	endpoints := getEndpoints("cassandra")
	cluster := gocql.NewCluster(endpoints...)
	cluster.Keyspace = "bakery"
	cluster.Consistency = gocql.Quorum
	session, _ = cluster.CreateSession()
	defer session.Close()

	r := mux.NewRouter()
	r.HandleFunc("/sensors", SensorsHandler)
	http.ListenAndServe(":9090", r)
}

type Sensor struct {
	SensorId  string    `json:"sensor_id"`
	State     string    `json:"state"`
	EventTime time.Time `json:"event_time"`
}

type Sensors struct {
	Sensors []Sensor `json:"sensors"`
}

func SensorsHandler(rw http.ResponseWriter, r *http.Request) {

	sensors := make([]Sensor, 0)

	q := session.Query(`SELECT sensor_id, state, event_time FROM sensor_states LIMIT 100`).Iter()
	for {
		sensor := Sensor{}
		if q.Scan(&sensor.SensorId, &sensor.State, &sensor.EventTime) {
			sensors = append(sensors, sensor)
		} else {
			break
		}
	}
	var sensorsList Sensors
	sensorsList.Sensors = sensors
	js, _ := json.Marshal(sensorsList)
	rw.Write(js)
}

<|endoftext|>


<commit_before>package github

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	"github.com/github/hub/Godeps/_workspace/src/github.com/howeyc/gopass"
	"github.com/github/hub/utils"
)

var (
	defaultConfigsFile = filepath.Join(os.Getenv("HOME"), ".config", "hub")
)

type yamlHost struct {
	User       string `yaml:"user"`
	OAuthToken string `yaml:"oauth_token"`
	Protocol   string `yaml:"protocol"`
}

type yamlConfig map[string][]yamlHost

type Host struct {
	Host        string `toml:"host"`
	User        string `toml:"user"`
	AccessToken string `toml:"access_token"`
	Protocol    string `toml:"protocol"`
}

type Config struct {
	Hosts []Host `toml:"hosts"`
}

func (c *Config) PromptForHost(host string) (h *Host, err error) {
	h = c.Find(host)
	if h != nil {
		return
	}

	user := c.PromptForUser()
	pass := c.PromptForPassword(host, user)

	client := NewClient(host)
	var code, token string
	for {
		token, err = client.FindOrCreateToken(user, pass, code)
		if err == nil {
			break
		}

		if ae, ok := err.(*AuthError); ok && ae.IsRequired2FACodeError() {
			if (code != "") {
				fmt.Fprintln(os.Stderr, "warning: invalid two-factor code")
			}
			code = c.PromptForOTP()
		} else {
			break
		}
	}

	if err != nil {
		return
	}

	client.Host.AccessToken = token
	currentUser, err := client.CurrentUser()
	if err != nil {
		return
	}

	h = &Host{
		Host:        host,
		User:        currentUser.Login,
		AccessToken: token,
		Protocol:    "https",
	}
	c.Hosts = append(c.Hosts, *h)
	err = newConfigService().Save(configsFile(), c)

	return
}

func (c *Config) PromptForUser() (user string) {
	user = os.Getenv("GITHUB_USER")
	if user != "" {
		return
	}

	fmt.Printf("%s username: ", GitHubHost)
	user = c.scanLine()

	return
}

func (c *Config) PromptForPassword(host, user string) (pass string) {
	pass = os.Getenv("GITHUB_PASSWORD")
	if pass != "" {
		return
	}

	fmt.Printf("%s password for %s (never stored): ", host, user)
	if isTerminal(os.Stdout.Fd()) {
		pass = string(gopass.GetPasswd())
	} else {
		pass = c.scanLine()
	}

	return
}

func (c *Config) PromptForOTP() string {
	fmt.Print("two-factor authentication code: ")
	return c.scanLine()
}

func (c *Config) scanLine() string {
	var line string
	scanner := bufio.NewScanner(os.Stdin)
	if scanner.Scan() {
		line = scanner.Text()
	}
	utils.Check(scanner.Err())

	return line
}

func (c *Config) Find(host string) *Host {
	for _, h := range c.Hosts {
		if h.Host == host {
			return &h
		}
	}

	return nil
}

func (c *Config) selectHost() *Host {
	options := len(c.Hosts)

	if options == 1 {
		return &c.Hosts[0]
	}

	prompt := "Select host:\n"
	for idx, host := range c.Hosts {
		prompt += fmt.Sprintf(" %d. %s\n", idx+1, host.Host)
	}
	prompt += fmt.Sprint("> ")

	fmt.Printf(prompt)
	index := c.scanLine()
	i, err := strconv.Atoi(index)
	if err != nil || i < 1 || i > options {
		utils.Check(fmt.Errorf("Error: must enter a number [1-%d]", options))
	}

	return &c.Hosts[i-1]
}

func configsFile() string {
	configsFile := os.Getenv("GH_CONFIG")
	if configsFile == "" {
		configsFile = defaultConfigsFile
	}

	return configsFile
}

func CurrentConfig() *Config {
	c := &Config{}
	newConfigService().Load(configsFile(), c)

	return c
}

func (c *Config) DefaultHost() (host *Host, err error) {
	if GitHubHostEnv != "" {
		host, err = c.PromptForHost(GitHubHostEnv)
	} else if len(c.Hosts) > 0 {
		host = c.selectHost()
	} else {
		host, err = c.PromptForHost(DefaultGitHubHost())
	}

	return
}

// Public for testing purpose
func CreateTestConfigs(user, token string) *Config {
	f, _ := ioutil.TempFile("", "test-config")
	defaultConfigsFile = f.Name()

	host := Host{
		User:        "jingweno",
		AccessToken: "123",
		Host:        GitHubHost,
	}

	c := &Config{Hosts: []Host{host}}
	err := newConfigService().Save(f.Name(), c)
	if err != nil {
		panic(err)
	}

	return c
}
<commit_msg>Get home dir using `user.Current()` if `HOME` env var is not set<commit_after>package github

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/user"
	"path/filepath"
	"strconv"

	"github.com/github/hub/Godeps/_workspace/src/github.com/howeyc/gopass"
	"github.com/github/hub/utils"
)

var defaultConfigsFile string

func init() {
	homeDir := os.Getenv("HOME")

	if homeDir == "" {
		if u, err := user.Current(); err == nil {
			homeDir = u.HomeDir
		}
	}

	if homeDir == "" {
		utils.Check(fmt.Errorf("Can't get current user's home dir"))
	}

	defaultConfigsFile = filepath.Join(homeDir, ".config", "hub")
}

type yamlHost struct {
	User       string `yaml:"user"`
	OAuthToken string `yaml:"oauth_token"`
	Protocol   string `yaml:"protocol"`
}

type yamlConfig map[string][]yamlHost

type Host struct {
	Host        string `toml:"host"`
	User        string `toml:"user"`
	AccessToken string `toml:"access_token"`
	Protocol    string `toml:"protocol"`
}

type Config struct {
	Hosts []Host `toml:"hosts"`
}

func (c *Config) PromptForHost(host string) (h *Host, err error) {
	h = c.Find(host)
	if h != nil {
		return
	}

	user := c.PromptForUser()
	pass := c.PromptForPassword(host, user)

	client := NewClient(host)
	var code, token string
	for {
		token, err = client.FindOrCreateToken(user, pass, code)
		if err == nil {
			break
		}

		if ae, ok := err.(*AuthError); ok && ae.IsRequired2FACodeError() {
			if code != "" {
				fmt.Fprintln(os.Stderr, "warning: invalid two-factor code")
			}
			code = c.PromptForOTP()
		} else {
			break
		}
	}

	if err != nil {
		return
	}

	client.Host.AccessToken = token
	currentUser, err := client.CurrentUser()
	if err != nil {
		return
	}

	h = &Host{
		Host:        host,
		User:        currentUser.Login,
		AccessToken: token,
		Protocol:    "https",
	}
	c.Hosts = append(c.Hosts, *h)
	err = newConfigService().Save(configsFile(), c)

	return
}

func (c *Config) PromptForUser() (user string) {
	user = os.Getenv("GITHUB_USER")
	if user != "" {
		return
	}

	fmt.Printf("%s username: ", GitHubHost)
	user = c.scanLine()

	return
}

func (c *Config) PromptForPassword(host, user string) (pass string) {
	pass = os.Getenv("GITHUB_PASSWORD")
	if pass != "" {
		return
	}

	fmt.Printf("%s password for %s (never stored): ", host, user)
	if isTerminal(os.Stdout.Fd()) {
		pass = string(gopass.GetPasswd())
	} else {
		pass = c.scanLine()
	}

	return
}

func (c *Config) PromptForOTP() string {
	fmt.Print("two-factor authentication code: ")
	return c.scanLine()
}

func (c *Config) scanLine() string {
	var line string
	scanner := bufio.NewScanner(os.Stdin)
	if scanner.Scan() {
		line = scanner.Text()
	}
	utils.Check(scanner.Err())

	return line
}

func (c *Config) Find(host string) *Host {
	for _, h := range c.Hosts {
		if h.Host == host {
			return &h
		}
	}

	return nil
}

func (c *Config) selectHost() *Host {
	options := len(c.Hosts)

	if options == 1 {
		return &c.Hosts[0]
	}

	prompt := "Select host:\n"
	for idx, host := range c.Hosts {
		prompt += fmt.Sprintf(" %d. %s\n", idx+1, host.Host)
	}
	prompt += fmt.Sprint("> ")

	fmt.Printf(prompt)
	index := c.scanLine()
	i, err := strconv.Atoi(index)
	if err != nil || i < 1 || i > options {
		utils.Check(fmt.Errorf("Error: must enter a number [1-%d]", options))
	}

	return &c.Hosts[i-1]
}

func configsFile() string {
	configsFile := os.Getenv("GH_CONFIG")
	if configsFile == "" {
		configsFile = defaultConfigsFile
	}

	return configsFile
}

func CurrentConfig() *Config {
	c := &Config{}
	newConfigService().Load(configsFile(), c)

	return c
}

func (c *Config) DefaultHost() (host *Host, err error) {
	if GitHubHostEnv != "" {
		host, err = c.PromptForHost(GitHubHostEnv)
	} else if len(c.Hosts) > 0 {
		host = c.selectHost()
	} else {
		host, err = c.PromptForHost(DefaultGitHubHost())
	}

	return
}

// Public for testing purpose
func CreateTestConfigs(user, token string) *Config {
	f, _ := ioutil.TempFile("", "test-config")
	defaultConfigsFile = f.Name()

	host := Host{
		User:        "jingweno",
		AccessToken: "123",
		Host:        GitHubHost,
	}

	c := &Config{Hosts: []Host{host}}
	err := newConfigService().Save(f.Name(), c)
	if err != nil {
		panic(err)
	}

	return c
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	//	"github.com/bluele/slack"
	"github.com/codegangsta/cli"
	"os"
	"os/user"
)

var channel string

func readConfig(path string) (string, error) {
	file, err := os.Open(path)
	if err != nil {
		return "", fmt.Errorf("missing config: %s", path)
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines[0], nil
}

func main() {
	usr, err := user.Current()
	if err != nil {
		fmt.Println("unable to determine current user")
		os.Exit(1)
	}

	app := cli.NewApp()
	app.Name = "slackcat"
	app.Usage = "redirect a file to slack"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "channel, c",
			Usage: "Slack channel to post to",
		},
	}

	app.Action = func(c *cli.Context) {
		if c.String("channel") == "" {
			fmt.Println("no channel provided!")
			os.Exit(1)
		}
		token, err := readConfig(usr.HomeDir + "/.slackcat")
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}
		fmt.Println(token)
	}

	app.Run(os.Args)

}
<commit_msg>add file upload, read stdin to tmp file<commit_after>package main

import (
	"bufio"
	"fmt"
	//	"github.com/bluele/slack"
	"github.com/bluele/slack"
	"github.com/codegangsta/cli"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/user"
	"strconv"
	"time"
)

var channel string

type Payload struct {
	token    string
	filename string
	filepath string
}

func failOnError(err error, msg string) {
	if err != nil {
		fmt.Println("%s: %s", msg, err)
		os.Exit(1)
	}
}

func getConfigPath() (string, error) {
	usr, err := user.Current()
	if err != nil {
		return "", fmt.Errorf("unable to determine current user")
	}
	return usr.HomeDir + "/.slackcat", nil
}

func readConfig() (string, error) {
	path, err := getConfigPath()

	file, err := os.Open(path)
	if err != nil {
		return "", fmt.Errorf("missing config: %s", path)
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines[0], nil
}

func readIn() *os.File {
	var line string
	var lines []string

	tmp, err := ioutil.TempFile(os.TempDir(), "multivac-")
	if err != nil {
		panic(err)
	}

	for {
		_, err := fmt.Scan(&line)
		if err != nil {
			if err != io.EOF {
				log.Fatal(err)
			}
			break
		}
		fmt.Println(line)
		lines = append(lines, line)
	}

	w := bufio.NewWriter(tmp)
	for _, line := range lines {
		fmt.Fprintln(w, line)
	}
	w.Flush()

	return tmp
}

func postToSlack(token, tmpPath, fileName, channelName string) error {
	api := slack.New(token)
	channel, err := api.FindChannelByName(channelName)
	if err != nil {
		return fmt.Errorf("Error uploading file to Slack: %s", err)
	}

	err = api.FilesUpload(&slack.FilesUploadOpt{
		Filepath: tmpPath,
		Filename: fileName,
		Title:    fileName,
		Channels: []string{channel.Id},
	})
	if err != nil {
		return fmt.Errorf("Error uploading file to Slack: %s", err)
	}

	return nil
}

func main() {
	app := cli.NewApp()
	app.Name = "slackcat"
	app.Usage = "redirect a file to slack"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "channel, c",
			Usage: "Slack channel to post to",
		},
	}

	app.Action = func(c *cli.Context) {
		if c.String("channel") == "" {
			panic(fmt.Errorf("no channel provided!"))
		}

		token, err := readConfig()
		if err != nil {
			panic(err)
		}

		tmpPath := readIn()
		fileName := strconv.FormatInt(time.Now().Unix(), 10)

		err = postToSlack(token, tmpPath.Name(), fileName, c.String("channel"))
		if err != nil {
			fmt.Println(err)
			os.Exit(1)
		}

		os.Remove(tmpPath.Name())

	}

	app.Run(os.Args)

}
<|endoftext|>


<commit_before>package prometheus

import (
	"context"
	"fmt"
	"sync"

	"github.com/asim/go-micro/v3/client"
	"github.com/asim/go-micro/v3/logger"
	"github.com/asim/go-micro/v3/registry"
	"github.com/asim/go-micro/v3/server"
	"github.com/prometheus/client_golang/prometheus"
)

var (
	// default metric prefix
	DefaultMetricPrefix = "micro_"
	// default label prefix
	DefaultLabelPrefix = "micro_"

	opsCounter           *prometheus.CounterVec
	timeCounterSummary   *prometheus.SummaryVec
	timeCounterHistogram *prometheus.HistogramVec

	mu sync.Mutex
)

type Options struct {
	Name    string
	Version string
	ID      string
}

type Option func(*Options)

func ServiceName(name string) Option {
	return func(opts *Options) {
		opts.Name = name
	}
}

func ServiceVersion(version string) Option {
	return func(opts *Options) {
		opts.Version = version
	}
}

func ServiceID(id string) Option {
	return func(opts *Options) {
		opts.ID = id
	}
}

func registerMetrics() {
	mu.Lock()
	defer mu.Unlock()

	if opsCounter == nil {
		opsCounter = prometheus.NewCounterVec(
			prometheus.CounterOpts{
				Name: fmt.Sprintf("%srequest_total", DefaultMetricPrefix),
				Help: "Requests processed, partitioned by endpoint and status",
			},
			[]string{
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "name"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "version"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "id"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "endpoint"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "status"),
			},
		)
	}

	if timeCounterSummary == nil {
		timeCounterSummary = prometheus.NewSummaryVec(
			prometheus.SummaryOpts{
				Name: fmt.Sprintf("%slatency_microseconds", DefaultMetricPrefix),
				Help: "Request latencies in microseconds, partitioned by endpoint",
			},
			[]string{
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "name"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "version"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "id"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "endpoint"),
			},
		)
	}

	if timeCounterHistogram == nil {
		timeCounterHistogram = prometheus.NewHistogramVec(
			prometheus.HistogramOpts{
				Name: fmt.Sprintf("%srequest_duration_seconds", DefaultMetricPrefix),
				Help: "Request time in seconds, partitioned by endpoint",
			},
			[]string{
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "name"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "version"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "id"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "endpoint"),
			},
		)
	}

	for _, collector := range []prometheus.Collector{opsCounter, timeCounterSummary, timeCounterHistogram} {
		if err := prometheus.DefaultRegisterer.Register(collector); err != nil {
			// if already registered, skip fatal
			if _, ok := err.(prometheus.AlreadyRegisteredError); !ok {
				logger.Fatal(err)
			}
		}
	}

}

type wrapper struct {
	options  Options
	callFunc client.CallFunc
	client.Client
}

func NewClientWrapper(opts ...Option) client.Wrapper {
	registerMetrics()

	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	return func(c client.Client) client.Client {
		handler := &wrapper{
			options: options,
			Client:  c,
		}

		return handler
	}
}

func NewCallWrapper(opts ...Option) client.CallWrapper {
	registerMetrics()

	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	return func(fn client.CallFunc) client.CallFunc {
		handler := &wrapper{
			options:  options,
			callFunc: fn,
		}

		return handler.CallFunc
	}
}

func (w *wrapper) CallFunc(ctx context.Context, node *registry.Node, req client.Request, rsp interface{}, opts client.CallOptions) error {
	endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	err := w.callFunc(ctx, node, req, rsp, opts)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return err

}

func (w *wrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	err := w.Client.Call(ctx, req, rsp, opts...)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return err
}

func (w *wrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) {
	endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	stream, err := w.Client.Stream(ctx, req, opts...)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return stream, err
}

func (w *wrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error {
	endpoint := p.Topic()

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	err := w.Client.Publish(ctx, p, opts...)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return err
}

func NewHandlerWrapper(opts ...Option) server.HandlerWrapper {
	registerMetrics()

	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	handler := &wrapper{
		options: options,
	}

	return handler.HandlerFunc
}

func (w *wrapper) HandlerFunc(fn server.HandlerFunc) server.HandlerFunc {
	return func(ctx context.Context, req server.Request, rsp interface{}) error {
		endpoint := req.Endpoint()

		timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
			us := v * 1000000 // make microseconds
			timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
			timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
		}))
		defer timer.ObserveDuration()

		err := fn(ctx, req, rsp)
		if err == nil {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
		} else {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
		}

		return err
	}
}

func NewSubscriberWrapper(opts ...Option) server.SubscriberWrapper {
	registerMetrics()

	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	handler := &wrapper{
		options: options,
	}

	return handler.SubscriberFunc
}

func (w *wrapper) SubscriberFunc(fn server.SubscriberFunc) server.SubscriberFunc {
	return func(ctx context.Context, msg server.Message) error {
		endpoint := msg.Topic()

		timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
			us := v * 1000000 // make microseconds
			timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
			timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
		}))
		defer timer.ObserveDuration()

		err := fn(ctx, msg)
		if err == nil {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
		} else {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
		}

		return err
	}
}
<commit_msg>Optimize prometheus wrapper,removed mutex,initialize MetricVec at init() (#2192)<commit_after>package prometheus

import (
	"context"
	"fmt"
	"github.com/asim/go-micro/v3/client"
	"github.com/asim/go-micro/v3/logger"
	"github.com/asim/go-micro/v3/registry"
	"github.com/asim/go-micro/v3/server"
	"github.com/prometheus/client_golang/prometheus"
)

var (
	// default metric prefix
	DefaultMetricPrefix = "micro_"
	// default label prefix
	DefaultLabelPrefix = "micro_"

	opsCounter           *prometheus.CounterVec
	timeCounterSummary   *prometheus.SummaryVec
	timeCounterHistogram *prometheus.HistogramVec
)

type Options struct {
	Name    string
	Version string
	ID      string
}

type Option func(*Options)

func ServiceName(name string) Option {
	return func(opts *Options) {
		opts.Name = name
	}
}

func ServiceVersion(version string) Option {
	return func(opts *Options) {
		opts.Version = version
	}
}

func ServiceID(id string) Option {
	return func(opts *Options) {
		opts.ID = id
	}
}

func init() {

	if opsCounter == nil {
		opsCounter = prometheus.NewCounterVec(
			prometheus.CounterOpts{
				Name: fmt.Sprintf("%srequest_total", DefaultMetricPrefix),
				Help: "Requests processed, partitioned by endpoint and status",
			},
			[]string{
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "name"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "version"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "id"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "endpoint"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "status"),
			},
		)
	}

	if timeCounterSummary == nil {
		timeCounterSummary = prometheus.NewSummaryVec(
			prometheus.SummaryOpts{
				Name: fmt.Sprintf("%slatency_microseconds", DefaultMetricPrefix),
				Help: "Request latencies in microseconds, partitioned by endpoint",
			},
			[]string{
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "name"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "version"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "id"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "endpoint"),
			},
		)
	}

	if timeCounterHistogram == nil {
		timeCounterHistogram = prometheus.NewHistogramVec(
			prometheus.HistogramOpts{
				Name: fmt.Sprintf("%srequest_duration_seconds", DefaultMetricPrefix),
				Help: "Request time in seconds, partitioned by endpoint",
			},
			[]string{
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "name"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "version"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "id"),
				fmt.Sprintf("%s%s", DefaultLabelPrefix, "endpoint"),
			},
		)
	}

	for _, collector := range []prometheus.Collector{opsCounter, timeCounterSummary, timeCounterHistogram} {
		if err := prometheus.DefaultRegisterer.Register(collector); err != nil {
			// if already registered, skip fatal
			if _, ok := err.(prometheus.AlreadyRegisteredError); !ok {
				logger.Fatal(err)
			}
		}
	}

}

type wrapper struct {
	options  Options
	callFunc client.CallFunc
	client.Client
}

func NewClientWrapper(opts ...Option) client.Wrapper {

	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	return func(c client.Client) client.Client {
		handler := &wrapper{
			options: options,
			Client:  c,
		}

		return handler
	}
}

func NewCallWrapper(opts ...Option) client.CallWrapper {
	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	return func(fn client.CallFunc) client.CallFunc {
		handler := &wrapper{
			options:  options,
			callFunc: fn,
		}

		return handler.CallFunc
	}
}

func (w *wrapper) CallFunc(ctx context.Context, node *registry.Node, req client.Request, rsp interface{}, opts client.CallOptions) error {
	endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	err := w.callFunc(ctx, node, req, rsp, opts)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return err

}

func (w *wrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	err := w.Client.Call(ctx, req, rsp, opts...)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return err
}

func (w *wrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) {
	endpoint := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint())

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	stream, err := w.Client.Stream(ctx, req, opts...)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return stream, err
}

func (w *wrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error {
	endpoint := p.Topic()

	timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
		us := v * 1000000 // make microseconds
		timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
		timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
	}))
	defer timer.ObserveDuration()

	err := w.Client.Publish(ctx, p, opts...)
	if err == nil {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
	} else {
		opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
	}

	return err
}

func NewHandlerWrapper(opts ...Option) server.HandlerWrapper {
	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	handler := &wrapper{
		options: options,
	}

	return handler.HandlerFunc
}

func (w *wrapper) HandlerFunc(fn server.HandlerFunc) server.HandlerFunc {
	return func(ctx context.Context, req server.Request, rsp interface{}) error {
		endpoint := req.Endpoint()

		timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
			us := v * 1000000 // make microseconds
			timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
			timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
		}))
		defer timer.ObserveDuration()

		err := fn(ctx, req, rsp)
		if err == nil {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
		} else {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
		}

		return err
	}
}

func NewSubscriberWrapper(opts ...Option) server.SubscriberWrapper {
	options := Options{}
	for _, opt := range opts {
		opt(&options)
	}

	handler := &wrapper{
		options: options,
	}

	return handler.SubscriberFunc
}

func (w *wrapper) SubscriberFunc(fn server.SubscriberFunc) server.SubscriberFunc {
	return func(ctx context.Context, msg server.Message) error {
		endpoint := msg.Topic()

		timer := prometheus.NewTimer(prometheus.ObserverFunc(func(v float64) {
			us := v * 1000000 // make microseconds
			timeCounterSummary.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(us)
			timeCounterHistogram.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint).Observe(v)
		}))
		defer timer.ObserveDuration()

		err := fn(ctx, msg)
		if err == nil {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "success").Inc()
		} else {
			opsCounter.WithLabelValues(w.options.Name, w.options.Version, w.options.ID, endpoint, "failure").Inc()
		}

		return err
	}
}
<|endoftext|>


<commit_before>package main

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

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

type SimpleChaincode struct {
}

func main() {
	err := shim.Start(new(SimpleChaincode))

	if err != nil {
		//do nothing
	}
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	// added by chenlin@20170308
	if len(args) != 0 {
		return nil, errors.New("incorrect args")
	}
	// adminCert, err := stub.GetCallerMetadata()
	// if err != nil {
	// 	return nil, errors.New("failed getting metadata")
	// }
	// if len(adminCert) == 0 {
	// 	return nil, errors.New("invalid admin certificate. Empty")
	// }
	stub.PutState("admin", []byte("hahahahaha"))
	err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{
		&shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true},
		&shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_STRING, Key: false},
	})
	if err != nil {
		return nil, errors.New("Failed creating AssetsOnwership table.")
	}
	return nil, nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	switch function {
	case "putState":
		if len(args) != 2 {
			return nil, errors.New("incorrect args")
		}
		key := args[0]
		value := []byte(args[1])
		err := stub.PutState(key, value)
		if err != nil {
			return nil, err
		}
		return value, err
	case "delState":
		if len(args) != 1 {
			return nil, errors.New("incorrect args")
		}
		key := args[0]
		err := stub.DelState(key)
		if err != nil {
			return nil, err
		}
		result := key + "has been deleted"
		return []byte(result), err

	case "createTable":
		err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{
			&shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true},
			&shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_STRING, Key: false},
		})
		if err != nil {
			return nil, errors.New("Failed creating AssetsOnwership table.")
		}
		return nil, nil

	case "insertTable":
		if len(args) != 2 {
			return nil, errors.New("incorrect args")
		}
		asset := args[0]
		owner := args[1]
		row := shim.Row{
			Columns: []*shim.Column{
				&shim.Column{Value: &shim.Column_String_{String_: asset}},
				&shim.Column{Value: &shim.Column_String_{String_: owner}}}}
		ok, err := stub.InsertRow("AssetsOwnership", row)
		if !ok && err == nil {
			return nil, errors.New("asset was already assigned")
		}
		return nil, nil //end of insertTable

	}
	return nil, nil
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	switch function {
	case "getTxID":
		txID := stub.GetTxID()
		result := []byte(txID)
		return result, nil
	case "getTxTimestamp":
		time, err := stub.GetTxTimestamp()
		result := []byte(time.String()) //时间转换为字符串，time.String()
		return result, err
	case "getStringArgs":
		strList := stub.GetStringArgs()
		var result string
		for index := 0; index < len(strList); index++ {
			result += "***" + strList[index] + "***"
		}
		return []byte(result), nil

	case "getState":
		if len(args) != 1 {
			return nil, errors.New("incorrect args")
		}
		key := args[0]
		result, err := stub.GetState(key)

		if err != nil {
			return nil, errors.New("Failed in function getState")
		}
		return result, err

	case "getCallerCert":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetCallerCertificate()
		if err != nil {
			return nil, errors.New("Failed in function getCallerCert")
		}
		return result, err

	case "getCallerMetadata":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetCallerMetadata()
		if err != nil {
			return nil, errors.New("Failed in function getCallerMetadata")
		}
		fmt.Println(result)
		return result, err
		// return []byte("getCallerMetadata"), err
	case "getBinding":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetBinding()

		if err != nil {
			return nil, errors.New("Failed in function getBinding")
		}
		fmt.Println(result)
		return result, err
		// return []byte("getBinding"), err
	case "getPayload":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetPayload()

		if err != nil {
			return nil, errors.New("Failed in function getPayload")
		}
		fmt.Println(result)
		return result, err
	// return []byte("getPayload"), err
	case "getRow":
		fmt.Println("*********************")
		fmt.Println("*********************")
		fmt.Println("*********************")
		if len(args) != 1 {
			return nil, errors.New("incorrect args")
		}
		asset := args[0]
		var columns []shim.Column
		col1 := shim.Column{Value: &shim.Column_String_{String_: asset}}
		columns = append(columns, col1)

		row, err := stub.GetRow("AssetsOwnership", columns)
		if err != nil {
			return nil, errors.New("failed in function getRow")
		}

		val0 := row.Columns[0].GetString_()
		val1 := row.Columns[1].GetString_()
		result := "****" + val0 + "****" + val1
		return []byte(result), err
	//end of "getRow"

	case "getRowDefinition":
		if len(args) != 2 {
			return nil, errors.New("incorrect args")
		}
		asset := args[0]
		owner := args[1]

		col0 := shim.Column{Value: &shim.Column_String_{String_: asset}} //col0，type=shim.column
		col1 := shim.Column{Value: &shim.Column_String_{String_: owner}} //col1, type=shim.column
		var columns []shim.Column                                        //define columns=[]shim.column
		columns = append(columns, col0)
		columns = append(columns, col1) //完成columns的赋值

		val0 := columns[0].GetString_()
		val1 := columns[1].GetString_()
		result := val0 + "****" + val1
		return []byte(result), nil

	case "getRows":
		var columns []shim.Column
		col0 := shim.Column{
			Value: &shim.Column_String_{},
		}
		columns = append(columns, col0)

		rowChannel, err := stub.GetRows("AssetsOwnership", columns)
		var rows []shim.Row
		for {
			select {
			case row, ok := <-rowChannel:
				if !ok {
					rowChannel = nil
				} else {
					rows = append(rows, row)
				}
			}
			if rowChannel == nil {
				break
			}
		}
		jsonRows, err := json.Marshal(rows)
		if err != nil {
			return nil, fmt.Errorf("getRowsTableTwo operation failed. Error marshaling JSON: %s", err)
		}
		return jsonRows, nil //end of function getRows()
	}

	return nil, nil
}
<commit_msg>fix bugs<commit_after>package main

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

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

type SimpleChaincode struct {
}

func main() {
	err := shim.Start(new(SimpleChaincode))

	if err != nil {
		//do nothing
	}
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	// added by chenlin@20170308
	if len(args) != 0 {
		return nil, errors.New("incorrect args")
	}
	// adminCert, err := stub.GetCallerMetadata()
	// if err != nil {
	// 	return nil, errors.New("failed getting metadata")
	// }
	// if len(adminCert) == 0 {
	// 	return nil, errors.New("invalid admin certificate. Empty")
	// }
	stub.PutState("admin", []byte("hahahahaha"))
	err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{
		&shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true},
		&shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_STRING, Key: false},
	})
	if err != nil {
		return nil, errors.New("Failed creating AssetsOnwership table.")
	}
	return nil, nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	switch function {
	case "putState":
		if len(args) != 2 {
			return nil, errors.New("incorrect args")
		}
		key := args[0]
		value := []byte(args[1])
		err := stub.PutState(key, value)
		if err != nil {
			return nil, err
		}
		return value, err
	case "delState":
		if len(args) != 1 {
			return nil, errors.New("incorrect args")
		}
		key := args[0]
		err := stub.DelState(key)
		if err != nil {
			return nil, err
		}
		result := key + "has been deleted"
		return []byte(result), err

	case "createTable":
		err := stub.CreateTable("AssetsOwnership", []*shim.ColumnDefinition{
			&shim.ColumnDefinition{Name: "Asset", Type: shim.ColumnDefinition_STRING, Key: true},
			&shim.ColumnDefinition{Name: "Owner", Type: shim.ColumnDefinition_STRING, Key: false},
		})
		if err != nil {
			return nil, errors.New("Failed creating AssetsOnwership table.")
		}
		return nil, nil

	case "insertTable":
		if len(args) != 2 {
			return nil, errors.New("incorrect args")
		}
		asset := args[0]
		owner := args[1]
		row := shim.Row{
			Columns: []*shim.Column{
				&shim.Column{Value: &shim.Column_String_{String_: asset}},
				&shim.Column{Value: &shim.Column_String_{String_: owner}}}}
		ok, err := stub.InsertRow("AssetsOwnership", row)
		if !ok && err == nil {
			return nil, errors.New("asset was already assigned")
		}
		return nil, nil //end of insertTable

	}
	return nil, nil
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	switch function {
	case "getTxID":
		txID := stub.GetTxID()
		result := []byte(txID)
		return result, nil
	case "getTxTimestamp":
		time, err := stub.GetTxTimestamp()
		result := []byte(time.String()) //时间转换为字符串，time.String()
		return result, err
	case "getStringArgs":
		strList := stub.GetStringArgs()
		var result string
		for index := 0; index < len(strList); index++ {
			result += "***" + strList[index] + "***"
		}
		return []byte(result), nil

	case "getState":
		if len(args) != 1 {
			return nil, errors.New("incorrect args")
		}
		key := args[0]
		result, err := stub.GetState(key)

		if err != nil {
			return nil, errors.New("Failed in function getState")
		}
		return result, err

	case "getCallerCert":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetCallerCertificate()
		if err != nil {
			return nil, errors.New("Failed in function getCallerCert")
		}
		return result, err

	case "getCallerMetadata":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetCallerMetadata()
		if err != nil {
			return nil, errors.New("Failed in function getCallerMetadata")
		}
		fmt.Println(result)
		return result, err
		// return []byte("getCallerMetadata"), err
	case "getBinding":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetBinding()

		if err != nil {
			return nil, errors.New("Failed in function getBinding")
		}
		fmt.Println(result)
		return result, err
		// return []byte("getBinding"), err
	case "getPayload":
		if len(args) != 0 {
			return nil, errors.New("incorrect args")
		}
		result, err := stub.GetPayload()

		if err != nil {
			return nil, errors.New("Failed in function getPayload")
		}
		fmt.Println(result)
		return result, err
	// return []byte("getPayload"), err
	case "getRow":
		fmt.Println("*********************")
		fmt.Println("*********************")
		fmt.Println("*********************")
		if len(args) != 1 {
			return nil, errors.New("incorrect args")
		}
		asset := args[0]
		var columns []shim.Column
		col1 := shim.Column{Value: &shim.Column_String_{String_: asset}}
		columns = append(columns, col1)

		row, err := stub.GetRow("AssetsOwnership", columns)
		if err != nil {
			return nil, errors.New("failed in function getRow")
		}

		val0 := row.Columns[0].GetString_()
		val1 := row.Columns[1].GetString_()
		result := "****" + val0 + "****" + val1
		return []byte(result), err
	//end of "getRow"

	case "getRowDefinition":
		if len(args) != 2 {
			return nil, errors.New("incorrect args")
		}
		asset := args[0]
		owner := args[1]

		col0 := shim.Column{Value: &shim.Column_String_{String_: asset}} //col0，type=shim.column
		col1 := shim.Column{Value: &shim.Column_String_{String_: owner}} //col1, type=shim.column
		var columns []shim.Column                                        //define columns=[]shim.column
		columns = append(columns, col0)
		columns = append(columns, col1) //完成columns的赋值

		val0 := columns[0].GetString_()
		val1 := columns[1].GetString_()
		result := val0 + "****" + val1
		return []byte(result), nil

	case "getRows":
		if len(args) != 1 {
			return nil, errors.New("incorrect args")
		}
		asset := args[0]
		var columns []shim.Column
		col0 := shim.Column{
			Value: &shim.Column_String_{String_: asset},
		}
		columns = append(columns, col0)

		rowChannel, err := stub.GetRows("AssetsOwnership", columns)
		var rows []shim.Row
		for {
			select {
			case row, ok := <-rowChannel:
				if !ok {
					rowChannel = nil
				} else {
					rows = append(rows, row)
				}
			}
			if rowChannel == nil {
				break
			}
		}
		jsonRows, err := json.Marshal(rows)
		if err != nil {
			return nil, fmt.Errorf("getRowsTableTwo operation failed. Error marshaling JSON: %s", err)
		}
		return jsonRows, nil //end of function getRows()
	}

	return nil, nil
}
<|endoftext|>


<commit_before>package common

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"strconv"
	"strings"
)

//-------------------------------------------------------
// hex and ints

// keeps N bytes of the conversion
func NumberToBytes(num interface{}, N int) []byte {
	buf := new(bytes.Buffer)
	err := binary.Write(buf, binary.BigEndian, num)
	if err != nil {
		// TODO: get this guy a return error?
	}
	//fmt.Println("btyes!", buf.Bytes())
	if buf.Len() > N {
		return buf.Bytes()[buf.Len()-N:]
	}
	return buf.Bytes()
}

// s can be string, hex, or int.
// returns properly formatted 32byte hex value
func Coerce2Hex(s string) string {
	//fmt.Println("coercing to hex:", s)
	// is int?
	i, err := strconv.Atoi(s)
	if err == nil {
		return "0x" + hex.EncodeToString(NumberToBytes(int32(i), i/256+1))
	}
	// is already prefixed hex?
	if len(s) > 1 && s[:2] == "0x" {
		if len(s)%2 == 0 {
			return s
		}
		return "0x0" + s[2:]
	}
	// is unprefixed hex?
	if len(s) > 32 {
		return "0x" + s
	}
	pad := strings.Repeat("\x00", (32-len(s))) + s
	ret := "0x" + hex.EncodeToString([]byte(pad))
	//fmt.Println("result:", ret)
	return ret
}

func IsHex(s string) bool {
	if len(s) < 2 {
		return false
	}
	if s[:2] == "0x" {
		return true
	}
	return false
}

func AddHex(s string) string {
	if len(s) < 2 {
		return "0x" + s
	}

	if s[:2] != "0x" {
		return "0x" + s
	}

	return s
}

func StripHex(s string) string {
	if len(s) > 1 {
		if s[:2] == "0x" {
			s = s[2:]
			if len(s)%2 != 0 {
				s = "0" + s
			}
			return s
		}
	}
	return s
}

func StripZeros(s string) string {
	i := 0
	for ; i < len(s); i++ {
		if s[i] != '0' {
			break
		}
	}
	return s[i:]
}

func Bytes2Hex(d []byte) string {
	return hex.EncodeToString(d)
}

func RightPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[0:len(slice)], slice)

	return padded
}

func LeftPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[l-len(slice):], slice)

	return padded
}

func LeftPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return zeros + str

}

func RightPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return str + zeros

}
<commit_msg>add coerce and pad function from ABI into common<commit_after>package common

import (
	"bytes"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"strconv"
	"strings"
)

//-------------------------------------------------------
// hex and ints

// keeps N bytes of the conversion
func NumberToBytes(num interface{}, N int) []byte {
	buf := new(bytes.Buffer)
	err := binary.Write(buf, binary.BigEndian, num)
	if err != nil {
		// TODO: get this guy a return error?
	}
	//fmt.Println("btyes!", buf.Bytes())
	if buf.Len() > N {
		return buf.Bytes()[buf.Len()-N:]
	}
	return buf.Bytes()
}

// s can be string, hex, or int.
// returns properly formatted 32byte hex value
func Coerce2Hex(s string) string {
	//fmt.Println("coercing to hex:", s)
	// is int?
	i, err := strconv.Atoi(s)
	if err == nil {
		return "0x" + hex.EncodeToString(NumberToBytes(int32(i), i/256+1))
	}
	// is already prefixed hex?
	if len(s) > 1 && s[:2] == "0x" {
		if len(s)%2 == 0 {
			return s
		}
		return "0x0" + s[2:]
	}
	// is unprefixed hex?
	if len(s) > 32 {
		return "0x" + s
	}
	pad := strings.Repeat("\x00", (32-len(s))) + s
	ret := "0x" + hex.EncodeToString([]byte(pad))
	//fmt.Println("result:", ret)
	return ret
}

func CoerceHexAndPad(aa string, padright bool) string {
	if !IsHex(aa) {
		//first try and convert to int
		n, err := strconv.Atoi(aa)
		if err != nil {
			// right pad strings
			if padright {
				aa = "0x" + fmt.Sprintf("%x", aa) + fmt.Sprintf("%0"+strconv.Itoa(64-len(aa)*2)+"s", "")
			} else {
				aa = "0x" + fmt.Sprintf("%x", aa)
			}
		} else {
			aa = "0x" + fmt.Sprintf("%x", n)
		}
	}
	return aa
}

func IsHex(s string) bool {
	if len(s) < 2 {
		return false
	}
	if s[:2] == "0x" {
		return true
	}
	return false
}

func AddHex(s string) string {
	if len(s) < 2 {
		return "0x" + s
	}

	if s[:2] != "0x" {
		return "0x" + s
	}

	return s
}

func StripHex(s string) string {
	if len(s) > 1 {
		if s[:2] == "0x" {
			s = s[2:]
			if len(s)%2 != 0 {
				s = "0" + s
			}
			return s
		}
	}
	return s
}

func StripZeros(s string) string {
	i := 0
	for ; i < len(s); i++ {
		if s[i] != '0' {
			break
		}
	}
	return s[i:]
}

func Bytes2Hex(d []byte) string {
	return hex.EncodeToString(d)
}

func RightPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[0:len(slice)], slice)

	return padded
}

func LeftPadBytes(slice []byte, l int) []byte {
	if l < len(slice) {
		return slice
	}

	padded := make([]byte, l)
	copy(padded[l-len(slice):], slice)

	return padded
}

func LeftPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return zeros + str

}

func RightPadString(str string, l int) string {
	if l < len(str) {
		return str
	}

	zeros := Bytes2Hex(make([]byte, (l-len(str))/2))

	return str + zeros

}
<|endoftext|>