<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"time"
)

const SUCCESS_EXIT int = 0
const ERROR_EXIT int = 1
const LIMIT_WAIT_COUNT int = 540 // 20sec * 540 = 3 hours
const API_SERVER string = "https://api.vaddy.net"

type StartScan struct {
	ScanID string `json:"scan_id"`
}

type ScanResult struct {
	Status        string `json:"status"`
	AlertCount    int    `json:"alert_count"`
	ScanResultUrl string `json:"scan_result_url"`
}

func main() {
	fmt.Println("==== Start VAddy Scan ====")

	var auth_key, user, fqdn, crawl string = getApiParamsFromArgsOrEnv()

	scan_id := startScan(auth_key, user, fqdn, crawl)

	var wait_count int = 0
	for {
		checkScanResult(auth_key, user, fqdn, scan_id)

		time.Sleep(20 * time.Second) //wait 20 second
		wait_count++
		if wait_count > LIMIT_WAIT_COUNT {
			fmt.Println("Error: time out")
			os.Exit(ERROR_EXIT)
		}
	}
}

func getApiParamsFromArgsOrEnv() (string, string, string, string) {
	var auth_key, user, fqdn, crawl string
	if len(os.Args) < 4 {
		return getArgsFromEnv()
	}

	auth_key = os.Args[1]
	user = os.Args[2]
	fqdn = os.Args[3]
	if len(os.Args) >= 5 {
		crawl = os.Args[4]
	}
	return auth_key, user, fqdn, crawl
}

func getArgsFromEnv() (string, string, string, string) {
	var auth_key, user, fqdn, crawl string
	auth_key, ok1 := os.LookupEnv("VADDY_TOKEN")
	user, ok2 := os.LookupEnv("VADDY_USER")
	fqdn, ok3 := os.LookupEnv("VADDY_HOST")
	crawl, _ = os.LookupEnv("VADDY_CRAWL")

	if !ok1 || !ok2 || !ok3 {
		fmt.Println("Missing arguments or system env.")
		fmt.Println("USAGE: vaddy ApiKey UserId FQDN CrawlID(optional)")
		os.Exit(ERROR_EXIT)
	}
	return auth_key, user, fqdn, crawl
}

func startScan(auth_key string, user string, fqdn string, crawl string) string {
	values := url.Values{}
	values.Add("auth_key", auth_key)
	values.Add("user", user)
	values.Add("fqdn", fqdn)
	values.Add("action", "start")
	if len(crawl) > 0 {
		values.Add("crawl_id", crawl)
	}

	apiServer := getApiServerName()
	res, err := http.PostForm(apiServer+"/v1/scan", values)
	if err != nil {
		fmt.Println(err)
		os.Exit(ERROR_EXIT)
	}
	defer res.Body.Close()
	json_response := getResponseData(res)
	scanId := getScanId(json_response)
	//fmt.Println("scanId: " + scanId)
	return scanId
}

func getScanResult(auth_key string, user string, fqdn string, scan_id string) []byte {
	values := url.Values{}
	values.Add("auth_key", auth_key)
	values.Add("user", user)
	values.Add("fqdn", fqdn)
	values.Add("scan_id", scan_id)

	apiServer := getApiServerName()
	res, err := http.Get(apiServer + "/v1/scan/result?" + values.Encode())
	if err != nil {
		fmt.Println(err)
		os.Exit(ERROR_EXIT)
	}
	defer res.Body.Close()

	json_response := getResponseData(res)
	return json_response
}

func checkScanResult(auth_key string, user string, fqdn string, scan_id string) {
	json_response := getScanResult(auth_key, user, fqdn, scan_id)

	var scan_result ScanResult
	convertJsonToStruct(json_response, &scan_result)

	status := scan_result.Status
	switch status {
	case "scanning":
		fmt.Println(scan_result.Status)
	case "canceled":
		fmt.Println(scan_result.Status)
		os.Exit(ERROR_EXIT)
	case "finish":
		//fmt.Println(string(json_response) + "\n")
		fmt.Println("Server: " + fqdn)
		fmt.Println("scanId: " + scan_id)
		fmt.Println("Result URL: " + scan_result.ScanResultUrl)

		if scan_result.AlertCount > 0 {
			fmt.Print("Vulnerabilities: ")
			fmt.Println(scan_result.AlertCount)
			fmt.Println("Warning!!!")
			os.Exit(ERROR_EXIT)
		} else {
			fmt.Println("Scan Success. No vulnerabilities!")
			os.Exit(SUCCESS_EXIT)
		}
	}
}

func getResponseData(resp *http.Response) []byte {
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(string(body))
		os.Exit(ERROR_EXIT)
	}
	status_code := resp.StatusCode
	//fmt.Println(status_code)
	if status_code != 200 {
		fmt.Println("Network/Auth error\n" + string(body))
		os.Exit(ERROR_EXIT)
	}
	return []byte(body)
}

func getScanId(jsonByteData []byte) string {
	var scan_result StartScan
	convertJsonToStruct(jsonByteData, &scan_result)
	return scan_result.ScanID
}

func convertJsonToStruct(jsonByteData []byte, structData interface{}) {
	err := json.Unmarshal(jsonByteData, structData)
	if err != nil {
		fmt.Println(err)
		os.Exit(ERROR_EXIT)
	}
}

func getApiServerName() string {
	apiserver, ok := os.LookupEnv("VADDY_API_SERVER")
	if ok {
		return apiserver
	}
	return API_SERVER
}
<commit_msg>set version num<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"time"
)
const VERSION string = "1.0.0"
const SUCCESS_EXIT int = 0
const ERROR_EXIT int = 1
const LIMIT_WAIT_COUNT int = 540 // 20sec * 540 = 3 hours
const API_SERVER string = "https://api.vaddy.net"

type StartScan struct {
	ScanID string `json:"scan_id"`
}

type ScanResult struct {
	Status        string `json:"status"`
	AlertCount    int    `json:"alert_count"`
	ScanResultUrl string `json:"scan_result_url"`
}

func main() {
	fmt.Println("==== Start VAddy Scan (Version " + VERSION + ")====")

	var auth_key, user, fqdn, crawl string = getApiParamsFromArgsOrEnv()

	scan_id := startScan(auth_key, user, fqdn, crawl)

	var wait_count int = 0
	for {
		checkScanResult(auth_key, user, fqdn, scan_id)

		time.Sleep(20 * time.Second) //wait 20 second
		wait_count++
		if wait_count > LIMIT_WAIT_COUNT {
			fmt.Println("Error: time out")
			os.Exit(ERROR_EXIT)
		}
	}
}

func getApiParamsFromArgsOrEnv() (string, string, string, string) {
	var auth_key, user, fqdn, crawl string
	if len(os.Args) < 4 {
		return getArgsFromEnv()
	}

	auth_key = os.Args[1]
	user = os.Args[2]
	fqdn = os.Args[3]
	if len(os.Args) >= 5 {
		crawl = os.Args[4]
	}
	return auth_key, user, fqdn, crawl
}

func getArgsFromEnv() (string, string, string, string) {
	var auth_key, user, fqdn, crawl string
	auth_key, ok1 := os.LookupEnv("VADDY_TOKEN")
	user, ok2 := os.LookupEnv("VADDY_USER")
	fqdn, ok3 := os.LookupEnv("VADDY_HOST")
	crawl, _ = os.LookupEnv("VADDY_CRAWL")

	if !ok1 || !ok2 || !ok3 {
		fmt.Println("Missing arguments or system env.")
		fmt.Println("USAGE: vaddy ApiKey UserId FQDN CrawlID(optional)")
		os.Exit(ERROR_EXIT)
	}
	return auth_key, user, fqdn, crawl
}

func startScan(auth_key string, user string, fqdn string, crawl string) string {
	values := url.Values{}
	values.Add("auth_key", auth_key)
	values.Add("user", user)
	values.Add("fqdn", fqdn)
	values.Add("action", "start")
	if len(crawl) > 0 {
		values.Add("crawl_id", crawl)
	}

	apiServer := getApiServerName()
	res, err := http.PostForm(apiServer+"/v1/scan", values)
	if err != nil {
		fmt.Println(err)
		os.Exit(ERROR_EXIT)
	}
	defer res.Body.Close()
	json_response := getResponseData(res)
	scanId := getScanId(json_response)
	//fmt.Println("scanId: " + scanId)
	return scanId
}

func getScanResult(auth_key string, user string, fqdn string, scan_id string) []byte {
	values := url.Values{}
	values.Add("auth_key", auth_key)
	values.Add("user", user)
	values.Add("fqdn", fqdn)
	values.Add("scan_id", scan_id)

	apiServer := getApiServerName()
	res, err := http.Get(apiServer + "/v1/scan/result?" + values.Encode())
	if err != nil {
		fmt.Println(err)
		os.Exit(ERROR_EXIT)
	}
	defer res.Body.Close()

	json_response := getResponseData(res)
	return json_response
}

func checkScanResult(auth_key string, user string, fqdn string, scan_id string) {
	json_response := getScanResult(auth_key, user, fqdn, scan_id)

	var scan_result ScanResult
	convertJsonToStruct(json_response, &scan_result)

	status := scan_result.Status
	switch status {
	case "scanning":
		fmt.Println(scan_result.Status)
	case "canceled":
		fmt.Println(scan_result.Status)
		os.Exit(ERROR_EXIT)
	case "finish":
		//fmt.Println(string(json_response) + "\n")
		fmt.Println("Server: " + fqdn)
		fmt.Println("scanId: " + scan_id)
		fmt.Println("Result URL: " + scan_result.ScanResultUrl)

		if scan_result.AlertCount > 0 {
			fmt.Print("Vulnerabilities: ")
			fmt.Println(scan_result.AlertCount)
			fmt.Println("Warning!!!")
			os.Exit(ERROR_EXIT)
		} else {
			fmt.Println("Scan Success. No vulnerabilities!")
			os.Exit(SUCCESS_EXIT)
		}
	}
}

func getResponseData(resp *http.Response) []byte {
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(string(body))
		os.Exit(ERROR_EXIT)
	}
	status_code := resp.StatusCode
	//fmt.Println(status_code)
	if status_code != 200 {
		fmt.Println("Network/Auth error\n" + string(body))
		os.Exit(ERROR_EXIT)
	}
	return []byte(body)
}

func getScanId(jsonByteData []byte) string {
	var scan_result StartScan
	convertJsonToStruct(jsonByteData, &scan_result)
	return scan_result.ScanID
}

func convertJsonToStruct(jsonByteData []byte, structData interface{}) {
	err := json.Unmarshal(jsonByteData, structData)
	if err != nil {
		fmt.Println(err)
		os.Exit(ERROR_EXIT)
	}
}

func getApiServerName() string {
	apiserver, ok := os.LookupEnv("VADDY_API_SERVER")
	if ok {
		return apiserver
	}
	return API_SERVER
}
<|endoftext|>


<commit_before>package terminal

import (
	"os"
	"regexp"

	"github.com/fatih/color"
	"golang.org/x/crypto/ssh/terminal"
)

const (
	red            color.Attribute = color.FgRed
	green                          = color.FgGreen
	yellow                         = color.FgYellow
	magenta                        = color.FgMagenta
	cyan                           = color.FgCyan
	grey                           = color.FgWhite
	defaultFgColor                 = color.FgWhite
)

var (
	colorize               func(message string, textColor color.Attribute, bold int) string
	TerminalSupportsColors = isTerminal()
	UserAskedForColors     = ""
)

func init() {
	InitColorSupport()
}

func InitColorSupport() {
	if colorsEnabled() {
		colorize = func(message string, textColor color.Attribute, bold int) string {
			colorPrinter := color.New(textColor)
			if bold == 1 {
				colorPrinter = colorPrinter.Add(color.Bold)
			}
			f := colorPrinter.SprintFunc()
			return f(message)
		}
	} else {
		colorize = func(message string, _ color.Attribute, _ int) string {
			return message
		}
	}
}

func colorsEnabled() bool {
	if os.Getenv("CF_COLOR") == "true" {
		return true
	}

	if os.Getenv("CF_COLOR") == "false" {
		return false
	}

	if UserAskedForColors == "true" {
		return true
	}

	return UserAskedForColors != "false" && TerminalSupportsColors
}

func Colorize(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 0)
}

func ColorizeBold(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 1)
}

var decolorizerRegex = regexp.MustCompile(`\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]`)

func Decolorize(message string) string {
	return string(decolorizerRegex.ReplaceAll([]byte(message), []byte("")))
}

func HeaderColor(message string) string {
	return ColorizeBold(message, defaultFgColor)
}

func CommandColor(message string) string {
	return ColorizeBold(message, yellow)
}

func StoppedColor(message string) string {
	return ColorizeBold(message, grey)
}

func AdvisoryColor(message string) string {
	return ColorizeBold(message, yellow)
}

func CrashedColor(message string) string {
	return ColorizeBold(message, red)
}

func FailureColor(message string) string {
	return ColorizeBold(message, red)
}

func SuccessColor(message string) string {
	return ColorizeBold(message, green)
}

func EntityNameColor(message string) string {
	return ColorizeBold(message, cyan)
}

func PromptColor(message string) string {
	return ColorizeBold(message, cyan)
}

func TableContentHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func WarningColor(message string) string {
	return ColorizeBold(message, magenta)
}

func LogStdoutColor(message string) string {
	return Colorize(message, defaultFgColor)
}

func LogStderrColor(message string) string {
	return Colorize(message, red)
}

func LogHealthHeaderColor(message string) string {
	return Colorize(message, grey)
}

func LogAppHeaderColor(message string) string {
	return ColorizeBold(message, yellow)
}

func LogSysHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func isTerminal() bool {
	return terminal.IsTerminal(int(os.Stdout.Fd()))
}
<commit_msg>print standard log out without color<commit_after>package terminal

import (
	"os"
	"regexp"

	"github.com/fatih/color"
	"golang.org/x/crypto/ssh/terminal"
)

const (
	red            color.Attribute = color.FgRed
	green                          = color.FgGreen
	yellow                         = color.FgYellow
	magenta                        = color.FgMagenta
	cyan                           = color.FgCyan
	grey                           = color.FgWhite
	defaultFgColor                 = 38
)

var (
	colorize               func(message string, textColor color.Attribute, bold int) string
	TerminalSupportsColors = isTerminal()
	UserAskedForColors     = ""
)

func init() {
	InitColorSupport()
}

func InitColorSupport() {
	if colorsEnabled() {
		colorize = func(message string, textColor color.Attribute, bold int) string {
			colorPrinter := color.New(textColor)
			if bold == 1 {
				colorPrinter = colorPrinter.Add(color.Bold)
			}
			f := colorPrinter.SprintFunc()
			return f(message)
		}
	} else {
		colorize = func(message string, _ color.Attribute, _ int) string {
			return message
		}
	}
}

func colorsEnabled() bool {
	if os.Getenv("CF_COLOR") == "true" {
		return true
	}

	if os.Getenv("CF_COLOR") == "false" {
		return false
	}

	if UserAskedForColors == "true" {
		return true
	}

	return UserAskedForColors != "false" && TerminalSupportsColors
}

func Colorize(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 0)
}

func ColorizeBold(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 1)
}

var decolorizerRegex = regexp.MustCompile(`\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]`)

func Decolorize(message string) string {
	return string(decolorizerRegex.ReplaceAll([]byte(message), []byte("")))
}

func HeaderColor(message string) string {
	return ColorizeBold(message, defaultFgColor)
}

func CommandColor(message string) string {
	return ColorizeBold(message, yellow)
}

func StoppedColor(message string) string {
	return ColorizeBold(message, grey)
}

func AdvisoryColor(message string) string {
	return ColorizeBold(message, yellow)
}

func CrashedColor(message string) string {
	return ColorizeBold(message, red)
}

func FailureColor(message string) string {
	return ColorizeBold(message, red)
}

func SuccessColor(message string) string {
	return ColorizeBold(message, green)
}

func EntityNameColor(message string) string {
	return ColorizeBold(message, cyan)
}

func PromptColor(message string) string {
	return ColorizeBold(message, cyan)
}

func TableContentHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func WarningColor(message string) string {
	return ColorizeBold(message, magenta)
}

func LogStdoutColor(message string) string {
	return message
}

func LogStderrColor(message string) string {
	return Colorize(message, red)
}

func LogHealthHeaderColor(message string) string {
	return Colorize(message, grey)
}

func LogAppHeaderColor(message string) string {
	return ColorizeBold(message, yellow)
}

func LogSysHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func isTerminal() bool {
	return terminal.IsTerminal(int(os.Stdout.Fd()))
}
<|endoftext|>


<commit_before>/*package geom contains routines for computing geometric quantities.

Contains implementations of algorithms described in Platis & Theoharis, 2015
as well as Schneider & Eberly.

The calling signatures might be more convoluted than they have to be because
I was too worried about memory consumption when I started it. I should include
examples.
*/
package geom

import (
	"math"
)

// Vec is a three dimensional vector. (Duh!)
type Vec [3]float32

// PluckerVec represents a ray. If P and L are the position of the ray's
// origin and the unit vector representing its direction, respectively, then
// U = L and V = L cross P.
type PluckerVec struct {
	U, V Vec
}

// AnchoredPluckerVec is a Plucker vector which also saves the position of
// the ray's origin.
type AnchoredPluckerVec struct {
	PluckerVec
	P Vec
}

// Init initializes a Plucker vector given a ray origin, P, and a unit
// direction vector, L.
func (p *PluckerVec) Init(P, L *Vec) {
	p.U = *L

	p.V[0] = -P[1]*L[2] + P[2]*L[1]
    p.V[1] = -P[2]*L[0] + P[0]*L[2]
    p.V[2] = -P[0]*L[1] + P[1]*L[0]
}

// InitFromSegment initialized a Plucker vector which corresponds to a ray
// pointing from the position vector P1 to the position vector P2.
func (p *PluckerVec) InitFromSegment(P1, P2 *Vec) {
	var sum float32
	for i := 0; i < 3; i++ {
		p.U[i] = P2[i] - P1[i]
		sum += p.U[i]*p.U[i]
	}
	sum = float32(math.Sqrt(float64(sum)))
	//for i := 0; i < 3; i++ { p.U[i] /= sum }

	p.V[0] = -P1[1]*p.U[2] + P1[2]*p.U[1]
    p.V[1] = -P1[2]*p.U[0] + P1[0]*p.U[2]
    p.V[2] = -P1[0]*p.U[1] + P1[1]*p.U[0]
}

// Translate translates a Plucker vector along the given vector.
func (p *PluckerVec) Translate(dx *Vec) {
	p.V[0] += -dx[1]*p.U[2] + dx[2]*p.U[1]
    p.V[1] += -dx[2]*p.U[0] + dx[0]*p.U[2]
    p.V[2] += -dx[0]*p.U[1] + dx[1]*p.U[0]
}

// Dot computes the permuted inner product of p1 and p2, i.e.
// p1.U*p2.V + p1.V*p2.U.
func (p1 *PluckerVec) Dot(p2 *PluckerVec, flip bool) float32 {
	var sum float32
	for i := 0; i < 3; i++ {
		sum += p1.U[i]*p2.V[i] + p1.V[i]*p2.U[i]
	}
	if flip {
		return sum
	} else {
		return -sum
	}
}

// Dot computes the permuted inner product of p1 and p2, i.e.
// p1.U*p2.V + p1.V*p2.U and also returns a sign flag of -1, 0, or +1 if
// that product is negative, zero, or positive, respectively.
func (p1 *PluckerVec) SignDot(p2 *PluckerVec, flip bool) (float32, int) {
	dot := p1.Dot(p2, flip)
	if dot == 0 {
		return dot, 0
	} else if dot > 0 {
		return dot, +1
	} else {
		return dot, -1
	}
}

// Init initializes an anchored Plucker vector given a ray origin, P, and a
// unit direction vector, L.
func (ap *AnchoredPluckerVec) Init(P, L *Vec) {
	ap.PluckerVec.Init(P, L)
	ap.P = *P
}

// InitFromSegment initialized a Plucker vector which corresponds to a ray
// pointing from the position vector P1 to the position vector P2.
func (ap *AnchoredPluckerVec) InitFromSegment(P1, P2 *Vec) {
	ap.PluckerVec.InitFromSegment(P1, P2)
	ap.P = *P1
}

// Translate translates a Plucker vector along the given vector.
func (ap *AnchoredPluckerVec) Translate(dx *Vec) {
	ap.PluckerVec.Translate(dx)
	for i := 0; i < 3; i++ { ap.P[i] += dx[i] }
}

// Tetra is a tetrahedron. (Duh!)
//
// Face ordering is:
// F0(V3, V2, V1)
// F1(V2, V3, V0)
// F2(V1, V0, V3)
// F3(V0, V1, V2)
type Tetra [4]Vec

var tetraIdxs = [4][3]int {
	[3]int{ 3, 2, 1 },
	[3]int{ 2, 3, 0 },
	[3]int{ 1, 0, 3 },
	[3]int{ 0, 1, 2 },
}

// VertexIdx returns the index into the given tetrahedron corresponding to
// the specified face and vertex.
func (_ *Tetra) VertexIdx(face, vertex int) int {
	return tetraIdxs[face][vertex]
}

// Orient arranges tetrahedron points so that all faces point outward for
// dir = +1 and inward for dir = -1.
func (t *Tetra) Orient(dir int) {
	v, w, n := Vec{}, Vec{}, Vec{}
	for i := 0; i < 3; i++ {
		v[i] = t[1][i] - t[0][i]
		w[i] = t[2][i] - t[0][i]
	}
	n[0] = -v[1]*w[2] + v[2]*w[1]
    n[1] = -v[2]*w[0] + v[0]*w[2]
    n[2] = -v[0]*w[1] + v[1]*w[0]

	var dot float32
	for i := 0; i < 3; i++ {
		dot += n[i] * (t[3][i] - t[0][i])
	}

	if (dot < 0 && dir == -1) || (dot > 0 && dir == +1) {
		t[0], t[1] = t[1], t[0]
	}
}

// Translate translates a tetrahedron by the given vector.
func (t *Tetra) Translate(dx *Vec) {
	for i := 0; i < 4; i++ {
		for j := 0; j < 3; j++ {
			t[i][j] += dx[j]
		}
	}
}

// Sphere is exactly what you think it is.
type Sphere struct {
	X, Y, Z, R float32
}

// Intersect returns true if the two spheres intersect and false otherwise.
func (s1 *Sphere) Intersect(s2 *Sphere) bool {
	dx, dy, dz, dr := s1.X - s2.X, s1.Y - s2.Y, s1.Z - s2.Z, s1.R - s2.R
	return dr*dr > dx*dx + dy*dy + dz*dz
}

// BoundingSphere draws a bounding sphere aorund the given tetrahedron.
func (t *Tetra) BoundingSphere(sph *Sphere) {
	bx := (t[0][0] + t[1][0] + t[2][0] + t[3][0]) / 4
	by := (t[0][1] + t[1][1] + t[2][1] + t[3][1]) / 4
	bz := (t[0][2] + t[1][2] + t[2][2] + t[3][2]) / 4

	dx, dy, dz := bx-t[0][0], by-t[0][1], bz-t[0][2]
	maxRSqr := dx*dx + dy*dy + dz*dz
	for i := 1; i < 4; i++ {
		dx, dy, dz = bx-t[i][0], by-t[i][1], bz-t[i][2]
		rSqr := dx*dx + dy*dy + dz*dz
		if rSqr > maxRSqr { maxRSqr = rSqr }
	}

	sph.X, sph.Y, sph.Z = bx, by, bz
	sph.R = float32(math.Sqrt(float64(maxRSqr)))
}

// TetraFaceBary contains information specifying the barycentric coordinates
// of a point on a face of a tetrahedron.
type TetraFaceBary struct {
	w [3]float32
	face int
}

// Distance calculates the distance from an anchored Plucker vector to a point
// in a tetrahedron described by the given unscaled barycentric coordinates.
func (t *Tetra) Distance(ap *AnchoredPluckerVec, bary *TetraFaceBary) float32 {
	// Computes one coordinate of the intersection point from the barycentric
	// coordinates of the intersection, then solves P_intr = P + t * L for t.
	var sum float32
	for i := 0; i < 3; i++ { sum += bary.w[i] }
	u0, u1, u2 := bary.w[0] / sum, bary.w[1] / sum, bary.w[2] / sum
	var dim int
	for dim = 0; dim < 3; dim++ {
		if ap.U[dim] > 1e-6 || ap.U[dim] < -1e-6 { break }
	}

	p0 := t[t.VertexIdx(bary.face, 0)][dim]
	p1 := t[t.VertexIdx(bary.face, 1)][dim]
	p2 := t[t.VertexIdx(bary.face, 2)][dim]

	d := ((u0*p0 + u1*p1 + u2*p2) - ap.P[dim]) / ap.U[dim]

	return d
}

// PluckerTetra is a tetrahedron represented by the Plucker vectors that make
// up its edges. It is used for Platis & Theoharis's interseciton detection
// algorithm.
//
// The raw ordering of edges is
// F0(V3, V2, V1)
// F1(V2, V3, V0)
// F2(V1, V0, V3)
// F3(V0, V1, V2)
// {0-1, 0-2, 0-3, 1-2, 1-3, 2-3}
type PluckerTetra [6]PluckerVec

var pluckerTetraEdges = [4][3]int{
	[3]int{ 3, 4, 5 }, // 2-1, 1-3, 3-2
	[3]int{ 2, 1, 5 }, // 3-0, 0-2, 2-3
	[3]int{ 2, 4, 0 }, // 0-3, 3-1, 1-0
	[3]int{ 3, 1, 0 }, // 1-2, 2-0, 0-1
}

var pluckerTetraFlips = [4][3]bool{
	[3]bool{true, false, true},
	[3]bool{true, false, false},
	[3]bool{false, true, true},
	[3]bool{false, true, false},
}

var pluckerTetraFaceShare = [6][6]bool {
	[6]bool{ false, true,  true,  true,  true,  false },
	[6]bool{ true,  false, true,  true,  false, true  },
	[6]bool{ true,  true,  false, false, true,  true  },
	[6]bool{ true,  true,  false, false, true,  true  },
	[6]bool{ true,  false, true,  true,  false, true  },
	[6]bool{ false, true,  true,  true,  true,  false },
}

var tetraEdgeStarts = [6]int{ 0, 0, 0, 1, 1, 2 }
var tetraEdgeEnds = [6]int{ 1, 2, 3, 2, 3, 3 }

// Init initializes a Plucker Tetrahedron from a normal Tetrahedron.
func (pt *PluckerTetra) Init(t *Tetra) {
	pt[0].InitFromSegment(&t[0], &t[1])
	pt[1].InitFromSegment(&t[0], &t[2])
	pt[2].InitFromSegment(&t[0], &t[3])
	pt[3].InitFromSegment(&t[1], &t[2])
	pt[4].InitFromSegment(&t[1], &t[3])
	pt[5].InitFromSegment(&t[2], &t[3])
}

// Translate translates a Plucker tetrahedron along the given vector.
func (pt *PluckerTetra) Translate(dx *Vec) {
	for i := 0; i < 6; i++ { pt[i].Translate(dx) }
}

// EdgeIdx returns the index into pt which corresponds to the requested
// face and edge. A flag is also returned indicating whether the vector stored
// in pt needs to be flipped when doing operations on that face.
func (_ *PluckerTetra) EdgeIdx(face, edge int) (idx int, flip bool) {
	idx = pluckerTetraEdges[face][edge]
	flip = pluckerTetraFlips[face][edge]
	return idx, flip
}

// TetraVertexIdx returns the indices of the vertices in a Tetra object which
// correspond to end points of a given PluckerVector within a PluckerTetra.
func (_ *PluckerTetra) TetraVertices(i int) (start, end int) {
	return tetraEdgeStarts[i], tetraEdgeEnds[i]
}
<commit_msg>Fixed bug in how sphere intersection was detected.<commit_after>/*package geom contains routines for computing geometric quantities.

Contains implementations of algorithms described in Platis & Theoharis, 2015
as well as Schneider & Eberly.

The calling signatures might be more convoluted than they have to be because
I was too worried about memory consumption when I started it. I should include
examples.
*/
package geom

import (
	"math"
)

// Vec is a three dimensional vector. (Duh!)
type Vec [3]float32

// PluckerVec represents a ray. If P and L are the position of the ray's
// origin and the unit vector representing its direction, respectively, then
// U = L and V = L cross P.
type PluckerVec struct {
	U, V Vec
}

// AnchoredPluckerVec is a Plucker vector which also saves the position of
// the ray's origin.
type AnchoredPluckerVec struct {
	PluckerVec
	P Vec
}

// Init initializes a Plucker vector given a ray origin, P, and a unit
// direction vector, L.
func (p *PluckerVec) Init(P, L *Vec) {
	p.U = *L

	p.V[0] = -P[1]*L[2] + P[2]*L[1]
    p.V[1] = -P[2]*L[0] + P[0]*L[2]
    p.V[2] = -P[0]*L[1] + P[1]*L[0]
}

// InitFromSegment initialized a Plucker vector which corresponds to a ray
// pointing from the position vector P1 to the position vector P2.
func (p *PluckerVec) InitFromSegment(P1, P2 *Vec) {
	var sum float32
	for i := 0; i < 3; i++ {
		p.U[i] = P2[i] - P1[i]
		sum += p.U[i]*p.U[i]
	}
	sum = float32(math.Sqrt(float64(sum)))
	//for i := 0; i < 3; i++ { p.U[i] /= sum }

	p.V[0] = -P1[1]*p.U[2] + P1[2]*p.U[1]
    p.V[1] = -P1[2]*p.U[0] + P1[0]*p.U[2]
    p.V[2] = -P1[0]*p.U[1] + P1[1]*p.U[0]
}

// Translate translates a Plucker vector along the given vector.
func (p *PluckerVec) Translate(dx *Vec) {
	p.V[0] += -dx[1]*p.U[2] + dx[2]*p.U[1]
    p.V[1] += -dx[2]*p.U[0] + dx[0]*p.U[2]
    p.V[2] += -dx[0]*p.U[1] + dx[1]*p.U[0]
}

// Dot computes the permuted inner product of p1 and p2, i.e.
// p1.U*p2.V + p1.V*p2.U.
func (p1 *PluckerVec) Dot(p2 *PluckerVec, flip bool) float32 {
	var sum float32
	for i := 0; i < 3; i++ {
		sum += p1.U[i]*p2.V[i] + p1.V[i]*p2.U[i]
	}
	if flip {
		return sum
	} else {
		return -sum
	}
}

// Dot computes the permuted inner product of p1 and p2, i.e.
// p1.U*p2.V + p1.V*p2.U and also returns a sign flag of -1, 0, or +1 if
// that product is negative, zero, or positive, respectively.
func (p1 *PluckerVec) SignDot(p2 *PluckerVec, flip bool) (float32, int) {
	dot := p1.Dot(p2, flip)
	if dot == 0 {
		return dot, 0
	} else if dot > 0 {
		return dot, +1
	} else {
		return dot, -1
	}
}

// Init initializes an anchored Plucker vector given a ray origin, P, and a
// unit direction vector, L.
func (ap *AnchoredPluckerVec) Init(P, L *Vec) {
	ap.PluckerVec.Init(P, L)
	ap.P = *P
}

// InitFromSegment initialized a Plucker vector which corresponds to a ray
// pointing from the position vector P1 to the position vector P2.
func (ap *AnchoredPluckerVec) InitFromSegment(P1, P2 *Vec) {
	ap.PluckerVec.InitFromSegment(P1, P2)
	ap.P = *P1
}

// Translate translates a Plucker vector along the given vector.
func (ap *AnchoredPluckerVec) Translate(dx *Vec) {
	ap.PluckerVec.Translate(dx)
	for i := 0; i < 3; i++ { ap.P[i] += dx[i] }
}

// Tetra is a tetrahedron. (Duh!)
//
// Face ordering is:
// F0(V3, V2, V1)
// F1(V2, V3, V0)
// F2(V1, V0, V3)
// F3(V0, V1, V2)
type Tetra [4]Vec

var tetraIdxs = [4][3]int {
	[3]int{ 3, 2, 1 },
	[3]int{ 2, 3, 0 },
	[3]int{ 1, 0, 3 },
	[3]int{ 0, 1, 2 },
}

// VertexIdx returns the index into the given tetrahedron corresponding to
// the specified face and vertex.
func (_ *Tetra) VertexIdx(face, vertex int) int {
	return tetraIdxs[face][vertex]
}

// Orient arranges tetrahedron points so that all faces point outward for
// dir = +1 and inward for dir = -1.
func (t *Tetra) Orient(dir int) {
	v, w, n := Vec{}, Vec{}, Vec{}
	for i := 0; i < 3; i++ {
		v[i] = t[1][i] - t[0][i]
		w[i] = t[2][i] - t[0][i]
	}
	n[0] = -v[1]*w[2] + v[2]*w[1]
    n[1] = -v[2]*w[0] + v[0]*w[2]
    n[2] = -v[0]*w[1] + v[1]*w[0]

	var dot float32
	for i := 0; i < 3; i++ {
		dot += n[i] * (t[3][i] - t[0][i])
	}

	if (dot < 0 && dir == -1) || (dot > 0 && dir == +1) {
		t[0], t[1] = t[1], t[0]
	}
}

// Translate translates a tetrahedron by the given vector.
func (t *Tetra) Translate(dx *Vec) {
	for i := 0; i < 4; i++ {
		for j := 0; j < 3; j++ {
			t[i][j] += dx[j]
		}
	}
}

// Sphere is exactly what you think it is.
type Sphere struct {
	X, Y, Z, R float32
}

// Intersect returns true if the two spheres intersect and false otherwise.
func (s1 *Sphere) Intersect(s2 *Sphere) bool {
	dx, dy, dz, dr := s1.X - s2.X, s1.Y - s2.Y, s1.Z - s2.Z, s1.R + s2.R
	return dr*dr > dx*dx + dy*dy + dz*dz
}

// BoundingSphere draws a bounding sphere aorund the given tetrahedron.
func (t *Tetra) BoundingSphere(sph *Sphere) {
	bx := (t[0][0] + t[1][0] + t[2][0] + t[3][0]) / 4
	by := (t[0][1] + t[1][1] + t[2][1] + t[3][1]) / 4
	bz := (t[0][2] + t[1][2] + t[2][2] + t[3][2]) / 4

	dx, dy, dz := bx-t[0][0], by-t[0][1], bz-t[0][2]
	maxRSqr := dx*dx + dy*dy + dz*dz
	for i := 1; i < 4; i++ {
		dx, dy, dz = bx-t[i][0], by-t[i][1], bz-t[i][2]
		rSqr := dx*dx + dy*dy + dz*dz
		if rSqr > maxRSqr { maxRSqr = rSqr }
	}

	sph.X, sph.Y, sph.Z = bx, by, bz
	sph.R = float32(math.Sqrt(float64(maxRSqr)))
}

// TetraFaceBary contains information specifying the barycentric coordinates
// of a point on a face of a tetrahedron.
type TetraFaceBary struct {
	w [3]float32
	face int
}

// Distance calculates the distance from an anchored Plucker vector to a point
// in a tetrahedron described by the given unscaled barycentric coordinates.
func (t *Tetra) Distance(ap *AnchoredPluckerVec, bary *TetraFaceBary) float32 {
	// Computes one coordinate of the intersection point from the barycentric
	// coordinates of the intersection, then solves P_intr = P + t * L for t.
	var sum float32
	for i := 0; i < 3; i++ { sum += bary.w[i] }
	u0, u1, u2 := bary.w[0] / sum, bary.w[1] / sum, bary.w[2] / sum
	var dim int
	for dim = 0; dim < 3; dim++ {
		if ap.U[dim] > 1e-6 || ap.U[dim] < -1e-6 { break }
	}

	p0 := t[t.VertexIdx(bary.face, 0)][dim]
	p1 := t[t.VertexIdx(bary.face, 1)][dim]
	p2 := t[t.VertexIdx(bary.face, 2)][dim]

	d := ((u0*p0 + u1*p1 + u2*p2) - ap.P[dim]) / ap.U[dim]

	return d
}

// PluckerTetra is a tetrahedron represented by the Plucker vectors that make
// up its edges. It is used for Platis & Theoharis's interseciton detection
// algorithm.
//
// The raw ordering of edges is
// F0(V3, V2, V1)
// F1(V2, V3, V0)
// F2(V1, V0, V3)
// F3(V0, V1, V2)
// {0-1, 0-2, 0-3, 1-2, 1-3, 2-3}
type PluckerTetra [6]PluckerVec

var pluckerTetraEdges = [4][3]int{
	[3]int{ 3, 4, 5 }, // 2-1, 1-3, 3-2
	[3]int{ 2, 1, 5 }, // 3-0, 0-2, 2-3
	[3]int{ 2, 4, 0 }, // 0-3, 3-1, 1-0
	[3]int{ 3, 1, 0 }, // 1-2, 2-0, 0-1
}

var pluckerTetraFlips = [4][3]bool{
	[3]bool{true, false, true},
	[3]bool{true, false, false},
	[3]bool{false, true, true},
	[3]bool{false, true, false},
}

var pluckerTetraFaceShare = [6][6]bool {
	[6]bool{ false, true,  true,  true,  true,  false },
	[6]bool{ true,  false, true,  true,  false, true  },
	[6]bool{ true,  true,  false, false, true,  true  },
	[6]bool{ true,  true,  false, false, true,  true  },
	[6]bool{ true,  false, true,  true,  false, true  },
	[6]bool{ false, true,  true,  true,  true,  false },
}

var tetraEdgeStarts = [6]int{ 0, 0, 0, 1, 1, 2 }
var tetraEdgeEnds = [6]int{ 1, 2, 3, 2, 3, 3 }

// Init initializes a Plucker Tetrahedron from a normal Tetrahedron.
func (pt *PluckerTetra) Init(t *Tetra) {
	pt[0].InitFromSegment(&t[0], &t[1])
	pt[1].InitFromSegment(&t[0], &t[2])
	pt[2].InitFromSegment(&t[0], &t[3])
	pt[3].InitFromSegment(&t[1], &t[2])
	pt[4].InitFromSegment(&t[1], &t[3])
	pt[5].InitFromSegment(&t[2], &t[3])
}

// Translate translates a Plucker tetrahedron along the given vector.
func (pt *PluckerTetra) Translate(dx *Vec) {
	for i := 0; i < 6; i++ { pt[i].Translate(dx) }
}

// EdgeIdx returns the index into pt which corresponds to the requested
// face and edge. A flag is also returned indicating whether the vector stored
// in pt needs to be flipped when doing operations on that face.
func (_ *PluckerTetra) EdgeIdx(face, edge int) (idx int, flip bool) {
	idx = pluckerTetraEdges[face][edge]
	flip = pluckerTetraFlips[face][edge]
	return idx, flip
}

// TetraVertexIdx returns the indices of the vertices in a Tetra object which
// correspond to end points of a given PluckerVector within a PluckerTetra.
func (_ *PluckerTetra) TetraVertices(i int) (start, end int) {
	return tetraEdgeStarts[i], tetraEdgeEnds[i]
}
<|endoftext|>


<commit_before>package host

import (
	"net"
	"time"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"

	"github.com/NebulousLabs/bolt"
)

// managedSendRecentRevision sends the most recent known file contract
// revision, including signatures, to the renter, for the file contract with
// the input id.
func (h *Host) managedRPCRevisionRequest(conn net.Conn) (types.FileContractID, error) {
	// Set the negotiation deadline.
	conn.SetDeadline(time.Now().Add(modules.NegotiateRevisionRequestTime))

	// Receive the file contract id from the renter.
	var fcid types.FileContractID
	err := encoding.ReadObject(conn, &fcid, uint64(len(fcid)))
	if err != nil {
		return types.FileContractID{}, err
	}

	// Fetch the storage obligation with the file contract revision
	// transaction.
	var so *storageObligation
	err = h.db.Update(func(tx *bolt.Tx) error {
		fso, err := getStorageObligation(tx, fcid)
		so = &fso
		return err
	})
	if err != nil {
		return types.FileContractID{}, composeErrors(err, modules.WriteNegotiationRejection(conn, err))
	}

	// Send the most recent file contract revision.
	revisionTxn := so.RevisionTransactionSet[len(so.RevisionTransactionSet)-1]
	recentRevision := revisionTxn.FileContractRevisions[0]
	// Find all of the signatures on the file contract revision. There should be two.
	var revisionSigs []types.TransactionSignature
	for _, sig := range revisionTxn.TransactionSignatures {
		if sig.ParentID == crypto.Hash(fcid) {
			revisionSigs = append(revisionSigs, sig)
		}
	}

	// Sanity check - verify that the host has a valid revision and set of
	// signatures.
	h.mu.RLock()
	blockHeight := h.blockHeight
	h.mu.RUnlock()
	err = modules.VerifyFileContractRevisionTransactionSignatures(recentRevision, revisionSigs, blockHeight)
	if err != nil {
		h.log.Critical("host is inconsistend, bad file contract revision transaction", err)
		return types.FileContractID{}, err
	}

	// Send the file contract revision and the corresponding signatures to the
	// renter.
	err = encoding.WriteObject(conn, revisionTxn)
	if err != nil {
		return types.FileContractID{}, err
	}
	err = encoding.WriteObject(conn, revisionSigs)
	if err != nil {
		return types.FileContractID{}, err
	}
	return fcid, nil
}
<commit_msg>fix pr comments<commit_after>package host

import (
	"net"
	"time"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
	"github.com/NebulousLabs/Sia/modules"
	"github.com/NebulousLabs/Sia/types"

	"github.com/NebulousLabs/bolt"
)

// managedSendRecentRevision sends the most recent known file contract
// revision, including signatures, to the renter, for the file contract with
// the input id.
func (h *Host) managedRPCRevisionRequest(conn net.Conn) (types.FileContractID, error) {
	// Set the negotiation deadline.
	conn.SetDeadline(time.Now().Add(modules.NegotiateRevisionRequestTime))

	// Receive the file contract id from the renter.
	var fcid types.FileContractID
	err := encoding.ReadObject(conn, &fcid, uint64(len(fcid)))
	if err != nil {
		return types.FileContractID{}, err
	}

	// Fetch the storage obligation with the file contract revision
	// transaction.
	var so *storageObligation
	err = h.db.Update(func(tx *bolt.Tx) error {
		fso, err := getStorageObligation(tx, fcid)
		so = &fso
		return err
	})
	if err != nil {
		return types.FileContractID{}, modules.WriteNegotiationRejection(conn, err)
	}

	// Send the most recent file contract revision.
	revisionTxn := so.RevisionTransactionSet[len(so.RevisionTransactionSet)-1]
	recentRevision := revisionTxn.FileContractRevisions[0]
	// Find all of the signatures on the file contract revision. There should be two.
	var revisionSigs []types.TransactionSignature
	for _, sig := range revisionTxn.TransactionSignatures {
		if sig.ParentID == crypto.Hash(fcid) {
			revisionSigs = append(revisionSigs, sig)
		}
	}

	// Sanity check - verify that the host has a valid revision and set of
	// signatures.
	h.mu.RLock()
	blockHeight := h.blockHeight
	h.mu.RUnlock()
	err = modules.VerifyFileContractRevisionTransactionSignatures(recentRevision, revisionSigs, blockHeight)
	if err != nil {
		h.log.Critical("host is inconsistent, bad file contract revision transaction", err)
		return types.FileContractID{}, err
	}

	// Send the file contract revision and the corresponding signatures to the
	// renter.
	err = encoding.WriteObject(conn, revisionTxn)
	if err != nil {
		return types.FileContractID{}, err
	}
	err = encoding.WriteObject(conn, revisionSigs)
	if err != nil {
		return types.FileContractID{}, err
	}
	return fcid, nil
}
<|endoftext|>


<commit_before>// Copyright 2015 MongoDB, Inc. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"./model"
	"./util"
	"flag"
	"fmt"
	"github.com/fractalcat/nagiosplugin"
	"os"
	"time"
)

const (
	CredFile = ".mongodb_mms"
)

var groupId string
var hostname string
var metricName string
var server string
var warning string
var critical string
var timeout int
var maxAge int

func main() {
	setupFlags()
	if server == "" || groupId == "" {
		flag.Usage()
		os.Exit(2)
		return
	}

	check := nagiosplugin.NewCheck()
	defer check.Finish()

	config, err := util.LoadConfigFromHome(CredFile)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "%v", err)
		return
	}

	username, apikey := config.GetCredentials()
	api, err := util.NewMMSAPI(server, timeout, username, apikey)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Failed to create API. Error: %v", err)
		return
	}

	host, err := api.GetHostByName(groupId, hostname)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "%v", err)
		return
	}

	if metricName == "" {
		doHostCheck(check, host)
	} else {
		doMetricCheck(check, api, host)
	}
}

func doHostCheck(check *nagiosplugin.Check, host *model.Host) {
	age := time.Since(host.LastPing)

	critRange, err := nagiosplugin.ParseRange(critical)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing critical range. Error: %v", err)
		return
	}

	if critRange.Check(age.Seconds()) {
		check.AddResultf(nagiosplugin.CRITICAL, fmt.Sprintf("Last ping was %v seconds ago", age.Seconds()))
		return
	}

	warnRange, err := nagiosplugin.ParseRange(warning)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing warning range. Error: %v", err)
		return
	}

	if warnRange.Check(age.Seconds()) {
		check.AddResultf(nagiosplugin.WARNING, fmt.Sprintf("Last ping was %v seconds ago", age.Seconds()))
		return
	}

	check.AddResultf(nagiosplugin.OK, fmt.Sprintf("Last ping was %v seconds ago", age.Seconds()))
}

func doMetricCheck(check *nagiosplugin.Check, api *util.MMSAPI, host *model.Host) {
	metric, err := api.GetHostMetric(groupId, host.Id, metricName)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "%v", err)
		return
	}

	if len(metric.DataPoints) == 0 {
		check.AddResultf(nagiosplugin.UNKNOWN, "No data points found for %v", metricName)
		return
	}

	lastDataPoint := metric.DataPoints[len(metric.DataPoints)-1]
	age := time.Since(lastDataPoint.Timestamp)
	if int(age.Seconds()) > maxAge {
		check.AddResultf(nagiosplugin.CRITICAL, "Last data point for %v is %v seconds old.", metricName, int(age.Seconds()))
		return
	}

	check.AddPerfDatum(metricName, "", lastDataPoint.Value)

	critRange, err := nagiosplugin.ParseRange(critical)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing critical range. Error: %v", err)
		return
	}

	if critRange.Check(lastDataPoint.Value) {
		check.AddResultf(nagiosplugin.CRITICAL, metric.ToStringLastDataPoint())
		return
	}

	warnRange, err := nagiosplugin.ParseRange(warning)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing warning range. Error: %v", err)
		return
	}

	if warnRange.Check(lastDataPoint.Value) {
		check.AddResultf(nagiosplugin.WARNING, metric.ToStringLastDataPoint())
		return
	}

	check.AddResultf(nagiosplugin.OK, metric.ToStringLastDataPoint())
}

func setupFlags() {
	const (
		groupIdDefault  = ""
		groupIdUsage    = "The MMS/Ops Manager group ID that contains the server"
		hostnameDefault = ""
		hostnameUsage   = "hostname:port of the mongod/s to check"
		metricDefault   = ""
		metricUsage     = "metric to query"
		serverDefault   = "https://mms.mongodb.com"
		serverUsage     = "hostname and port of the MMS/Ops Manager service"
		warningDefault  = "~:" // considered negative infinity to positive infinity (https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT)
		warningUsage    = "warning threshold for given metric"
		criticalDefault = "~:"
		criticalUsage   = "critical threshold for given metric"
		timeoutDefault  = 10
		timeoutUsage    = "connection timeout connecting MMS/Ops Manager service"
		maxAgeDefault   = 180
		maxAgeUsage     = "the maximum number of seconds old a metric before it is considerd stale"
	)

	flag.StringVar(&groupId, "groupid", groupIdDefault, groupIdUsage)
	flag.StringVar(&groupId, "g", groupIdDefault, groupIdUsage)

	flag.StringVar(&hostname, "hostname", hostnameDefault, hostnameUsage)
	flag.StringVar(&hostname, "H", hostnameDefault, hostnameUsage)

	flag.StringVar(&metricName, "metric", metricDefault, metricUsage)
	flag.StringVar(&metricName, "m", metricDefault, metricUsage)

	flag.IntVar(&maxAge, "maxage", maxAgeDefault, maxAgeUsage)
	flag.IntVar(&maxAge, "a", maxAgeDefault, maxAgeUsage)

	flag.StringVar(&server, "server", serverDefault, serverUsage)
	flag.StringVar(&server, "s", serverDefault, serverUsage)

	flag.StringVar(&warning, "warning", warningDefault, warningUsage)
	flag.StringVar(&warning, "w", warningDefault, warningUsage)

	flag.StringVar(&critical, "critical", criticalDefault, criticalUsage)
	flag.StringVar(&critical, "c", criticalDefault, criticalUsage)

	flag.IntVar(&timeout, "timeout", timeoutDefault, timeoutUsage)
	flag.IntVar(&timeout, "t", timeoutDefault, timeoutUsage)

	flag.Usage = func() {
		fmt.Fprintf(os.Stdout, "Usage: check_mongodb_mms  -g groupid -s server [-m metric] [-a age] [-H hostname] [-t timeout] [-w warning_level] [-c critica_level]\n")
		fmt.Fprintf(os.Stdout, "     -g, --groupid  %v\n", groupIdUsage)
		fmt.Fprintf(os.Stdout, "     -H, --hostname %v\n", hostnameUsage)
		fmt.Fprintf(os.Stdout, "     -m, --metric (no metric means check last ping age in seconds) %v\n", metricUsage)
		fmt.Fprintf(os.Stdout, "     -a, --maxage (default %v) %v\n", maxAgeDefault, maxAgeUsage)
		fmt.Fprintf(os.Stdout, "     -s, --server (default: %v) %v\n", serverDefault, serverUsage)
		fmt.Fprintf(os.Stdout, "     -w, --warning (default: %v) %v\n", warningDefault, warningUsage)
		fmt.Fprintf(os.Stdout, "     -c, --critical (default: %v) %v\n", criticalDefault, criticalUsage)
		fmt.Fprintf(os.Stdout, "     -t, --timeout (default: %v) %v\n", timeoutDefault, timeoutUsage)
		fmt.Fprintf(os.Stdout, "\n     -w and -c support the standard nagios threshold formats.\n"+
			"     See https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT for more details.\n")
	}
	flag.Parse()
}
<commit_msg>fix help and hostname check<commit_after>// Copyright 2015 MongoDB, Inc. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"./model"
	"./util"
	"flag"
	"fmt"
	"github.com/fractalcat/nagiosplugin"
	"os"
	"time"
)

const (
	CredFile = ".mongodb_mms"
)

var groupId string
var hostname string
var metricName string
var server string
var warning string
var critical string
var timeout int
var maxAge int

func main() {
	setupFlags()
	if hostname == "" || groupId == "" {
		flag.Usage()
		os.Exit(2)
		return
	}

	check := nagiosplugin.NewCheck()
	defer check.Finish()

	config, err := util.LoadConfigFromHome(CredFile)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "%v", err)
		return
	}

	username, apikey := config.GetCredentials()
	api, err := util.NewMMSAPI(server, timeout, username, apikey)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Failed to create API. Error: %v", err)
		return
	}

	host, err := api.GetHostByName(groupId, hostname)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "%v", err)
		return
	}

	if metricName == "" {
		doHostCheck(check, host)
	} else {
		doMetricCheck(check, api, host)
	}
}

func doHostCheck(check *nagiosplugin.Check, host *model.Host) {
	age := time.Since(host.LastPing)

	critRange, err := nagiosplugin.ParseRange(critical)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing critical range. Error: %v", err)
		return
	}

	if critRange.Check(age.Seconds()) {
		check.AddResultf(nagiosplugin.CRITICAL, fmt.Sprintf("Last ping was %v seconds ago", age.Seconds()))
		return
	}

	warnRange, err := nagiosplugin.ParseRange(warning)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing warning range. Error: %v", err)
		return
	}

	if warnRange.Check(age.Seconds()) {
		check.AddResultf(nagiosplugin.WARNING, fmt.Sprintf("Last ping was %v seconds ago", age.Seconds()))
		return
	}

	check.AddResultf(nagiosplugin.OK, fmt.Sprintf("Last ping was %v seconds ago", age.Seconds()))
}

func doMetricCheck(check *nagiosplugin.Check, api *util.MMSAPI, host *model.Host) {
	metric, err := api.GetHostMetric(groupId, host.Id, metricName)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "%v", err)
		return
	}

	if len(metric.DataPoints) == 0 {
		check.AddResultf(nagiosplugin.UNKNOWN, "No data points found for %v", metricName)
		return
	}

	lastDataPoint := metric.DataPoints[len(metric.DataPoints)-1]
	age := time.Since(lastDataPoint.Timestamp)
	if int(age.Seconds()) > maxAge {
		check.AddResultf(nagiosplugin.CRITICAL, "Last data point for %v is %v seconds old.", metricName, int(age.Seconds()))
		return
	}

	check.AddPerfDatum(metricName, "", lastDataPoint.Value)

	critRange, err := nagiosplugin.ParseRange(critical)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing critical range. Error: %v", err)
		return
	}

	if critRange.Check(lastDataPoint.Value) {
		check.AddResultf(nagiosplugin.CRITICAL, metric.ToStringLastDataPoint())
		return
	}

	warnRange, err := nagiosplugin.ParseRange(warning)
	if err != nil {
		check.AddResultf(nagiosplugin.UNKNOWN, "Error parsing warning range. Error: %v", err)
		return
	}

	if warnRange.Check(lastDataPoint.Value) {
		check.AddResultf(nagiosplugin.WARNING, metric.ToStringLastDataPoint())
		return
	}

	check.AddResultf(nagiosplugin.OK, metric.ToStringLastDataPoint())
}

func setupFlags() {
	const (
		groupIdDefault  = ""
		groupIdUsage    = "The MMS/Ops Manager group ID that contains the server"
		hostnameDefault = ""
		hostnameUsage   = "hostname:port of the mongod/s to check"
		metricDefault   = ""
		metricUsage     = "metric to query"
		serverDefault   = "https://mms.mongodb.com"
		serverUsage     = "hostname and port of the MMS/Ops Manager service"
		warningDefault  = "~:" // considered negative infinity to positive infinity (https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT)
		warningUsage    = "warning threshold for given metric"
		criticalDefault = "~:"
		criticalUsage   = "critical threshold for given metric"
		timeoutDefault  = 10
		timeoutUsage    = "connection timeout connecting MMS/Ops Manager service"
		maxAgeDefault   = 180
		maxAgeUsage     = "the maximum number of seconds old a metric before it is considerd stale"
	)

	flag.StringVar(&groupId, "groupid", groupIdDefault, groupIdUsage)
	flag.StringVar(&groupId, "g", groupIdDefault, groupIdUsage)

	flag.StringVar(&hostname, "hostname", hostnameDefault, hostnameUsage)
	flag.StringVar(&hostname, "H", hostnameDefault, hostnameUsage)

	flag.StringVar(&metricName, "metric", metricDefault, metricUsage)
	flag.StringVar(&metricName, "m", metricDefault, metricUsage)

	flag.IntVar(&maxAge, "maxage", maxAgeDefault, maxAgeUsage)
	flag.IntVar(&maxAge, "a", maxAgeDefault, maxAgeUsage)

	flag.StringVar(&server, "server", serverDefault, serverUsage)
	flag.StringVar(&server, "s", serverDefault, serverUsage)

	flag.StringVar(&warning, "warning", warningDefault, warningUsage)
	flag.StringVar(&warning, "w", warningDefault, warningUsage)

	flag.StringVar(&critical, "critical", criticalDefault, criticalUsage)
	flag.StringVar(&critical, "c", criticalDefault, criticalUsage)

	flag.IntVar(&timeout, "timeout", timeoutDefault, timeoutUsage)
	flag.IntVar(&timeout, "t", timeoutDefault, timeoutUsage)

	flag.Usage = func() {
		fmt.Fprintf(os.Stdout, "Usage: check_mongodb_mms  -g groupid -H hostname [-m metric] [-a age] [-s server] [-t timeout] [-w warning_level] [-c critica_level]\n")
		fmt.Fprintf(os.Stdout, "     -g, --groupid  %v\n", groupIdUsage)
		fmt.Fprintf(os.Stdout, "     -H, --hostname %v\n", hostnameUsage)
		fmt.Fprintf(os.Stdout, "     -m, --metric (no metric means check last ping age in seconds) %v\n", metricUsage)
		fmt.Fprintf(os.Stdout, "     -a, --maxage (default %v) %v\n", maxAgeDefault, maxAgeUsage)
		fmt.Fprintf(os.Stdout, "     -s, --server (default: %v) %v\n", serverDefault, serverUsage)
		fmt.Fprintf(os.Stdout, "     -w, --warning (default: %v) %v\n", warningDefault, warningUsage)
		fmt.Fprintf(os.Stdout, "     -c, --critical (default: %v) %v\n", criticalDefault, criticalUsage)
		fmt.Fprintf(os.Stdout, "     -t, --timeout (default: %v) %v\n", timeoutDefault, timeoutUsage)
		fmt.Fprintf(os.Stdout, "\n     -w and -c support the standard nagios threshold formats.\n"+
			"     See https://nagios-plugins.org/doc/guidelines.html#THRESHOLDFORMAT for more details.\n")
	}
	flag.Parse()
}
<|endoftext|>


<commit_before>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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

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

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

package main

//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
//to be modified as well with the new ID of chaincode_example02.
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
//hard-coding.

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

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

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

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

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

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

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

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

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function == "delete" {
		// Deletes an entity from its state
		return t.delete(stub, args)
	}

	if function == "addTable" {
		// Deletes an entity from its state
		return t.addTable(stub, args)
	}

	if function == "getTable" {
		// Deletes an entity from its state
		return t.getTable(stub, args)
	}

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

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

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	if err != nil {
		return nil, errors.New("Invalid transaction amount, expecting a integer value")
	}
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

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

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

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) addTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	err := stub.CreateTable("Customer", []*shim.ColumnDefinition{
	&shim.ColumnDefinition{Name: "Customer_ID", Type: shim.ColumnDefinition_STRING, Key: true},
	&shim.ColumnDefinition{Name: "Customer_Name", Type: shim.ColumnDefinition_STRING, Key: false},
	&shim.ColumnDefinition{Name: "Customer_Gender", Type: shim.ColumnDefinition_STRING, Key: false},
	})

	if err != nil {
		return nil, err
	}

	success1, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1001"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Vivek"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success1 {
		return nil, errors.New("Entity not found")
	}

	if err != nil {
		return nil, err
	}

	success2, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1002"}},
	&shim.Column{Value: &shim.Column_String_{String_: "John"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success2 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}

	success3, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1003"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Simone"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Female"}},
	},
	})

	if !success3 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) getTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: "C1001"}}
	columns = append(columns, col1)

	row, err := stub.GetRow("Customer", columns)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}

	cust := row.Columns[1].GetBytes()
	myLogger.Debugf(" customer is [% x]",  cust)

	var columns2 []shim.Column
	col2 := shim.Column{Value: &shim.Column_String_{String_: "Male"}}
	columns = append(columns2, col2)

	rowChannel, err := stub.GetRows("Customer", columns2)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}
	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("getRows operation failed. Error marshaling JSON: %s", err)
		}
	fmt.Printf("Query Response:%s\n", jsonRows)
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}
	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}
<commit_msg>Update accumshare.go<commit_after>/*
Copyright IBM Corp. 2016 All Rights Reserved.

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

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

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

package main

//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has
//to be modified as well with the new ID of chaincode_example02.
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of
//hard-coding.

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

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

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

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

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

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

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

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

	return nil, nil
}

// Transaction makes payment of X units from A to B
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function == "delete" {
		// Deletes an entity from its state
		return t.delete(stub, args)
	}

	if function == "addTable" {
		// Deletes an entity from its state
		return t.addTable(stub, args)
	}

	if function == "getTable" {
		// Deletes an entity from its state
		return t.getTable(stub, args)
	}

	var A, B string    // Entities
	var Aval, Bval int // Asset holdings
	var X int          // Transaction value
	var err error

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

	A = args[0]
	B = args[1]

	// Get the state from the ledger
	// TODO: will be nice to have a GetAllState call to ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Avalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Aval, _ = strconv.Atoi(string(Avalbytes))

	Bvalbytes, err := stub.GetState(B)
	if err != nil {
		return nil, errors.New("Failed to get state")
	}
	if Bvalbytes == nil {
		return nil, errors.New("Entity not found")
	}
	Bval, _ = strconv.Atoi(string(Bvalbytes))

	// Perform the execution
	X, err = strconv.Atoi(args[2])
	if err != nil {
		return nil, errors.New("Invalid transaction amount, expecting a integer value")
	}
	Aval = Aval - X
	Bval = Bval + X
	fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)

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

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

	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) addTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	err := stub.CreateTable("Customer", []*shim.ColumnDefinition{
	&shim.ColumnDefinition{Name: "Customer_ID", Type: shim.ColumnDefinition_STRING, Key: true},
	&shim.ColumnDefinition{Name: "Customer_Name", Type: shim.ColumnDefinition_STRING, Key: false},
	&shim.ColumnDefinition{Name: "Customer_Gender", Type: shim.ColumnDefinition_STRING, Key: false},
	})

	if err != nil {
		return nil, err
	}

	success1, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1001"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Vivek"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success1 {
		return nil, errors.New("Entity not found")
	}

	if err != nil {
		return nil, err
	}

	success2, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1002"}},
	&shim.Column{Value: &shim.Column_String_{String_: "John"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Male"}},
	},
	})

	if !success2 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}

	success3, err := stub.InsertRow("Customer", shim.Row{
	Columns: []*shim.Column{
	&shim.Column{Value: &shim.Column_String_{String_: "C1003"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Simone"}},
	&shim.Column{Value: &shim.Column_String_{String_: "Female"}},
	},
	})

	if !success3 {
		return nil, errors.New("Entity not found")
	}
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) getTable(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {

	var columns []shim.Column
	col1 := shim.Column{Value: &shim.Column_String_{String_: "C1001"}}
	columns = append(columns, col1)

	row, err := stub.GetRow("Customer", columns)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}

	cust := row.Columns[1].GetBytes()
	fmt.Printf("Customer = %d\n", cust)
	//myLogger.Debugf(" customer is [% x]",  cust)

	var columns2 []shim.Column
	col2 := shim.Column{Value: &shim.Column_String_{String_: "Male"}}
	columns = append(columns2, col2)

	rowChannel, err := stub.GetRows("Customer", columns2)
	if err != nil {
		return nil, fmt.Errorf("getRows operation failed. %s", err)
	}
	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("getRows operation failed. Error marshaling JSON: %s", err)
		}
	fmt.Printf("Query Response:%s\n", jsonRows)
	return nil, nil
}

// Deletes an entity from state
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	A := args[0]

	// Delete the key from the state in ledger
	err := stub.DelState(A)
	if err != nil {
		return nil, errors.New("Failed to delete state")
	}

	return nil, nil
}

// Query callback representing the query of a chaincode
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if function != "query" {
		return nil, errors.New("Invalid query function name. Expecting \"query\"")
	}
	var A string // Entities
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")
	}

	A = args[0]

	// Get the state from the ledger
	Avalbytes, err := stub.GetState(A)
	if err != nil {
		jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	if Avalbytes == nil {
		jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
		return nil, errors.New(jsonResp)
	}

	jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
	fmt.Printf("Query Response:%s\n", jsonResp)
	return Avalbytes, nil
}

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


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package mungers

import (
	"regexp"
	"sort"
	"strconv"

	githubapi "github.com/google/go-github/github"
	"github.com/spf13/cobra"

	"k8s.io/test-infra/mungegithub/features"
	"k8s.io/test-infra/mungegithub/github"
	"k8s.io/test-infra/mungegithub/mungers/approvers"
	c "k8s.io/test-infra/mungegithub/mungers/matchers/comment"
	"k8s.io/test-infra/mungegithub/mungers/matchers/event"
)

const (
	approveCommand  = "APPROVE"
	lgtmCommand     = "LGTM"
	cancelArgument  = "cancel"
	noIssueArgument = "no-issue"
)

var AssociatedIssueRegex = regexp.MustCompile(`(?:kubernetes/[^/]+/issues/|#)(\d+)`)

// ApprovalHandler will try to add "approved" label once
// all files of change has been approved by approvers.
type ApprovalHandler struct {
	features *features.Features
}

func init() {
	h := &ApprovalHandler{}
	RegisterMungerOrDie(h)
}

// Name is the name usable in --pr-mungers
func (*ApprovalHandler) Name() string { return "approval-handler" }

// RequiredFeatures is a slice of 'features' that must be provided
func (*ApprovalHandler) RequiredFeatures() []string {
	return []string{features.RepoFeatureName, features.AliasesFeature}
}

// Initialize will initialize the munger
func (h *ApprovalHandler) Initialize(config *github.Config, features *features.Features) error {
	h.features = features
	return nil
}

// EachLoop is called at the start of every munge loop
func (*ApprovalHandler) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (*ApprovalHandler) AddFlags(cmd *cobra.Command, config *github.Config) {}

// Returns associated issue, or 0 if it can't find any.
// This is really simple, and could be improved later.
func findAssociatedIssue(body *string) int {
	if body == nil {
		return 0
	}
	match := AssociatedIssueRegex.FindStringSubmatch(*body)
	if len(match) == 0 {
		return 0
	}
	v, err := strconv.Atoi(match[1])
	if err != nil {
		return 0
	}
	return v
}

// Munge is the workhorse the will actually make updates to the PR
// The algorithm goes as:
// - Initially, we build an approverSet
//   - Go through all comments in order of creation.
//		 - (Issue/PR comments, PR review comments, and PR review bodies are considered as comments)
//	 - If anyone said "/approve" or "/lgtm", add them to approverSet.
// - Then, for each file, we see if any approver of this file is in approverSet and keep track of files without approval
//   - An approver of a file is defined as:
//     - Someone listed as an "approver" in an OWNERS file in the files directory OR
//     - in one of the file's parent directorie
// - Iff all files have been approved, the bot will add the "approved" label.
// - Iff a cancel command is found, that reviewer will be removed from the approverSet
// 	and the munger will remove the approved label if it has been applied
func (h *ApprovalHandler) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}
	filenames := []string{}
	files, ok := obj.ListFiles()
	if !ok {
		return
	}
	for _, fn := range files {
		filenames = append(filenames, *fn.Filename)
	}
	issueComments, ok := obj.ListComments()
	if !ok {
		return
	}
	reviewComments, ok := obj.ListReviewComments()
	if !ok {
		return
	}
	reviews, ok := obj.ListReviews()
	if !ok {
		return
	}
	commentsFromIssueComments := c.FromIssueComments(issueComments)
	comments := append(commentsFromIssueComments, c.FromReviewComments(reviewComments)...)
	comments = append(comments, c.FromReviews(reviews)...)
	sort.SliceStable(comments, func(i, j int) bool {
		return comments[i].CreatedAt.Before(*comments[j].CreatedAt)
	})
	approveComments := getApproveComments(comments)

	approversHandler := approvers.NewApprovers(
		approvers.NewOwners(
			filenames,
			approvers.NewRepoAlias(h.features.Repos, *h.features.Aliases),
			int64(*obj.Issue.Number)))
	approversHandler.AssociatedIssue = findAssociatedIssue(obj.Issue.Body)
	addApprovers(&approversHandler, approveComments)
	// Author implicitly approves their own PR
	if obj.Issue.User != nil && obj.Issue.User.Login != nil {
		url := ""
		if obj.Issue.HTMLURL != nil {
			// Append extra # so that it doesn't reload the page.
			url = *obj.Issue.HTMLURL + "#"
		}
		approversHandler.AddAuthorSelfApprover(*obj.Issue.User.Login, url)
	}

	for _, user := range obj.Issue.Assignees {
		if user != nil && user.Login != nil {
			approversHandler.AddAssignees(*user.Login)
		}
	}

	notificationMatcher := c.MungerNotificationName(approvers.ApprovalNotificationName)

	latestNotification := c.FilterComments(commentsFromIssueComments, notificationMatcher).GetLast()
	latestApprove := approveComments.GetLast()
	newMessage := h.updateNotification(obj.Org(), obj.Project(), latestNotification, latestApprove, approversHandler)
	if newMessage != nil {
		if latestNotification != nil {
			obj.DeleteComment(latestNotification.Source.(*githubapi.IssueComment))
		}
		obj.WriteComment(*newMessage)
	}

	if !approversHandler.IsApprovedWithIssue() {
		if obj.HasLabel(approvedLabel) && !humanAddedApproved(obj) {
			obj.RemoveLabel(approvedLabel)
		}
	} else {
		//pr is fully approved
		if !obj.HasLabel(approvedLabel) {
			obj.AddLabel(approvedLabel)
		}
	}

}

func humanAddedApproved(obj *github.MungeObject) bool {
	events, ok := obj.GetEvents()
	if !ok {
		return false
	}
	approveAddedMatcher := event.And([]event.Matcher{event.AddLabel{}, event.LabelName(approvedLabel)})
	labelEvents := event.FilterEvents(events, approveAddedMatcher)
	lastAdded := labelEvents.GetLast()
	if lastAdded == nil || lastAdded.Actor == nil || lastAdded.Actor.Login == nil {
		return false
	}
	return *lastAdded.Actor.Login != botName
}

func getApproveComments(comments []*c.Comment) c.FilteredComments {
	approverMatcher := c.CommandName(approveCommand)
	lgtmMatcher := c.CommandName(lgtmLabel)
	return c.FilterComments(comments, c.And{c.HumanActor(), c.Or{approverMatcher, lgtmMatcher}})
}

func (h *ApprovalHandler) updateNotification(org, project string, latestNotification, latestApprove *c.Comment, approversHandler approvers.Approvers) *string {
	if latestNotification != nil && (latestApprove == nil || latestApprove.CreatedAt.Before(*latestNotification.CreatedAt)) {
		// if we have an existing notification AND
		// the latestApprove happened before we updated
		// the notification, we do NOT need to update
		return nil
	}
	return approvers.GetMessage(approversHandler, org, project)
}

// addApprovers iterates through the list of comments on a PR
// and identifies all of the people that have said /approve and adds
// them to the Approvers.  The function uses the latest approve or cancel comment
// to determine the Users intention
func addApprovers(approversHandler *approvers.Approvers, approveComments c.FilteredComments) {
	for _, comment := range approveComments {
		commands := c.ParseCommands(comment)
		for _, cmd := range commands {
			if cmd.Name != approveCommand && cmd.Name != lgtmCommand {
				continue
			}
			if comment.Author == nil {
				continue
			}

			if cmd.Arguments == cancelArgument {
				approversHandler.RemoveApprover(*comment.Author)
			} else {
				url := ""
				if comment.HTMLURL != nil {
					url = *comment.HTMLURL
				}

				if cmd.Name == approveCommand {
					approversHandler.AddApprover(
						*comment.Author,
						url,
						cmd.Arguments == noIssueArgument,
					)
				} else {
					approversHandler.AddLGTMer(
						*comment.Author,
						url,
						cmd.Arguments == noIssueArgument,
					)
				}

			}
		}
	}
}
<commit_msg>Fix approval notification matching bug.<commit_after>/*
Copyright 2016 The Kubernetes Authors.

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

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

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

package mungers

import (
	"regexp"
	"sort"
	"strconv"

	githubapi "github.com/google/go-github/github"
	"github.com/spf13/cobra"

	"k8s.io/test-infra/mungegithub/features"
	"k8s.io/test-infra/mungegithub/github"
	"k8s.io/test-infra/mungegithub/mungers/approvers"
	c "k8s.io/test-infra/mungegithub/mungers/matchers/comment"
	"k8s.io/test-infra/mungegithub/mungers/matchers/event"
)

const (
	approveCommand  = "APPROVE"
	lgtmCommand     = "LGTM"
	cancelArgument  = "cancel"
	noIssueArgument = "no-issue"
)

var AssociatedIssueRegex = regexp.MustCompile(`(?:kubernetes/[^/]+/issues/|#)(\d+)`)

// ApprovalHandler will try to add "approved" label once
// all files of change has been approved by approvers.
type ApprovalHandler struct {
	features *features.Features
}

func init() {
	h := &ApprovalHandler{}
	RegisterMungerOrDie(h)
}

// Name is the name usable in --pr-mungers
func (*ApprovalHandler) Name() string { return "approval-handler" }

// RequiredFeatures is a slice of 'features' that must be provided
func (*ApprovalHandler) RequiredFeatures() []string {
	return []string{features.RepoFeatureName, features.AliasesFeature}
}

// Initialize will initialize the munger
func (h *ApprovalHandler) Initialize(config *github.Config, features *features.Features) error {
	h.features = features
	return nil
}

// EachLoop is called at the start of every munge loop
func (*ApprovalHandler) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (*ApprovalHandler) AddFlags(cmd *cobra.Command, config *github.Config) {}

// Returns associated issue, or 0 if it can't find any.
// This is really simple, and could be improved later.
func findAssociatedIssue(body *string) int {
	if body == nil {
		return 0
	}
	match := AssociatedIssueRegex.FindStringSubmatch(*body)
	if len(match) == 0 {
		return 0
	}
	v, err := strconv.Atoi(match[1])
	if err != nil {
		return 0
	}
	return v
}

// Munge is the workhorse the will actually make updates to the PR
// The algorithm goes as:
// - Initially, we build an approverSet
//   - Go through all comments in order of creation.
//		 - (Issue/PR comments, PR review comments, and PR review bodies are considered as comments)
//	 - If anyone said "/approve" or "/lgtm", add them to approverSet.
// - Then, for each file, we see if any approver of this file is in approverSet and keep track of files without approval
//   - An approver of a file is defined as:
//     - Someone listed as an "approver" in an OWNERS file in the files directory OR
//     - in one of the file's parent directorie
// - Iff all files have been approved, the bot will add the "approved" label.
// - Iff a cancel command is found, that reviewer will be removed from the approverSet
// 	and the munger will remove the approved label if it has been applied
func (h *ApprovalHandler) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}
	filenames := []string{}
	files, ok := obj.ListFiles()
	if !ok {
		return
	}
	for _, fn := range files {
		filenames = append(filenames, *fn.Filename)
	}
	issueComments, ok := obj.ListComments()
	if !ok {
		return
	}
	reviewComments, ok := obj.ListReviewComments()
	if !ok {
		return
	}
	reviews, ok := obj.ListReviews()
	if !ok {
		return
	}
	commentsFromIssueComments := c.FromIssueComments(issueComments)
	comments := append(c.FromReviewComments(reviewComments), commentsFromIssueComments...)
	comments = append(comments, c.FromReviews(reviews)...)
	sort.SliceStable(comments, func(i, j int) bool {
		return comments[i].CreatedAt.Before(*comments[j].CreatedAt)
	})
	approveComments := getApproveComments(comments)

	approversHandler := approvers.NewApprovers(
		approvers.NewOwners(
			filenames,
			approvers.NewRepoAlias(h.features.Repos, *h.features.Aliases),
			int64(*obj.Issue.Number)))
	approversHandler.AssociatedIssue = findAssociatedIssue(obj.Issue.Body)
	addApprovers(&approversHandler, approveComments)
	// Author implicitly approves their own PR
	if obj.Issue.User != nil && obj.Issue.User.Login != nil {
		url := ""
		if obj.Issue.HTMLURL != nil {
			// Append extra # so that it doesn't reload the page.
			url = *obj.Issue.HTMLURL + "#"
		}
		approversHandler.AddAuthorSelfApprover(*obj.Issue.User.Login, url)
	}

	for _, user := range obj.Issue.Assignees {
		if user != nil && user.Login != nil {
			approversHandler.AddAssignees(*user.Login)
		}
	}

	notificationMatcher := c.MungerNotificationName(approvers.ApprovalNotificationName)

	notifications := c.FilterComments(commentsFromIssueComments, notificationMatcher)
	latestNotification := notifications.GetLast()
	latestApprove := approveComments.GetLast()
	newMessage := h.updateNotification(obj.Org(), obj.Project(), latestNotification, latestApprove, approversHandler)
	if newMessage != nil {
		for _, notif := range notifications {
			obj.DeleteComment(notif.Source.(*githubapi.IssueComment))
		}
		obj.WriteComment(*newMessage)
	}

	if !approversHandler.IsApprovedWithIssue() {
		if obj.HasLabel(approvedLabel) && !humanAddedApproved(obj) {
			obj.RemoveLabel(approvedLabel)
		}
	} else {
		//pr is fully approved
		if !obj.HasLabel(approvedLabel) {
			obj.AddLabel(approvedLabel)
		}
	}

}

func humanAddedApproved(obj *github.MungeObject) bool {
	events, ok := obj.GetEvents()
	if !ok {
		return false
	}
	approveAddedMatcher := event.And([]event.Matcher{event.AddLabel{}, event.LabelName(approvedLabel)})
	labelEvents := event.FilterEvents(events, approveAddedMatcher)
	lastAdded := labelEvents.GetLast()
	if lastAdded == nil || lastAdded.Actor == nil || lastAdded.Actor.Login == nil {
		return false
	}
	return *lastAdded.Actor.Login != botName
}

func getApproveComments(comments []*c.Comment) c.FilteredComments {
	approverMatcher := c.CommandName(approveCommand)
	lgtmMatcher := c.CommandName(lgtmLabel)
	return c.FilterComments(comments, c.And{c.HumanActor(), c.Or{approverMatcher, lgtmMatcher}})
}

func (h *ApprovalHandler) updateNotification(org, project string, latestNotification, latestApprove *c.Comment, approversHandler approvers.Approvers) *string {
	if latestNotification != nil && (latestApprove == nil || latestApprove.CreatedAt.Before(*latestNotification.CreatedAt)) {
		// if we have an existing notification AND
		// the latestApprove happened before we updated
		// the notification, we do NOT need to update
		return nil
	}
	return approvers.GetMessage(approversHandler, org, project)
}

// addApprovers iterates through the list of comments on a PR
// and identifies all of the people that have said /approve and adds
// them to the Approvers.  The function uses the latest approve or cancel comment
// to determine the Users intention
func addApprovers(approversHandler *approvers.Approvers, approveComments c.FilteredComments) {
	for _, comment := range approveComments {
		commands := c.ParseCommands(comment)
		for _, cmd := range commands {
			if cmd.Name != approveCommand && cmd.Name != lgtmCommand {
				continue
			}
			if comment.Author == nil {
				continue
			}

			if cmd.Arguments == cancelArgument {
				approversHandler.RemoveApprover(*comment.Author)
			} else {
				url := ""
				if comment.HTMLURL != nil {
					url = *comment.HTMLURL
				}

				if cmd.Name == approveCommand {
					approversHandler.AddApprover(
						*comment.Author,
						url,
						cmd.Arguments == noIssueArgument,
					)
				} else {
					approversHandler.AddLGTMer(
						*comment.Author,
						url,
						cmd.Arguments == noIssueArgument,
					)
				}

			}
		}
	}
}
<|endoftext|>


<commit_before>package v1payload

//DatasetCreateInput is used as input to dataset creation
type DatasetCreateInput struct{}

//DatasetCreateOutput is returned from creating a dataset
type DatasetCreateOutput struct {
	Dataset
}

//DatasetDescribeOutput is returned from a specific dataset
type DatasetDescribeOutput struct {
	Dataset
}

//DatasetListOutput is returned from the dataset listing
type DatasetListOutput struct {
	Datasets []*Dataset `json:"datasets"`
}

//Dataset is a dataset in the list output
type Dataset struct {
	ProjectID string `json:"project_id"`
	DatasetID string `json:"dataset_id"`
	Bucket    string `json:"bucket"`
	Root      string `json:"root"`
}
<commit_msg>added starter dataset payloads<commit_after>package v1payload

//CreateDatasetInput is used as input to dataset creation
type CreateDatasetInput struct{}

//CreateDatasetOutput is returned from creating a dataset
type CreateDatasetOutput struct {
	DatasetSummary
}

//DescribeDatasetInput is input for queue creation
type DescribeDatasetInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	QueueID   string `json:"queue_id" valid:"required"`
	DatasetID int64  `json:"dataset_id" valid:"required"`
}

//DescribeDatasetOutput is output for queue creation
type DescribeDatasetOutput struct {
	TaskSummary
}

//ListDatasetsInput is input for queue creation
type ListDatasetsInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	QueueID   string `json:"queue_id" valid:"required"`
}

//DatasetSummary is a small version of
type DatasetSummary struct {
	DatasetID string `json:"dataset_id"`
	QueueID   string `json:"queue_id"`
}

//ListDatasetsOutput is output for queue creation
type ListDatasetsOutput struct {
	Datasets []*DatasetSummary
}
<|endoftext|>