<commit_before>
package main

import (
	"fmt"
	"strings"
	"strconv"
	"errors"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

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

type Employee struct {
	Name string `json:"name"`
	EmployeeId int `json:"employeeId"`
	Project string `json:"project"`
}

type Customer struct {
	Name string `json:"name"`
	CustomerId int `json:"customerId"`
}
type Project struct {
	Name string `json:"name"`
	ProjectId int `json:"projectId"`
	CustomerOf string `json:"customerOf"`
	StartTime string `json:"startDate"`
	EndTime string `json:"endDate"`
}

type EmployeeEfforts struct{
	Efforts string
	Project string
}

type ProjectEfforts struct{
	Efforts string
	Employee string
}

type EmployeeInvoice struct{
	List []EmployeeEfforts
}
type ProjectInvoice struct{
	List []ProjectEfforts
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Init is running " + function)
    return nil,nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {

    fmt.Println("Invoke is running " + function)

    if function =="initEmployee"{
		return t.initEmployee(stub,args)
	}else if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="initCustomer"{
		return t.initCustomer(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="initProject"{
		return t.initProject(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}else if function =="changeProject"{
		return t.changeProject(stub,args)
	}else if function =="submitEfforts"{
		return t.submitEfforts(stub,args)
	}
	return nil,errors.New("Received unknown function invocation")
}

func (t *SimpleChaincode) submitEfforts(stub shim.ChaincodeStubInterface, args []string)([]byte,error){
	if len(args)!=4{
		return nil,errors.New("Incorrect Number of arguments. Expecting 4")
	}
	fmt.Println("- start submitEfforts -")
	employeeId := args[0]
	timestamp := args[1]
	employeeIdAndTimestamp := args[2]
	efforts := args[3]
	employeeJSONasBytes,err := stub.GetState(employeeId)

	if err != nil {
		return nil,err
	}
	var e Employee
	json.Unmarshal(employeeJSONasBytes,&e)

	var ei EmployeeInvoice
	var pi ProjectInvoice

	employeeInvoiceAsBytes,err := stub.GetState(employeeIdAndTimestamp)

	if err != nil{
		return nil,err
	}
	json.Unmarshal(employeeInvoiceAsBytes,&ei)

	var ef EmployeeEfforts
	ef = EmployeeEfforts{efforts,e.Project}
	ei.List = append(ei.List,ef)

	employeeInvoiceAsBytes,err = json.Marshal(ei)
	if err!= nil{
		return nil,err
	}
	err = stub.PutState(employeeIdAndTimestamp,employeeInvoiceAsBytes)
	if err !=nil{
		return nil,err
	}

	var projectIdAndTimestamp string
	projectIdAndTimestamp = e.Project+""+timestamp

	projectInvoiceAsBytes,err := stub.GetState(projectIdAndTimestamp)

	json.Unmarshal(projectInvoiceAsBytes,&pi)

	var pf ProjectEfforts
	pf = ProjectEfforts{efforts,employeeId}
	pi.List = append(pi.List,pf)

	projectInvoiceAsBytes,err = json.Marshal(pi)

	if err!= nil{
		return nil,err
	}

	err = stub.PutState(projectIdAndTimestamp,projectInvoiceAsBytes)

	if err!= nil{
		return nil,err
	}

	return nil,nil
}
func (t *SimpleChaincode) changeProject(stub shim.ChaincodeStubInterface, args []string)([]byte,error){
	if len(args)!=2 {
		return nil,errors.New("Incorrect Number of arguments. Expecting 2")
	}
	// ==== Input sanitation ====
	fmt.Println("- start changeProject")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	employeeId := args[0]
	project := strings.ToLower(args[1])
	_, err := strconv.Atoi(project)

	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}
	_, err = strconv.Atoi(employeeId)

	if err != nil {
		return nil,errors.New("1st argument must be a numeric string")
	}

	_, err = stub.GetState(project)
	if err != nil {
		return nil,err
	}

	employee, err := stub.GetState(employeeId)
	if err != nil {
		return nil,err
	}

	var e Employee

	json.Unmarshal(employee,&e)
	e.Project = project
	fmt.Println(e)

	employeeJSONasBytes, err := json.Marshal(e)
	fmt.Println(employeeJSONasBytes)
	if err != nil {
		return nil,err
	}
	err = stub.PutState(employeeId, employeeJSONasBytes)

	if err != nil {
		return nil,err
	}
	return nil,nil
}
func (t *SimpleChaincode) initProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 5 {
		return nil,errors.New("Incorrect number of arguments. Expecting 5")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initProject")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}
	if len(args[3]) <= 0 {
		return nil,errors.New("4th argument must be a non-empty string")
	}
	if len(args[4]) <= 0 {
		return nil,errors.New("5th argument must be a non-empty string")
	}

	projectName := args[0]
	customerOf := strings.ToLower(args[2])
	projectId, err := strconv.Atoi(args[1])
	projectIdAsString := args[1]
	startDate:= args[3]
	endDate:= args[4]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	projectAsBytes, err := stub.GetState(projectIdAsString)
	if err != nil {
		return nil,err
	} else if projectAsBytes != nil {
		fmt.Println("This project already exists: " + projectIdAsString)
		return nil, errors.New("This project already exists "+projectIdAsString)
	}

	project:= Project{projectName,projectId,customerOf,startDate,endDate}

	projectJSONasBytes, err := json.Marshal(project)

	if err != nil {
		return nil,err
	}
	err = stub.PutState(projectIdAsString, projectJSONasBytes)

	if err != nil {
		return nil,err
	}

	// composite key creation for searching projects according to customer
	/*
	indexName := "customerOf"
	customerOfIndexKey, err := stub.CreateCompositeKey(indexName, []string{customerOf, projectIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(customerOfIndexKey, value)
    */
	fmt.Println("- end initProject")
	return nil,nil
}

func (t *SimpleChaincode) getProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	projectId := args[0]
	project, err := stub.GetState(projectId)
	if err != nil {
		return nil,err
	}

	return project,nil
}

func (t *SimpleChaincode) getCustomer(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	customerId := args[0]
	customer, err := stub.GetState(customerId)
	if err != nil {
		return nil,err
	}

	return customer,nil
}

func (t *SimpleChaincode) initCustomer(stub shim.ChaincodeStubInterface,args []string) ([]byte,error) {
		if len(args) != 2{
			return nil,errors.New("Incorrect number of arguments. Expecting 2")
		}
			// ==== Input sanitation ====
		fmt.Println("- start initCustomer")
		if len(args[0]) <= 0 {
			return nil,errors.New("1st argument must be a non-empty string")
		}
		if len(args[1]) <= 0 {
			return nil,errors.New("2nd argument must be a non-empty string")
		}

		customerName := args[0]
		customerId, err := strconv.Atoi(args[1])
		customerIdAsString := args[1]
		if err != nil {
			return nil,errors.New("2nd argument must be a numeric string")
		}
		customerAsBytes, err := stub.GetState(customerIdAsString)
		if err != nil {
			 return nil,err
		} else if customerAsBytes != nil {
			fmt.Println("This customer already exists: " + customerIdAsString)
			return nil,errors.New("This customer already exists: "+customerIdAsString)
		}

		customer:= Customer{customerName,customerId}

		customerJSONasBytes, err := json.Marshal(customer)

		if err != nil {
			return nil,err
		}
		err = stub.PutState(customerIdAsString, customerJSONasBytes)

		if err != nil {
			return nil,err
		}
		stub.SetEvent("customerAdded",[]byte(customerName))
		fmt.Println("- end initCustomer")
		return nil,nil
}

func (t *SimpleChaincode) initEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 3 {
		return nil,errors.New("Incorrect number of arguments. Expecting 3")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initEmployee")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}

	employeeName := args[0]
	project := strings.ToLower(args[2])
	employeeId, err := strconv.Atoi(args[1])
	employeeIdAsString := args[1]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	employeeAsBytes, err := stub.GetState(employeeIdAsString)
	if err != nil {
		return nil,err
	} else if employeeAsBytes != nil {
		fmt.Println("This employee already exists: " + employeeIdAsString)
		return []byte("duplicate"),errors.New("This employee already exists: "+employeeIdAsString)
	}

	employee:= Employee{employeeName,employeeId,project}
	fmt.Println(employee)
	employeeJSONasBytes, err := json.Marshal(employee)
	fmt.Println(employeeJSONasBytes)
	if err != nil {
		return nil,err
	}
	err = stub.PutState(employeeIdAsString, employeeJSONasBytes)

	if err != nil {
		return nil,err
	}
	employee_temp,_ := stub.GetState(employeeIdAsString)
	fmt.Println(employee_temp)
	// composite key to get employees by project

	/*
	indexName := "project"
	projectIndexKey, err := stub.CreateCompositeKey(indexName, []string{project, employeeIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(projectIndexKey, value)
	*/
	fmt.Println("- end initEmployee")
	return nil,nil
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Query is running " + function)

    if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}else if function == "getEfforts"{
		return t.getEfforts(stub,args)
	}

	return nil,errors.New("Received unknown function query")
}
func (t *SimpleChaincode) getEfforts(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	fmt.Printf("getEfforts called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	idAndTimestamp := args[0]
	invoice, err := stub.GetState(idAndTimestamp)
	fmt.Println(invoice)
	if err != nil {
		return nil,err
	}

	return invoice,nil
}
func (t *SimpleChaincode) getEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	fmt.Printf("getEmployee called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	employeeId := args[0]
	employee, err := stub.GetState(employeeId)
	fmt.Println(employee)
	if err != nil {
		return nil,err
	}

	return employee,nil
}

func main() {
    	err := shim.Start(new(SimpleChaincode))
    if err != nil {
        fmt.Printf("Error starting Simple chaincode: %s", err)
    }
}
<commit_msg>customer events added<commit_after>
package main

import (
	"fmt"
	"strings"
	"strconv"
	"errors"
	"encoding/json"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

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

type Employee struct {
	Name string `json:"name"`
	EmployeeId int `json:"employeeId"`
	Project string `json:"project"`
}

type Customer struct {
	Name string `json:"name"`
	CustomerId int `json:"customerId"`
}
type Project struct {
	Name string `json:"name"`
	ProjectId int `json:"projectId"`
	CustomerOf string `json:"customerOf"`
	StartTime string `json:"startDate"`
	EndTime string `json:"endDate"`
}

type EmployeeEfforts struct{
	Efforts string
	Project string
}

type ProjectEfforts struct{
	Efforts string
	Employee string
}

type EmployeeInvoice struct{
	List []EmployeeEfforts
}
type ProjectInvoice struct{
	List []ProjectEfforts
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Init is running " + function)
    return nil,nil
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {

    fmt.Println("Invoke is running " + function)

    if function =="initEmployee"{
		return t.initEmployee(stub,args)
	}else if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="initCustomer"{
		return t.initCustomer(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="initProject"{
		return t.initProject(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}else if function =="changeProject"{
		return t.changeProject(stub,args)
	}else if function =="submitEfforts"{
		return t.submitEfforts(stub,args)
	}
	return nil,errors.New("Received unknown function invocation")
}

func (t *SimpleChaincode) submitEfforts(stub shim.ChaincodeStubInterface, args []string)([]byte,error){
	if len(args)!=4{
		return nil,errors.New("Incorrect Number of arguments. Expecting 4")
	}
	fmt.Println("- start submitEfforts -")
	employeeId := args[0]
	timestamp := args[1]
	employeeIdAndTimestamp := args[2]
	efforts := args[3]
	employeeJSONasBytes,err := stub.GetState(employeeId)

	if err != nil {
		return nil,err
	}
	var e Employee
	json.Unmarshal(employeeJSONasBytes,&e)

	var ei EmployeeInvoice
	var pi ProjectInvoice

	employeeInvoiceAsBytes,err := stub.GetState(employeeIdAndTimestamp)

	if err != nil{
		return nil,err
	}
	json.Unmarshal(employeeInvoiceAsBytes,&ei)

	var ef EmployeeEfforts
	ef = EmployeeEfforts{efforts,e.Project}
	ei.List = append(ei.List,ef)

	employeeInvoiceAsBytes,err = json.Marshal(ei)
	if err!= nil{
		return nil,err
	}
	err = stub.PutState(employeeIdAndTimestamp,employeeInvoiceAsBytes)
	if err !=nil{
		return nil,err
	}

	var projectIdAndTimestamp string
	projectIdAndTimestamp = e.Project+""+timestamp

	projectInvoiceAsBytes,err := stub.GetState(projectIdAndTimestamp)

	json.Unmarshal(projectInvoiceAsBytes,&pi)

	var pf ProjectEfforts
	pf = ProjectEfforts{efforts,employeeId}
	pi.List = append(pi.List,pf)

	projectInvoiceAsBytes,err = json.Marshal(pi)

	if err!= nil{
		return nil,err
	}

	err = stub.PutState(projectIdAndTimestamp,projectInvoiceAsBytes)

	if err!= nil{
		return nil,err
	}

	return nil,nil
}
func (t *SimpleChaincode) changeProject(stub shim.ChaincodeStubInterface, args []string)([]byte,error){
	if len(args)!=2 {
		return nil,errors.New("Incorrect Number of arguments. Expecting 2")
	}
	// ==== Input sanitation ====
	fmt.Println("- start changeProject")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	employeeId := args[0]
	project := strings.ToLower(args[1])
	_, err := strconv.Atoi(project)

	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}
	_, err = strconv.Atoi(employeeId)

	if err != nil {
		return nil,errors.New("1st argument must be a numeric string")
	}

	_, err = stub.GetState(project)
	if err != nil {
		return nil,err
	}

	employee, err := stub.GetState(employeeId)
	if err != nil {
		return nil,err
	}

	var e Employee

	json.Unmarshal(employee,&e)
	e.Project = project
	fmt.Println(e)

	employeeJSONasBytes, err := json.Marshal(e)
	fmt.Println(employeeJSONasBytes)
	if err != nil {
		return nil,err
	}
	err = stub.PutState(employeeId, employeeJSONasBytes)

	if err != nil {
		return nil,err
	}
	return nil,nil
}
func (t *SimpleChaincode) initProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 5 {
		return nil,errors.New("Incorrect number of arguments. Expecting 5")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initProject")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}
	if len(args[3]) <= 0 {
		return nil,errors.New("4th argument must be a non-empty string")
	}
	if len(args[4]) <= 0 {
		return nil,errors.New("5th argument must be a non-empty string")
	}

	projectName := args[0]
	customerOf := strings.ToLower(args[2])
	projectId, err := strconv.Atoi(args[1])
	projectIdAsString := args[1]
	startDate:= args[3]
	endDate:= args[4]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	projectAsBytes, err := stub.GetState(projectIdAsString)
	if err != nil {
		return nil,err
	} else if projectAsBytes != nil {
		fmt.Println("This project already exists: " + projectIdAsString)
		return nil, errors.New("This project already exists "+projectIdAsString)
	}

	project:= Project{projectName,projectId,customerOf,startDate,endDate}

	projectJSONasBytes, err := json.Marshal(project)

	if err != nil {
		return nil,err
	}
	err = stub.PutState(projectIdAsString, projectJSONasBytes)

	if err != nil {
		return nil,err
	}

	// composite key creation for searching projects according to customer
	/*
	indexName := "customerOf"
	customerOfIndexKey, err := stub.CreateCompositeKey(indexName, []string{customerOf, projectIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(customerOfIndexKey, value)
    */
	fmt.Println("- end initProject")
	return nil,nil
}

func (t *SimpleChaincode) getProject(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	projectId := args[0]
	project, err := stub.GetState(projectId)
	if err != nil {
		return nil,err
	}

	return project,nil
}

func (t *SimpleChaincode) getCustomer(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	customerId := args[0]
	customer, err := stub.GetState(customerId)
	if err != nil {
		return nil,err
	}

	return customer,nil
}

func (t *SimpleChaincode) initCustomer(stub shim.ChaincodeStubInterface,args []string) ([]byte,error) {
		if len(args) != 2{
			return nil,errors.New("Incorrect number of arguments. Expecting 2")
		}
			// ==== Input sanitation ====
		fmt.Println("- start initCustomer")
		if len(args[0]) <= 0 {
			return nil,errors.New("1st argument must be a non-empty string")
		}
		if len(args[1]) <= 0 {
			return nil,errors.New("2nd argument must be a non-empty string")
		}

		customerName := args[0]
		customerId, err := strconv.Atoi(args[1])
		customerIdAsString := args[1]
		if err != nil {
			return nil,errors.New("2nd argument must be a numeric string")
		}
		customerAsBytes, err := stub.GetState(customerIdAsString)
		if err != nil {
			 return nil,err
		} else if customerAsBytes != nil {
			fmt.Println("This customer already exists: " + customerIdAsString)
			return nil,errors.New("This customer already exists: "+customerIdAsString)
		}

		customer:= Customer{customerName,customerId}

		customerJSONasBytes, err := json.Marshal(customer)

		if err != nil {
			return nil,err
		}
		err = stub.PutState(customerIdAsString, customerJSONasBytes)

		if err != nil {
			return nil,err
		}
		stub.SetEvent("customerAdded",customerJSONasBytes)
		fmt.Println("- end initCustomer")
		return nil,nil
}

func (t *SimpleChaincode) initEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){

	if len(args) != 3 {
		return nil,errors.New("Incorrect number of arguments. Expecting 3")
	}
	// ==== Input sanitation ====
	fmt.Println("- start initEmployee")
	if len(args[0]) <= 0 {
		return nil,errors.New("1st argument must be a non-empty string")
	}
	if len(args[1]) <= 0 {
		return nil,errors.New("2nd argument must be a non-empty string")
	}
	if len(args[2]) <= 0 {
		return nil,errors.New("3rd argument must be a non-empty string")
	}

	employeeName := args[0]
	project := strings.ToLower(args[2])
	employeeId, err := strconv.Atoi(args[1])
	employeeIdAsString := args[1]
	if err != nil {
		return nil,errors.New("2nd argument must be a numeric string")
	}

	employeeAsBytes, err := stub.GetState(employeeIdAsString)
	if err != nil {
		return nil,err
	} else if employeeAsBytes != nil {
		fmt.Println("This employee already exists: " + employeeIdAsString)
		return []byte("duplicate"),errors.New("This employee already exists: "+employeeIdAsString)
	}

	employee:= Employee{employeeName,employeeId,project}
	fmt.Println(employee)
	employeeJSONasBytes, err := json.Marshal(employee)
	fmt.Println(employeeJSONasBytes)
	if err != nil {
		return nil,err
	}
	err = stub.PutState(employeeIdAsString, employeeJSONasBytes)

	if err != nil {
		return nil,err
	}
	employee_temp,_ := stub.GetState(employeeIdAsString)
	fmt.Println(employee_temp)
	// composite key to get employees by project

	/*
	indexName := "project"
	projectIndexKey, err := stub.CreateCompositeKey(indexName, []string{project, employeeIdAsString})
	if err != nil {
		return nil,err
	}

	value := []byte{0x00}
	stub.PutState(projectIndexKey, value)
	*/
	fmt.Println("- end initEmployee")
	return nil,nil
}

func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte,error) {
    fmt.Println("Query is running " + function)

    if function =="getEmployee"{
		return t.getEmployee(stub,args)
	}else if function =="getCustomer"{
		return t.getCustomer(stub,args)
	}else if function =="getProject"{
		return t.getProject(stub,args)
	}else if function == "getEfforts"{
		return t.getEfforts(stub,args)
	}

	return nil,errors.New("Received unknown function query")
}
func (t *SimpleChaincode) getEfforts(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	fmt.Printf("getEfforts called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	idAndTimestamp := args[0]
	invoice, err := stub.GetState(idAndTimestamp)
	fmt.Println(invoice)
	if err != nil {
		return nil,err
	}

	return invoice,nil
}
func (t *SimpleChaincode) getEmployee(stub shim.ChaincodeStubInterface, args []string) ([]byte,error){
	fmt.Printf("getEmployee called")
	if len(args) !=1{
		return nil,errors.New("Incorrect number of arguments. Expecting 1")
	}
	employeeId := args[0]
	employee, err := stub.GetState(employeeId)
	fmt.Println(employee)
	if err != nil {
		return nil,err
	}

	return employee,nil
}

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


<commit_before>/*
Copyright 2014 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 intstr

import (
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"runtime/debug"
	"strconv"
	"strings"

	"github.com/google/gofuzz"
	"k8s.io/klog"
)

// IntOrString is a type that can hold an int32 or a string.  When used in
// JSON or YAML marshalling and unmarshalling, it produces or consumes the
// inner type.  This allows you to have, for example, a JSON field that can
// accept a name or number.
// TODO: Rename to Int32OrString
//
// +protobuf=true
// +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:openapi-gen=true
type IntOrString struct {
	Type   Type   `protobuf:"varint,1,opt,name=type,casttype=Type"`
	IntVal int32  `protobuf:"varint,2,opt,name=intVal"`
	StrVal string `protobuf:"bytes,3,opt,name=strVal"`
}

// Type represents the stored type of IntOrString.
type Type int

const (
	Int    Type = iota // The IntOrString holds an int.
	String             // The IntOrString holds a string.
)

// FromInt creates an IntOrString object with an int32 value. It is
// your responsibility not to call this method with a value greater
// than int32.
// TODO: convert to (val int32)
func FromInt(val int) IntOrString {
	if val > math.MaxInt32 || val < math.MinInt32 {
		klog.Errorf("value: %d overflows int32\n%s\n", val, debug.Stack())
	}
	return IntOrString{Type: Int, IntVal: int32(val)}
}

// FromString creates an IntOrString object with a string value.
func FromString(val string) IntOrString {
	return IntOrString{Type: String, StrVal: val}
}

// Parse the given string and try to convert it to an integer before
// setting it as a string value.
func Parse(val string) IntOrString {
	i, err := strconv.Atoi(val)
	if err != nil {
		return FromString(val)
	}
	return FromInt(i)
}

// UnmarshalJSON implements the json.Unmarshaller interface.
func (intstr *IntOrString) UnmarshalJSON(value []byte) error {
	if value[0] == '"' {
		intstr.Type = String
		return json.Unmarshal(value, &intstr.StrVal)
	}
	intstr.Type = Int
	return json.Unmarshal(value, &intstr.IntVal)
}

// String returns the string value, or the Itoa of the int value.
func (intstr *IntOrString) String() string {
	if intstr.Type == String {
		return intstr.StrVal
	}
	return strconv.Itoa(intstr.IntValue())
}

// IntValue returns the IntVal if type Int, or if
// it is a String, will attempt a conversion to int.
func (intstr *IntOrString) IntValue() int {
	if intstr.Type == String {
		i, _ := strconv.Atoi(intstr.StrVal)
		return i
	}
	return int(intstr.IntVal)
}

// MarshalJSON implements the json.Marshaller interface.
func (intstr IntOrString) MarshalJSON() ([]byte, error) {
	switch intstr.Type {
	case Int:
		return json.Marshal(intstr.IntVal)
	case String:
		return json.Marshal(intstr.StrVal)
	default:
		return []byte{}, fmt.Errorf("impossible IntOrString.Type")
	}
}

// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (_ IntOrString) OpenAPISchemaType() []string { return []string{"string"} }

// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (_ IntOrString) OpenAPISchemaFormat() string { return "int-or-string" }

func (intstr *IntOrString) Fuzz(c fuzz.Continue) {
	if intstr == nil {
		return
	}
	if c.RandBool() {
		intstr.Type = Int
		c.Fuzz(&intstr.IntVal)
		intstr.StrVal = ""
	} else {
		intstr.Type = String
		intstr.IntVal = 0
		c.Fuzz(&intstr.StrVal)
	}
}

func ValueOrDefault(intOrPercent *IntOrString, defaultValue IntOrString) *IntOrString {
	if intOrPercent == nil {
		return &defaultValue
	}
	return intOrPercent
}

func GetValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool) (int, error) {
	if intOrPercent == nil {
		return 0, errors.New("nil value for IntOrString")
	}
	value, isPercent, err := getIntOrPercentValue(intOrPercent)
	if err != nil {
		return 0, fmt.Errorf("invalid value for IntOrString: %v", err)
	}
	if isPercent {
		if roundUp {
			value = int(math.Ceil(float64(value) * (float64(total)) / 100))
		} else {
			value = int(math.Floor(float64(value) * (float64(total)) / 100))
		}
	}
	return value, nil
}

func getIntOrPercentValue(intOrStr *IntOrString) (int, bool, error) {
	switch intOrStr.Type {
	case Int:
		return intOrStr.IntValue(), false, nil
	case String:
		s := strings.Replace(intOrStr.StrVal, "%", "", -1)
		v, err := strconv.Atoi(s)
		if err != nil {
			return 0, false, fmt.Errorf("invalid value %q: %v", intOrStr.StrVal, err)
		}
		return int(v), true, nil
	}
	return 0, false, fmt.Errorf("invalid type: neither int nor percentage")
}
<commit_msg>staging file fix lint error: receiver name should not be an underscore and rename<commit_after>/*
Copyright 2014 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 intstr

import (
	"encoding/json"
	"errors"
	"fmt"
	"math"
	"runtime/debug"
	"strconv"
	"strings"

	"github.com/google/gofuzz"
	"k8s.io/klog"
)

// IntOrString is a type that can hold an int32 or a string.  When used in
// JSON or YAML marshalling and unmarshalling, it produces or consumes the
// inner type.  This allows you to have, for example, a JSON field that can
// accept a name or number.
// TODO: Rename to Int32OrString
//
// +protobuf=true
// +protobuf.options.(gogoproto.goproto_stringer)=false
// +k8s:openapi-gen=true
type IntOrString struct {
	Type   Type   `protobuf:"varint,1,opt,name=type,casttype=Type"`
	IntVal int32  `protobuf:"varint,2,opt,name=intVal"`
	StrVal string `protobuf:"bytes,3,opt,name=strVal"`
}

// Type represents the stored type of IntOrString.
type Type int

const (
	Int    Type = iota // The IntOrString holds an int.
	String             // The IntOrString holds a string.
)

// FromInt creates an IntOrString object with an int32 value. It is
// your responsibility not to call this method with a value greater
// than int32.
// TODO: convert to (val int32)
func FromInt(val int) IntOrString {
	if val > math.MaxInt32 || val < math.MinInt32 {
		klog.Errorf("value: %d overflows int32\n%s\n", val, debug.Stack())
	}
	return IntOrString{Type: Int, IntVal: int32(val)}
}

// FromString creates an IntOrString object with a string value.
func FromString(val string) IntOrString {
	return IntOrString{Type: String, StrVal: val}
}

// Parse the given string and try to convert it to an integer before
// setting it as a string value.
func Parse(val string) IntOrString {
	i, err := strconv.Atoi(val)
	if err != nil {
		return FromString(val)
	}
	return FromInt(i)
}

// UnmarshalJSON implements the json.Unmarshaller interface.
func (intstr *IntOrString) UnmarshalJSON(value []byte) error {
	if value[0] == '"' {
		intstr.Type = String
		return json.Unmarshal(value, &intstr.StrVal)
	}
	intstr.Type = Int
	return json.Unmarshal(value, &intstr.IntVal)
}

// String returns the string value, or the Itoa of the int value.
func (intstr *IntOrString) String() string {
	if intstr.Type == String {
		return intstr.StrVal
	}
	return strconv.Itoa(intstr.IntValue())
}

// IntValue returns the IntVal if type Int, or if
// it is a String, will attempt a conversion to int.
func (intstr *IntOrString) IntValue() int {
	if intstr.Type == String {
		i, _ := strconv.Atoi(intstr.StrVal)
		return i
	}
	return int(intstr.IntVal)
}

// MarshalJSON implements the json.Marshaller interface.
func (intstr IntOrString) MarshalJSON() ([]byte, error) {
	switch intstr.Type {
	case Int:
		return json.Marshal(intstr.IntVal)
	case String:
		return json.Marshal(intstr.StrVal)
	default:
		return []byte{}, fmt.Errorf("impossible IntOrString.Type")
	}
}

// OpenAPISchemaType is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
//
// See: https://github.com/kubernetes/kube-openapi/tree/master/pkg/generators
func (IntOrString) OpenAPISchemaType() []string { return []string{"string"} }

// OpenAPISchemaFormat is used by the kube-openapi generator when constructing
// the OpenAPI spec of this type.
func (IntOrString) OpenAPISchemaFormat() string { return "int-or-string" }

func (intstr *IntOrString) Fuzz(c fuzz.Continue) {
	if intstr == nil {
		return
	}
	if c.RandBool() {
		intstr.Type = Int
		c.Fuzz(&intstr.IntVal)
		intstr.StrVal = ""
	} else {
		intstr.Type = String
		intstr.IntVal = 0
		c.Fuzz(&intstr.StrVal)
	}
}

func ValueOrDefault(intOrPercent *IntOrString, defaultValue IntOrString) *IntOrString {
	if intOrPercent == nil {
		return &defaultValue
	}
	return intOrPercent
}

func GetValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool) (int, error) {
	if intOrPercent == nil {
		return 0, errors.New("nil value for IntOrString")
	}
	value, isPercent, err := getIntOrPercentValue(intOrPercent)
	if err != nil {
		return 0, fmt.Errorf("invalid value for IntOrString: %v", err)
	}
	if isPercent {
		if roundUp {
			value = int(math.Ceil(float64(value) * (float64(total)) / 100))
		} else {
			value = int(math.Floor(float64(value) * (float64(total)) / 100))
		}
	}
	return value, nil
}

func getIntOrPercentValue(intOrStr *IntOrString) (int, bool, error) {
	switch intOrStr.Type {
	case Int:
		return intOrStr.IntValue(), false, nil
	case String:
		s := strings.Replace(intOrStr.StrVal, "%", "", -1)
		v, err := strconv.Atoi(s)
		if err != nil {
			return 0, false, fmt.Errorf("invalid value %q: %v", intOrStr.StrVal, err)
		}
		return int(v), true, nil
	}
	return 0, false, fmt.Errorf("invalid type: neither int nor percentage")
}
<|endoftext|>


<commit_before>// Copyright 2018 Google LLC 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 google

import (
	"strings"
	"sync"

	"github.com/google/go-containerregistry/pkg/authn"
	"github.com/google/go-containerregistry/pkg/logs"
)

// Keychain exports an instance of the google Keychain.
var Keychain authn.Keychain = &googleKeychain{}

type googleKeychain struct {
	once sync.Once
	auth authn.Authenticator
}

// Resolve implements authn.Keychain a la docker-credential-gcr.
//
// This behaves similarly to the GCR credential helper, but reuses tokens until
// they expire.
//
// We can't easily add this behavior to our credential helper implementation
// of authn.Authenticator because the credential helper protocol doesn't include
// expiration information, see here:
// https://godoc.org/github.com/docker/docker-credential-helpers/credentials#Credentials
//
// In addition to being a performance optimization, the reuse of these access
// tokens works around a bug in gcloud. It appears that attempting to invoke
// `gcloud config config-helper` multiple times too quickly will fail:
// https://github.com/GoogleCloudPlatform/docker-credential-gcr/issues/54
//
// We could upstream this behavior into docker-credential-gcr by parsing
// gcloud's output and persisting its tokens across invocations, but then
// we have to deal with invalidating caches across multiple runs (no fun).
//
// In general, we don't worry about that here because we expect to use the same
// gcloud configuration in the scope of this one process.
func (gk *googleKeychain) Resolve(target authn.Resource) (authn.Authenticator, error) {
	// Only authenticate GCR and AR so it works with authn.NewMultiKeychain to fallback.
	host := target.RegistryStr()
	if host != "gcr.io" &&
		!strings.HasSuffix(host, ".gcr.io") &&
		!strings.HasSuffix(host, ".pkg.dev") &&
		!strings.HasSuffix(host, ".google.com") {
		return authn.Anonymous, nil
	}

	gk.once.Do(func() {
		gk.auth = resolve()
	})

	return gk.auth, nil
}

func resolve() authn.Authenticator {
	auth, envErr := NewEnvAuthenticator()
	if envErr == nil && auth != authn.Anonymous {
		return auth
	}

	auth, gErr := NewGcloudAuthenticator()
	if gErr == nil && auth != authn.Anonymous {
		return auth
	}

	logs.Debug.Println("Failed to get any Google credentials, falling back to Anonymous")
	if envErr != nil {
		logs.Debug.Printf("Google env error: %v", envErr)
	}
	if gErr != nil {
		logs.Debug.Printf("gcloud error: %v", gErr)
	}
	return authn.Anonymous
}
<commit_msg>Add debug logs to google.Keychain (#1390)<commit_after>// Copyright 2018 Google LLC 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 google

import (
	"strings"
	"sync"

	"github.com/google/go-containerregistry/pkg/authn"
	"github.com/google/go-containerregistry/pkg/logs"
)

// Keychain exports an instance of the google Keychain.
var Keychain authn.Keychain = &googleKeychain{}

type googleKeychain struct {
	once sync.Once
	auth authn.Authenticator
}

// Resolve implements authn.Keychain a la docker-credential-gcr.
//
// This behaves similarly to the GCR credential helper, but reuses tokens until
// they expire.
//
// We can't easily add this behavior to our credential helper implementation
// of authn.Authenticator because the credential helper protocol doesn't include
// expiration information, see here:
// https://godoc.org/github.com/docker/docker-credential-helpers/credentials#Credentials
//
// In addition to being a performance optimization, the reuse of these access
// tokens works around a bug in gcloud. It appears that attempting to invoke
// `gcloud config config-helper` multiple times too quickly will fail:
// https://github.com/GoogleCloudPlatform/docker-credential-gcr/issues/54
//
// We could upstream this behavior into docker-credential-gcr by parsing
// gcloud's output and persisting its tokens across invocations, but then
// we have to deal with invalidating caches across multiple runs (no fun).
//
// In general, we don't worry about that here because we expect to use the same
// gcloud configuration in the scope of this one process.
func (gk *googleKeychain) Resolve(target authn.Resource) (authn.Authenticator, error) {
	// Only authenticate GCR and AR so it works with authn.NewMultiKeychain to fallback.
	host := target.RegistryStr()
	if host != "gcr.io" &&
		!strings.HasSuffix(host, ".gcr.io") &&
		!strings.HasSuffix(host, ".pkg.dev") &&
		!strings.HasSuffix(host, ".google.com") {
		return authn.Anonymous, nil
	}

	gk.once.Do(func() {
		gk.auth = resolve()
	})

	return gk.auth, nil
}

func resolve() authn.Authenticator {
	auth, envErr := NewEnvAuthenticator()
	if envErr == nil && auth != authn.Anonymous {
		logs.Debug.Println("google.Keychain: using Application Default Credentials")
		return auth
	}

	auth, gErr := NewGcloudAuthenticator()
	if gErr == nil && auth != authn.Anonymous {
		logs.Debug.Println("google.Keychain: using gcloud fallback")
		return auth
	}

	logs.Debug.Println("Failed to get any Google credentials, falling back to Anonymous")
	if envErr != nil {
		logs.Debug.Printf("Google env error: %v", envErr)
	}
	if gErr != nil {
		logs.Debug.Printf("gcloud error: %v", gErr)
	}
	return authn.Anonymous
}
<|endoftext|>


<commit_before>/*** Copyright (c) 2016, University of Florida Research Foundation, Inc. ***
 *** For more information please refer to the LICENSE.md file            ***/

// Package gorods is a Golang binding for the iRods C API (iRods client library).
// GoRods uses cgo to call iRods client functions.
package gorods

// #include "wrapper.h"
import "C"

import (
	"fmt"
	"strings"
	"unsafe"
)

type User struct {
	Name string
	Zone string // need to convert to zone obj

	Init bool

	Groups Groups
	Con    *Connection
}

type Users []*User

// initUser
func initUser(name string, zone string, con *Connection) (*User, error) {

	usr := new(User)

	usr.Name = name
	usr.Zone = zone
	usr.Con = con

	if err := usr.init(); err != nil {
		return nil, err
	}

	return usr, nil
}

func (usr *User) init() error {
	if !usr.Init {
		if err := usr.RefreshInfo(); err != nil {
			return err
		}
		// Need to implement getgroups
		// if err := usr.RefreshGroups(); err != nil {
		// 	return err
		// }
		usr.Init = true
	}

	return nil
}

func (usr *User) RefreshInfo() error {
	// r_comment:
	// create_ts:01471444167
	// modify_ts:01471444167
	// user_id:10019
	// user_name:designers
	// user_type_name:rodsgroup
	// zone_name:tempZone
	// user_info:
	if _, err := usr.GetInfo(); err == nil {
		// usr.Comment = infoMap["r_comment"]
		// usr.CreateTime = TimeStringToTime(infoMap["create_ts"])
		// usr.ModifyTime = TimeStringToTime(infoMap["modify_ts"])
		// usr.Id, _ = strconv.Atoi(infoMap["user_id"])
		// usr.Type = infoMap["user_type_name"]
		// //usr.Zone = infoMap["zone_name"]
		// usr.Info = infoMap["user_info"]
	} else {
		return err
	}

	return nil
}

func (usrs Users) FindByName(name string) *User {
	for _, usr := range usrs {
		if usr.Name == name {
			return usr
		}
	}
	return nil
}

func (usr *User) String() string {
	return fmt.Sprintf("%v#%v", usr.Name, usr.Zone)
}

func (usr *User) GetInfo() (map[string]string, error) {
	var (
		result C.goRodsStringResult_t
		err    *C.char
	)

	result.size = C.int(0)

	cUser := C.CString(usr.Name)
	defer C.free(unsafe.Pointer(cUser))

	ccon := usr.Con.GetCcon()
	defer usr.Con.ReturnCcon(ccon)

	if status := C.gorods_get_user(cUser, ccon, &result, &err); status != 0 {
		return nil, newError(Fatal, fmt.Sprintf("iRods Get Users Failed: %v", C.GoString(err)))
	}

	unsafeArr := unsafe.Pointer(result.strArr)
	arrLen := int(result.size)

	// Convert C array to slice, backed by arr *C.char
	slice := (*[1 << 30]*C.char)(unsafeArr)[:arrLen:arrLen]

	//response := make(Users, 0)
	response := make(map[string]string)

	for _, userInfo := range slice {

		userAttributes := strings.Split(strings.Trim(C.GoString(userInfo), " \n"), "\n")

		for _, attr := range userAttributes {

			split := strings.Split(attr, ": ")

			attrName := split[0]
			attrVal := split[1]

			response[attrName] = attrVal

		}

	}

	C.gorods_free_string_result(&result)

	return response, nil
}

func (usr *User) AddToGroup(grp interface{}) error {

	switch grp.(type) {
	case string:
		return AddToGroup(usr.Name, usr.Zone, grp.(string), usr.Con)
	case *Group:
		return AddToGroup(usr.Name, usr.Zone, (grp.(*Group)).Name, usr.Con)
	default:
	}

	return newError(Fatal, fmt.Sprintf("iRods AddToGroup Failed: unknown type passed"))
}

func (usr *User) RemoveFromGroup(grp interface{}) error {
	switch grp.(type) {
	case string:
		return RemoveFromGroup(usr.Name, usr.Zone, grp.(string), usr.Con)
	case *Group:
		return RemoveFromGroup(usr.Name, usr.Zone, (grp.(*Group)).Name, usr.Con)
	default:
	}

	return newError(Fatal, fmt.Sprintf("iRods RemoveFromGroup Failed: unknown type passed"))
}
<commit_msg>#10 Finished User info initializer<commit_after>/*** Copyright (c) 2016, University of Florida Research Foundation, Inc. ***
 *** For more information please refer to the LICENSE.md file            ***/

// Package gorods is a Golang binding for the iRods C API (iRods client library).
// GoRods uses cgo to call iRods client functions.
package gorods

// #include "wrapper.h"
import "C"

import (
	"fmt"
	"strconv"
	"strings"
	"time"
	"unsafe"
)

type User struct {
	Name       string
	Zone       string // need to convert to zone obj
	CreateTime time.Time
	ModifyTime time.Time
	Id         int
	Type       string
	Info       string
	Comment    string

	Init bool

	Groups Groups
	Con    *Connection
}

type Users []*User

// initUser
func initUser(name string, zone string, con *Connection) (*User, error) {

	usr := new(User)

	usr.Name = name
	usr.Zone = zone
	usr.Con = con

	if err := usr.init(); err != nil {
		return nil, err
	}

	return usr, nil
}

func (usr *User) init() error {
	if !usr.Init {
		if err := usr.RefreshInfo(); err != nil {
			return err
		}
		// Need to implement getgroups
		// if err := usr.RefreshGroups(); err != nil {
		// 	return err
		// }
		usr.Init = true
	}

	return nil
}

func (usr *User) RefreshInfo() error {

	// create_ts:01471441907
	// modify_ts:01471441907
	// user_id:10011
	// user_name:john
	// user_type_name:rodsuser
	// zone_name:tempZone
	// user_info:
	// r_comment:

	if infoMap, err := usr.GetInfo(); err == nil {
		usr.Comment = infoMap["r_comment"]
		usr.CreateTime = TimeStringToTime(infoMap["create_ts"])
		usr.ModifyTime = TimeStringToTime(infoMap["modify_ts"])
		usr.Id, _ = strconv.Atoi(infoMap["user_id"])
		usr.Type = infoMap["user_type_name"]
		//usr.Zone = infoMap["zone_name"]
		usr.Info = infoMap["user_info"]
	} else {
		return err
	}

	return nil
}

func (usrs Users) FindByName(name string) *User {
	for _, usr := range usrs {
		if usr.Name == name {
			return usr
		}
	}
	return nil
}

func (usr *User) String() string {
	return fmt.Sprintf("%v#%v", usr.Name, usr.Zone)
}

func (usr *User) GetInfo() (map[string]string, error) {
	var (
		result C.goRodsStringResult_t
		err    *C.char
	)

	result.size = C.int(0)

	cUser := C.CString(usr.Name)
	defer C.free(unsafe.Pointer(cUser))

	ccon := usr.Con.GetCcon()
	defer usr.Con.ReturnCcon(ccon)

	if status := C.gorods_get_user(cUser, ccon, &result, &err); status != 0 {
		return nil, newError(Fatal, fmt.Sprintf("iRods Get Users Failed: %v", C.GoString(err)))
	}

	unsafeArr := unsafe.Pointer(result.strArr)
	arrLen := int(result.size)

	// Convert C array to slice, backed by arr *C.char
	slice := (*[1 << 30]*C.char)(unsafeArr)[:arrLen:arrLen]

	//response := make(Users, 0)
	response := make(map[string]string)

	for _, userInfo := range slice {

		userAttributes := strings.Split(strings.Trim(C.GoString(userInfo), " \n"), "\n")

		for _, attr := range userAttributes {

			split := strings.Split(attr, ": ")

			attrName := split[0]
			attrVal := split[1]

			response[attrName] = attrVal

		}

	}

	C.gorods_free_string_result(&result)

	return response, nil
}

func (usr *User) AddToGroup(grp interface{}) error {

	switch grp.(type) {
	case string:
		return AddToGroup(usr.Name, usr.Zone, grp.(string), usr.Con)
	case *Group:
		return AddToGroup(usr.Name, usr.Zone, (grp.(*Group)).Name, usr.Con)
	default:
	}

	return newError(Fatal, fmt.Sprintf("iRods AddToGroup Failed: unknown type passed"))
}

func (usr *User) RemoveFromGroup(grp interface{}) error {
	switch grp.(type) {
	case string:
		return RemoveFromGroup(usr.Name, usr.Zone, grp.(string), usr.Con)
	case *Group:
		return RemoveFromGroup(usr.Name, usr.Zone, (grp.(*Group)).Name, usr.Con)
	default:
	}

	return newError(Fatal, fmt.Sprintf("iRods RemoveFromGroup Failed: unknown type passed"))
}
<|endoftext|>


<commit_before>package sechat

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

var (
	ErrInvalidUserResponse = errors.New("invalid user response")
	ErrInvalidJavaScript   = errors.New("invalid JavaScript (no access to room)")
)

// Room provides information about a room that a user is currently present in.
type Room struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	LastPost int    `json:"last_post"`
	Activity int    `json:"activity"`
}

// Site describes a user's parent site.
type Site struct {
	Icon    string `json:"icon"`
	Caption string `json:"caption"`
}

// InviteTarget describes a site that another user may be invited to.
type InviteTarget struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

// User provides information about a chat user, such as their display name,
// moderator status, etc. Not every method that returns an instance of this
// type populates all fields.
type User struct {
	ID           int     `json:"id"`
	Name         string  `json:"name"`
	EmailHash    string  `json:"email_hash"`
	Reputation   int     `json:"reputation"`
	IsModerator  bool    `json:"is_moderator"`
	IsOwner      bool    `json:"is_owner"`
	IsRegistered bool    `json:"is_registered"`
	LastPost     int     `json:"last_post"`
	LastSeen     int     `json:"last_seen"`
	Rooms        []*Room `json:"rooms"`
	UserMessage  string  `json:"user_message"`
	ProfileURL   string  `json:"profileUrl"`
	Site         *Site   `json:"site"`
	Host         string  `json:"host"`
	MayPairoff   bool    `json:"may_pairoff"`
	Issues       int     `json:"issues"`
}

// mapToUser creates a user from an astMap. Interestingly, the easiest way to
// do this is encode the map and then decode it as JSON.
func mapToUser(m astMap) (*User, error) {
	buff := &bytes.Buffer{}
	if err := json.NewEncoder(buff).Encode(m); err != nil {
		return nil, err
	}
	user := &User{}
	if err := json.NewDecoder(buff).Decode(user); err != nil {
		return nil, err
	}
	return user, nil
}

// User retrieves extended information for a specific user.
func (c *Conn) User(user int) (*User, error) {
	req, err := c.newRequest(
		http.MethodGet,
		fmt.Sprintf("https://chat.stackexchange.com/users/thumbs/%d", user),
		nil,
	)
	if err != nil {
		return nil, err
	}
	res, err := c.client.Do(req)
	if err != nil {
		return nil, err
	}
	u := &User{}
	if err := json.NewDecoder(res.Body).Decode(u); err != nil {
		return nil, err
	}
	return u, nil
}

// Users retrieves limited information for the specified users. Only the first
// few fields in the User struct are filled in.
func (c *Conn) Users(users []int, room int) ([]*User, error) {
	usersStr := make([]string, len(users))
	for i, user := range users {
		usersStr[i] = strconv.Itoa(user)
	}
	res, err := c.postForm(
		"/user/info",
		&url.Values{
			"ids":    {strings.Join(usersStr, ", ")},
			"roomid": {strconv.Itoa(room)},
		},
	)
	if err != nil {
		return nil, err
	}
	var v struct {
		Users []*User `json:"users"`
	}
	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
		return nil, err
	}
	return v.Users, nil
}

// UsersInRoom retrieves a list of users in the specified room. Only the first
// few fields in the User struct are filled in.
func (c *Conn) UsersInRoom(room int) ([]*User, error) {
	program, err := c.parseJavaScriptFromPage(
		fmt.Sprintf("https://chat.stackexchange.com/rooms/%d", room),
	)
	if err != nil {
		return nil, err
	}
	statements := c.findOnReadyStatements(program)
	for _, stm := range statements {
		call := c.parseFunctionCall(stm)
		if call == nil {
			continue
		}
		if call.Name != "CHAT.RoomUsers.initPresent" {
			continue
		}
		if len(call.Arguments) != 1 {
			return nil, ErrInvalidJavaScript
		}
		vals, ok := c.parseArray(call.Arguments[0])
		if !ok {
			return nil, ErrInvalidJavaScript
		}
		users := []*User{}
		for _, exp := range vals {
			user, err := mapToUser(c.parseMap(exp))
			if err != nil {
				return nil, err
			}
			users = append(users, user)
		}
		return users, nil
	}
	return nil, ErrInvalidJavaScript
}
<commit_msg>Reverse the order of parameters to Users() for consistency.<commit_after>package sechat

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

var (
	ErrInvalidUserResponse = errors.New("invalid user response")
	ErrInvalidJavaScript   = errors.New("invalid JavaScript (no access to room)")
)

// Room provides information about a room that a user is currently present in.
type Room struct {
	ID       int    `json:"id"`
	Name     string `json:"name"`
	LastPost int    `json:"last_post"`
	Activity int    `json:"activity"`
}

// Site describes a user's parent site.
type Site struct {
	Icon    string `json:"icon"`
	Caption string `json:"caption"`
}

// InviteTarget describes a site that another user may be invited to.
type InviteTarget struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

// User provides information about a chat user, such as their display name,
// moderator status, etc. Not every method that returns an instance of this
// type populates all fields.
type User struct {
	ID           int     `json:"id"`
	Name         string  `json:"name"`
	EmailHash    string  `json:"email_hash"`
	Reputation   int     `json:"reputation"`
	IsModerator  bool    `json:"is_moderator"`
	IsOwner      bool    `json:"is_owner"`
	IsRegistered bool    `json:"is_registered"`
	LastPost     int     `json:"last_post"`
	LastSeen     int     `json:"last_seen"`
	Rooms        []*Room `json:"rooms"`
	UserMessage  string  `json:"user_message"`
	ProfileURL   string  `json:"profileUrl"`
	Site         *Site   `json:"site"`
	Host         string  `json:"host"`
	MayPairoff   bool    `json:"may_pairoff"`
	Issues       int     `json:"issues"`
}

// mapToUser creates a user from an astMap. Interestingly, the easiest way to
// do this is encode the map and then decode it as JSON.
func mapToUser(m astMap) (*User, error) {
	buff := &bytes.Buffer{}
	if err := json.NewEncoder(buff).Encode(m); err != nil {
		return nil, err
	}
	user := &User{}
	if err := json.NewDecoder(buff).Decode(user); err != nil {
		return nil, err
	}
	return user, nil
}

// User retrieves extended information for a specific user.
func (c *Conn) User(user int) (*User, error) {
	req, err := c.newRequest(
		http.MethodGet,
		fmt.Sprintf("https://chat.stackexchange.com/users/thumbs/%d", user),
		nil,
	)
	if err != nil {
		return nil, err
	}
	res, err := c.client.Do(req)
	if err != nil {
		return nil, err
	}
	u := &User{}
	if err := json.NewDecoder(res.Body).Decode(u); err != nil {
		return nil, err
	}
	return u, nil
}

// Users retrieves limited information for the specified users. Only the first
// few fields in the User struct are filled in.
func (c *Conn) Users(room int, users []int) ([]*User, error) {
	usersStr := make([]string, len(users))
	for i, user := range users {
		usersStr[i] = strconv.Itoa(user)
	}
	res, err := c.postForm(
		"/user/info",
		&url.Values{
			"ids":    {strings.Join(usersStr, ", ")},
			"roomid": {strconv.Itoa(room)},
		},
	)
	if err != nil {
		return nil, err
	}
	var v struct {
		Users []*User `json:"users"`
	}
	if err := json.NewDecoder(res.Body).Decode(&v); err != nil {
		return nil, err
	}
	return v.Users, nil
}

// UsersInRoom retrieves a list of users in the specified room. Only the first
// few fields in the User struct are filled in.
func (c *Conn) UsersInRoom(room int) ([]*User, error) {
	program, err := c.parseJavaScriptFromPage(
		fmt.Sprintf("https://chat.stackexchange.com/rooms/%d", room),
	)
	if err != nil {
		return nil, err
	}
	statements := c.findOnReadyStatements(program)
	for _, stm := range statements {
		call := c.parseFunctionCall(stm)
		if call == nil {
			continue
		}
		if call.Name != "CHAT.RoomUsers.initPresent" {
			continue
		}
		if len(call.Arguments) != 1 {
			return nil, ErrInvalidJavaScript
		}
		vals, ok := c.parseArray(call.Arguments[0])
		if !ok {
			return nil, ErrInvalidJavaScript
		}
		users := []*User{}
		for _, exp := range vals {
			user, err := mapToUser(c.parseMap(exp))
			if err != nil {
				return nil, err
			}
			users = append(users, user)
		}
		return users, nil
	}
	return nil, ErrInvalidJavaScript
}
<|endoftext|>


<commit_before>package main

import  (
    "os"
    "fmt"
    "crypto/sha512"
    "encoding/hex"
    "github.com/hinasssan/msgpack-go"
    "hash"
    "path/filepath"
    "flag"
    "net/http"
    "net/url"
    "io/ioutil"
    "log"
    "strconv"
)

type LMVFile struct {
    Hash string `msgpack:"hash"`
    Size int64  `msgpack:"size"`
    Name string `msgpack:"name"`
    Algorithm string `msgpack:"algorithm"`
}

func CalculateSHA512(data []byte) string {

    var hasher hash.Hash = sha512.New()

    hasher.Reset()
    hasher.Write(data)
    return hex.EncodeToString(hasher.Sum(nil))

}

func encode(fp string, token bool) {

    lmv_file := new(LMVFile)

    lmv_file.Algorithm = "SHA512"

    file, err := os.Open(fp)

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

    defer file.Close()

    stat, err := file.Stat()

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

    bs := make([]byte, stat.Size())
    _, err = file.Read(bs)

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

    lmv_file.Hash = CalculateSHA512(bs)
    lmv_file.Size = stat.Size()
    lmv_file.Name = filepath.Base(fp)

    if token {

        upload_address := "http://127.0.0.1:8081/upload"

        fields := make(url.Values)
        fields.Set("name", lmv_file.Name)
        fields.Set("hash", lmv_file.Hash)
        fields.Set("size", strconv.FormatInt(lmv_file.Size, 10))

        resp, err := http.PostForm(upload_address, fields)

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

        defer resp.Body.Close()

        body, err := ioutil.ReadAll(resp.Body)

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

        fmt.Println("'" + lmv_file.Name + "'" + " --> " + "'" + string(body) + "'")

    } else {

        os.Create(lmv_file.Name + ".lmv")

        b, err := msgpack.Marshal(lmv_file)

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

        err = ioutil.WriteFile(lmv_file.Name + ".lmv", b, 0644)

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

    }

}

func main() {

    token := flag.Bool("token", false, "Use tokens in place of .lmv files")

    flag.Parse()

    if len(os.Args) < 2 {

        fmt.Println("Use lmv -h for usage")

    } else {

        for i := 0; i < len(os.Args[1:]); i++ {

            if _, err := os.Stat(os.Args[i+1]); err == nil {

                encode(os.Args[i+1], *token)

            }

        }

    }
}
<commit_msg>Allow setting the register as a flag<commit_after>package main

import  (
    "os"
    "fmt"
    "crypto/sha512"
    "encoding/hex"
    "github.com/hinasssan/msgpack-go"
    "hash"
    "path/filepath"
    "flag"
    "net/http"
    "net/url"
    "io/ioutil"
    "log"
    "strconv"
)

type LMVFile struct {
    Hash string `msgpack:"hash"`
    Size int64  `msgpack:"size"`
    Name string `msgpack:"name"`
    Algorithm string `msgpack:"algorithm"`
}

func CalculateSHA512(data []byte) string {

    var hasher hash.Hash = sha512.New()

    hasher.Reset()
    hasher.Write(data)
    return hex.EncodeToString(hasher.Sum(nil))

}

func encode(fp string, token bool, register string) {

    lmv_file := new(LMVFile)

    lmv_file.Algorithm = "SHA512"

    file, err := os.Open(fp)

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

    defer file.Close()

    stat, err := file.Stat()

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

    bs := make([]byte, stat.Size())
    _, err = file.Read(bs)

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

    lmv_file.Hash = CalculateSHA512(bs)
    lmv_file.Size = stat.Size()
    lmv_file.Name = filepath.Base(fp)

    if token {

        upload_address := register + "/upload"

        fields := make(url.Values)
        fields.Set("name", lmv_file.Name)
        fields.Set("hash", lmv_file.Hash)
        fields.Set("size", strconv.FormatInt(lmv_file.Size, 10))

        resp, err := http.PostForm(upload_address, fields)

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

        defer resp.Body.Close()

        body, err := ioutil.ReadAll(resp.Body)

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

        fmt.Println("'" + lmv_file.Name + "'" + " --> " + "'" + string(body) + "'")

    } else {

        os.Create(lmv_file.Name + ".lmv")

        b, err := msgpack.Marshal(lmv_file)

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

        err = ioutil.WriteFile(lmv_file.Name + ".lmv", b, 0644)

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

    }

}

func main() {

    token := flag.Bool("token", false, "Use tokens in place of .lmv files")
    register := flag.String("register", "http://127.0.0.1:8081", "Register for tokens (including protocol)")

    flag.Parse()

    if len(os.Args) < 2 {

        fmt.Println("Use lmv -h for usage")

    } else {

        for i := 0; i < len(os.Args[1:]); i++ {

            if _, err := os.Stat(os.Args[i+1]); err == nil {

                encode(os.Args[i+1], *token, *register)

            }

        }

    }
}
<|endoftext|>


<commit_before>package eveConsumer

import (
	"testing"

	"github.com/garyburd/redigo/redis"
)

func TestKillmailsConsumer(t *testing.T) {
	err := killmailAddToQueue(1, "FAKE HASH")
	if err != nil {
		t.Error(err)
		return
	}
	err = killmailAddToQueue(2, "FAKE HASH")
	if err != nil {
		t.Error(err)
		return
	}
}

func TestKillmailsConsumer(t *testing.T) {
	r := ctx.Cache.Get()
	defer r.Close()
	for {
		_, err := killmailsConsumer(eC, r)
		if err != nil {
			t.Error(err)
			return
		}
		if i, _ := redis.Int(r.Do("SCARD", "EVEDATA_killQueue")); i == 0 {
			break
		}
	}
}
<commit_msg>Fix broken build<commit_after>package eveConsumer

import (
	"testing"

	"github.com/garyburd/redigo/redis"
)

func TestKillmailsAddToQueue(t *testing.T) {
	err := eC.killmailAddToQueue(1, "FAKE HASH")
	if err != nil {
		t.Error(err)
		return
	}
	err = eC.killmailAddToQueue(2, "FAKE HASH")
	if err != nil {
		t.Error(err)
		return
	}
}

func TestKillmailsConsumer(t *testing.T) {
	r := ctx.Cache.Get()
	defer r.Close()
	for {
		_, err := killmailsConsumer(eC, r)
		if err != nil {
			t.Error(err)
			return
		}
		if i, _ := redis.Int(r.Do("SCARD", "EVEDATA_killQueue")); i == 0 {
			break
		}
	}
}
<|endoftext|>


<commit_before>// Package vago

package vago

/*
#cgo pkg-config: varnishapi
#cgo LDFLAGS: -lvarnishapi -lm
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <vapi/vsc.h>
#include <vapi/vsm.h>
#include <vapi/vsl.h>

int dispatchCallback(struct VSL_data *vsl, struct VSL_transaction **trans, void *priv);
*/
import "C"

import (
	"encoding/binary"
	"errors"
	"time"
	"unsafe"
)

const (
	lenmask       = 0xffff
	clientmarker  = uint32(1) << 30
	backendmarker = uint32(1) << 31
	identmask     = ^(uint32(3) << 30)
)

// LogCallback defines a callback function.
// It's used by Log.
type LogCallback func(vxid uint32, tag, _type, data string) int

// Log calls the given callback for any transactions matching the query
// and grouping.
func (v *Varnish) Log(query string, grouping uint32, logCallback LogCallback) error {
	v.vsl = C.VSL_New()
	handle := ptrHandles.track(logCallback)
	defer ptrHandles.untrack(handle)
	for {
		v.cursor = C.VSL_CursorVSM(v.vsl, v.vsm, 1)
		if v.cursor != nil {
			break
		}
	}
	if grouping < 0 || grouping > 4 {
		grouping = VXID
	}
	if query != "" {
		cs := C.CString(query)
		defer C.free(unsafe.Pointer(cs))
		v.vslq = C.VSLQ_New(v.vsl, &v.cursor, grouping, cs)
	} else {
		v.vslq = C.VSLQ_New(v.vsl, &v.cursor, grouping, nil)
	}
	if v.vslq == nil {
		return errors.New(C.GoString(C.VSL_Error(v.vsl)))
	}
	for v.alive {
		i := C.VSLQ_Dispatch(v.vslq,
			(*C.VSLQ_dispatch_f)(unsafe.Pointer(C.dispatchCallback)),
			handle)
		if i == 1 {
			continue
		}
		if i == 0 {
			time.Sleep(1000)
			continue
		}
		if i == -1 {
			break
		}
	}
	return nil
}

// dispatchCallback walks through the transaction and calls a function of
// type LogCallback.
//export dispatchCallback
func dispatchCallback(vsl *C.struct_VSL_data, pt **C.struct_VSL_transaction, handle unsafe.Pointer) C.int {
	var tx = uintptr(unsafe.Pointer(pt))
	var _type string
	logCallback := ptrHandles.get(handle)
	for {
		if tx == 0 {
			break
		}
		t := ((**C.struct_VSL_transaction)(unsafe.Pointer(tx)))
		if *t == nil {
			break
		}
		for {
			i := C.VSL_Next((*t).c)
			if i < 0 {
				return i
			}
			if i == 0 {
				break
			}
			if C.VSL_Match(vsl, (*t).c) == 0 {
				continue
			}
			s1 := cui32tosl((*t).c.rec.ptr, 8)
			tag := C.GoString(C.VSL_tags[s1[0]>>24])
			vxid := s1[1] & identmask
			length := C.int(s1[0] & lenmask)
			switch {
			case s1[1]&(clientmarker) != 0:
				_type = "c"
			case s1[1]&(backendmarker) != 0:
				_type = "b"
			default:
				_type = "-"
			}
			s2 := cui32tosl((*t).c.rec.ptr, (length+2)*4)
			data := ui32tostr(&s2[2], length)
			ret := logCallback.(LogCallback)(vxid, tag, _type, data)
			if ret != 0 {
				return C.int(ret)
			}
		}
		tx += unsafe.Sizeof(t)
	}
	return 0
}

// Convert C.uint32_t to slice of uint32
func cui32tosl(ptr *C.uint32_t, length C.int) []uint32 {
	b := C.GoBytes(unsafe.Pointer(ptr), length)
	s := make([]uint32, length/4)
	for i := range s {
		s[i] = uint32(binary.LittleEndian.Uint32(b[i*4 : (i+1)*4]))
	}
	return s
}

// Convert uint32 to string
func ui32tostr(val *uint32, length C.int) string {
	return C.GoStringN((*C.char)(unsafe.Pointer(val)), length-1)
}
<commit_msg>follow upstream timeout<commit_after>// Package vago

package vago

/*
#cgo pkg-config: varnishapi
#cgo LDFLAGS: -lvarnishapi -lm
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <vapi/vsc.h>
#include <vapi/vsm.h>
#include <vapi/vsl.h>

int dispatchCallback(struct VSL_data *vsl, struct VSL_transaction **trans, void *priv);
*/
import "C"

import (
	"encoding/binary"
	"errors"
	"time"
	"unsafe"
)

const (
	lenmask       = 0xffff
	clientmarker  = uint32(1) << 30
	backendmarker = uint32(1) << 31
	identmask     = ^(uint32(3) << 30)
)

// LogCallback defines a callback function.
// It's used by Log.
type LogCallback func(vxid uint32, tag, _type, data string) int

// Log calls the given callback for any transactions matching the query
// and grouping.
func (v *Varnish) Log(query string, grouping uint32, logCallback LogCallback) error {
	v.vsl = C.VSL_New()
	handle := ptrHandles.track(logCallback)
	defer ptrHandles.untrack(handle)
	for {
		v.cursor = C.VSL_CursorVSM(v.vsl, v.vsm, 1)
		if v.cursor != nil {
			break
		}
	}
	if grouping < 0 || grouping > 4 {
		grouping = VXID
	}
	if query != "" {
		cs := C.CString(query)
		defer C.free(unsafe.Pointer(cs))
		v.vslq = C.VSLQ_New(v.vsl, &v.cursor, grouping, cs)
	} else {
		v.vslq = C.VSLQ_New(v.vsl, &v.cursor, grouping, nil)
	}
	if v.vslq == nil {
		return errors.New(C.GoString(C.VSL_Error(v.vsl)))
	}
	for v.alive {
		i := C.VSLQ_Dispatch(v.vslq,
			(*C.VSLQ_dispatch_f)(unsafe.Pointer(C.dispatchCallback)),
			handle)
		if i == 1 {
			continue
		}
		if i == 0 {
			time.Sleep(10 * time.Millisecond)
			continue
		}
		if i == -1 {
			break
		}
	}
	return nil
}

// dispatchCallback walks through the transaction and calls a function of
// type LogCallback.
//export dispatchCallback
func dispatchCallback(vsl *C.struct_VSL_data, pt **C.struct_VSL_transaction, handle unsafe.Pointer) C.int {
	var tx = uintptr(unsafe.Pointer(pt))
	var _type string
	logCallback := ptrHandles.get(handle)
	for {
		if tx == 0 {
			break
		}
		t := ((**C.struct_VSL_transaction)(unsafe.Pointer(tx)))
		if *t == nil {
			break
		}
		for {
			i := C.VSL_Next((*t).c)
			if i < 0 {
				return i
			}
			if i == 0 {
				break
			}
			if C.VSL_Match(vsl, (*t).c) == 0 {
				continue
			}
			s1 := cui32tosl((*t).c.rec.ptr, 8)
			tag := C.GoString(C.VSL_tags[s1[0]>>24])
			vxid := s1[1] & identmask
			length := C.int(s1[0] & lenmask)
			switch {
			case s1[1]&(clientmarker) != 0:
				_type = "c"
			case s1[1]&(backendmarker) != 0:
				_type = "b"
			default:
				_type = "-"
			}
			s2 := cui32tosl((*t).c.rec.ptr, (length+2)*4)
			data := ui32tostr(&s2[2], length)
			ret := logCallback.(LogCallback)(vxid, tag, _type, data)
			if ret != 0 {
				return C.int(ret)
			}
		}
		tx += unsafe.Sizeof(t)
	}
	return 0
}

// Convert C.uint32_t to slice of uint32
func cui32tosl(ptr *C.uint32_t, length C.int) []uint32 {
	b := C.GoBytes(unsafe.Pointer(ptr), length)
	s := make([]uint32, length/4)
	for i := range s {
		s[i] = uint32(binary.LittleEndian.Uint32(b[i*4 : (i+1)*4]))
	}
	return s
}

// Convert uint32 to string
func ui32tostr(val *uint32, length C.int) string {
	return C.GoStringN((*C.char)(unsafe.Pointer(val)), length-1)
}
<|endoftext|>


<commit_before>/*
Copyright 2013 Google Inc.

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 lru implements an LRU cache.
package lru

import (
	"container/list"
	"time"
)

// Cache is an LRU cache. It is not safe for concurrent access.
type Cache struct {
	// MaxEntries is the maximum number of cache entries before
	// an item is evicted. Zero means no limit.
	MaxEntries int

	// OnEvicted optionally specificies a callback function to be
	// executed when an entr is purged from the cache.
	OnEvicted func(key Key, value interface{})

	ll    *list.List
	Cache map[interface{}]*list.Element
}

// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators
type Key interface{}

type Entry struct {
	Key    Key
	Value  interface{}
	Access time.Time
}

// New creates a new Cache.
// If maxEntries is zero, the cache has no limit and it's assumed
// that eviction is done by the caller.
func New(maxEntries int) *Cache {
	return &Cache{
		MaxEntries: maxEntries,
		ll:         list.New(),
		cache:      make(map[interface{}]*list.Element),
	}
}

// Add adds a value to the cache.
func (c *Cache) Add(key Key, value interface{}) {
	if c.cache == nil {
		c.cache = make(map[interface{}]*list.Element)
		c.ll = list.New()
	}
	if ee, ok := c.cache[key]; ok {
		c.ll.MoveToFront(ee)
		ee.Value.(*Entry).value = value
		ee.Value.(*Entry).access = time.Now()
		return
	}
	ele := c.ll.PushFront(&Entry{key, value, time.Now()})
	c.cache[key] = ele
	if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {
		c.RemoveOldest()
	}
}

// Get looks up a key's value from the cache.
func (c *Cache) Get(key Key) (value interface{}, ok bool) {
	if c.cache == nil {
		return
	}
	if ele, hit := c.cache[key]; hit {
		c.ll.MoveToFront(ele)
		ele.Value.(*Entry).access = time.Now()
		return ele.Value.(*Entry).value, true
	}
	return
}

// Remove removes the provided key from the cache.
func (c *Cache) Remove(key Key) {
	if c.cache == nil {
		return
	}
	if ele, hit := c.cache[key]; hit {
		c.removeElement(ele)
	}
}

// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() {
	if c.cache == nil {
		return
	}
	ele := c.ll.Back()
	if ele != nil {
		c.removeElement(ele)
	}
}

func (c *Cache) peekOldest() *list.Element {
	if c.cache == nil {
		return nil
	}
	ele := c.ll.Back()
	return ele
}

func (c *Cache) PruneOldest(before time.Time) {
	for ele := c.peekOldest(); ele != nil && ele.Value.(*Entry).access.Before(before); ele = c.peekOldest() {
		c.removeElement(ele)
	}
}

func (c *Cache) removeElement(e *list.Element) {
	c.ll.Remove(e)
	kv := e.Value.(*entry)
	delete(c.cache, kv.key)
	if c.OnEvicted != nil {
		c.OnEvicted(kv.key, kv.value)
	}
}

// Len returns the number of items in the cache.
func (c *Cache) Len() int {
	if c.cache == nil {
		return 0
	}
	return c.ll.Len()
}
<commit_msg>Created field GetValue on Entry, revereted members to private<commit_after>/*
Copyright 2013 Google Inc.

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 lru implements an LRU cache.
package lru

import (
	"container/list"
	"time"
)

// Cache is an LRU cache. It is not safe for concurrent access.
type Cache struct {
	// MaxEntries is the maximum number of cache entries before
	// an item is evicted. Zero means no limit.
	MaxEntries int

	// OnEvicted optionally specificies a callback function to be
	// executed when an entr is purged from the cache.
	OnEvicted func(key Key, value interface{})

	ll    *list.List
	Cache map[interface{}]*list.Element
}

// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators
type Key interface{}

type Entry struct {
	key    Key
	value  interface{}
	access time.Time
}

func (e *Entry) GetValue() interface{} {
	return e.value
}

// New creates a new Cache.
// If maxEntries is zero, the cache has no limit and it's assumed
// that eviction is done by the caller.
func New(maxEntries int) *Cache {
	return &Cache{
		MaxEntries: maxEntries,
		ll:         list.New(),
		cache:      make(map[interface{}]*list.Element),
	}
}

// Add adds a value to the cache.
func (c *Cache) Add(key Key, value interface{}) {
	if c.cache == nil {
		c.cache = make(map[interface{}]*list.Element)
		c.ll = list.New()
	}
	if ee, ok := c.cache[key]; ok {
		c.ll.MoveToFront(ee)
		ee.Value.(*Entry).value = value
		ee.Value.(*Entry).access = time.Now()
		return
	}
	ele := c.ll.PushFront(&Entry{key, value, time.Now()})
	c.cache[key] = ele
	if c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {
		c.RemoveOldest()
	}
}

// Get looks up a key's value from the cache.
func (c *Cache) Get(key Key) (value interface{}, ok bool) {
	if c.cache == nil {
		return
	}
	if ele, hit := c.cache[key]; hit {
		c.ll.MoveToFront(ele)
		ele.Value.(*Entry).access = time.Now()
		return ele.Value.(*Entry).value, true
	}
	return
}

// Remove removes the provided key from the cache.
func (c *Cache) Remove(key Key) {
	if c.cache == nil {
		return
	}
	if ele, hit := c.cache[key]; hit {
		c.removeElement(ele)
	}
}

// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() {
	if c.cache == nil {
		return
	}
	ele := c.ll.Back()
	if ele != nil {
		c.removeElement(ele)
	}
}

func (c *Cache) peekOldest() *list.Element {
	if c.cache == nil {
		return nil
	}
	ele := c.ll.Back()
	return ele
}

func (c *Cache) PruneOldest(before time.Time) {
	for ele := c.peekOldest(); ele != nil && ele.Value.(*Entry).access.Before(before); ele = c.peekOldest() {
		c.removeElement(ele)
	}
}

func (c *Cache) removeElement(e *list.Element) {
	c.ll.Remove(e)
	kv := e.Value.(*entry)
	delete(c.cache, kv.key)
	if c.OnEvicted != nil {
		c.OnEvicted(kv.key, kv.value)
	}
}

// Len returns the number of items in the cache.
func (c *Cache) Len() int {
	if c.cache == nil {
		return 0
	}
	return c.ll.Len()
}
<|endoftext|>


<commit_before>package lru

import (
	"sync"

	"github.com/hashicorp/golang-lru/simplelru"
)

// Cache is a thread-safe fixed size LRU cache.
type Cache struct {
	lru  simplelru.LRUCache
	lock sync.RWMutex
}

// New creates an LRU of the given size.
func New(size int) (*Cache, error) {
	return NewWithEvict(size, nil)
}

// NewWithEvict constructs a fixed size cache with the given eviction
// callback.
func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) {
	lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted))
	if err != nil {
		return nil, err
	}
	c := &Cache{
		lru: lru,
	}
	return c, nil
}

// Purge is used to completely clear the cache.
func (c *Cache) Purge() {
	c.lock.Lock()
	c.lru.Purge()
	c.lock.Unlock()
}

// Add adds a value to the cache. Returns true if an eviction occurred.
func (c *Cache) Add(key, value interface{}) (evicted bool) {
	c.lock.Lock()
	evicted = c.lru.Add(key, value)
	c.lock.Unlock()
	return evicted
}

// Get looks up a key's value from the cache.
func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
	c.lock.Lock()
	value, ok = c.lru.Get(key)
	c.lock.Unlock()
	return value, ok
}

// Contains checks if a key is in the cache, without updating the
// recent-ness or deleting it for being stale.
func (c *Cache) Contains(key interface{}) bool {
	c.lock.RLock()
	containKey := c.lru.Contains(key)
	c.lock.RUnlock()
	return containKey
}

// Peek returns the key value (or undefined if not found) without updating
// the "recently used"-ness of the key.
func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
	c.lock.RLock()
	value, ok = c.lru.Peek(key)
	c.lock.RUnlock()
	return value, ok
}

// ContainsOrAdd checks if a key is in the cache without updating the
// recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred.
func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
	c.lock.Lock()
	defer c.lock.Unlock()

	if c.lru.Contains(key) {
		return true, false
	}
	evicted = c.lru.Add(key, value)
	return false, evicted
}

// PeekOrAdd checks if a key is in the cache without updating the
// recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred.
func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) {
	c.lock.Lock()
	defer c.lock.Unlock()

	previous, ok = c.lru.Peek(key)
	if ok {
		return previous, true, false
	}

	evicted = c.lru.Add(key, value)
	return nil, false, evicted
}

// Remove removes the provided key from the cache.
func (c *Cache) Remove(key interface{}) (present bool) {
	c.lock.Lock()
	present = c.lru.Remove(key)
	c.lock.Unlock()
	return
}

// Resize changes the cache size.
func (c *Cache) Resize(size int) (evicted int) {
	c.lock.Lock()
	evicted = c.lru.Resize(size)
	c.lock.Unlock()
	return evicted
}

// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() (key, value interface{}, ok bool) {
	c.lock.Lock()
	key, value, ok = c.lru.RemoveOldest()
	c.lock.Unlock()
	return
}

// GetOldest returns the oldest entry
func (c *Cache) GetOldest() (key, value interface{}, ok bool) {
	c.lock.Lock()
	key, value, ok = c.lru.GetOldest()
	c.lock.Unlock()
	return
}

// Keys returns a slice of the keys in the cache, from oldest to newest.
func (c *Cache) Keys() []interface{} {
	c.lock.RLock()
	keys := c.lru.Keys()
	c.lock.RUnlock()
	return keys
}

// Len returns the number of items in the cache.
func (c *Cache) Len() int {
	c.lock.RLock()
	length := c.lru.Len()
	c.lock.RUnlock()
	return length
}
<commit_msg>rework lru's external registered callback invocation to avoid concurr… (#80)<commit_after>package lru

import (
	"sync"

	"github.com/hashicorp/golang-lru/simplelru"
)

const (
	// DefaultEvictedBufferSize defines the default buffer size to store evicted key/val
	DefaultEvictedBufferSize = 16
)

// Cache is a thread-safe fixed size LRU cache.
type Cache struct {
	lru                      *simplelru.LRU
	evictedKeys, evictedVals []interface{}
	onEvictedCB              func(k, v interface{})
	lock                     sync.RWMutex
}

// New creates an LRU of the given size.
func New(size int) (*Cache, error) {
	return NewWithEvict(size, nil)
}

// NewWithEvict constructs a fixed size cache with the given eviction
// callback.
func NewWithEvict(size int, onEvicted func(key, value interface{})) (c *Cache, err error) {
	// create a cache with default settings
	c = &Cache{
		onEvictedCB: onEvicted,
	}
	if onEvicted != nil {
		c.initEvictBuffers()
		onEvicted = c.onEvicted
	}
	c.lru, err = simplelru.NewLRU(size, onEvicted)
	return
}

func (c *Cache) initEvictBuffers() {
	c.evictedKeys = make([]interface{}, 0, DefaultEvictedBufferSize)
	c.evictedVals = make([]interface{}, 0, DefaultEvictedBufferSize)
}

// onEvicted save evicted key/val and sent in externally registered callback
// outside of critical section
func (c *Cache) onEvicted(k, v interface{}) {
	c.evictedKeys = append(c.evictedKeys, k)
	c.evictedVals = append(c.evictedVals, v)
}

// Purge is used to completely clear the cache.
func (c *Cache) Purge() {
	var ks, vs []interface{}
	c.lock.Lock()
	c.lru.Purge()
	if c.onEvictedCB != nil && len(c.evictedKeys) > 0 {
		ks, vs = c.evictedKeys, c.evictedVals
		c.initEvictBuffers()
	}
	c.lock.Unlock()
	// invoke callback outside of critical section
	if c.onEvictedCB != nil {
		for i := 0; i < len(ks); i++ {
			c.onEvictedCB(ks[i], vs[i])
		}
	}
}

// Add adds a value to the cache. Returns true if an eviction occurred.
func (c *Cache) Add(key, value interface{}) (evicted bool) {
	var k, v interface{}
	c.lock.Lock()
	evicted = c.lru.Add(key, value)
	if c.onEvictedCB != nil && evicted {
		k, v = c.evictedKeys[0], c.evictedVals[0]
		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
	}
	c.lock.Unlock()
	if c.onEvictedCB != nil && evicted {
		c.onEvictedCB(k, v)
	}
	return
}

// Get looks up a key's value from the cache.
func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
	c.lock.Lock()
	value, ok = c.lru.Get(key)
	c.lock.Unlock()
	return value, ok
}

// Contains checks if a key is in the cache, without updating the
// recent-ness or deleting it for being stale.
func (c *Cache) Contains(key interface{}) bool {
	c.lock.RLock()
	containKey := c.lru.Contains(key)
	c.lock.RUnlock()
	return containKey
}

// Peek returns the key value (or undefined if not found) without updating
// the "recently used"-ness of the key.
func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
	c.lock.RLock()
	value, ok = c.lru.Peek(key)
	c.lock.RUnlock()
	return value, ok
}

// ContainsOrAdd checks if a key is in the cache without updating the
// recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred.
func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
	var k, v interface{}
	c.lock.Lock()
	if c.lru.Contains(key) {
		c.lock.Unlock()
		return true, false
	}
	evicted = c.lru.Add(key, value)
	if c.onEvictedCB != nil && evicted {
		k, v = c.evictedKeys[0], c.evictedVals[0]
		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
	}
	c.lock.Unlock()
	if c.onEvictedCB != nil && evicted {
		c.onEvictedCB(k, v)
	}
	return false, evicted
}

// PeekOrAdd checks if a key is in the cache without updating the
// recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred.
func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) {
	var k, v interface{}
	c.lock.Lock()
	previous, ok = c.lru.Peek(key)
	if ok {
		c.lock.Unlock()
		return previous, true, false
	}
	evicted = c.lru.Add(key, value)
	if c.onEvictedCB != nil && evicted {
		k, v = c.evictedKeys[0], c.evictedVals[0]
		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
	}
	c.lock.Unlock()
	if c.onEvictedCB != nil && evicted {
		c.onEvictedCB(k, v)
	}
	return nil, false, evicted
}

// Remove removes the provided key from the cache.
func (c *Cache) Remove(key interface{}) (present bool) {
	var k, v interface{}
	c.lock.Lock()
	present = c.lru.Remove(key)
	if c.onEvictedCB != nil && present {
		k, v = c.evictedKeys[0], c.evictedVals[0]
		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
	}
	c.lock.Unlock()
	if c.onEvictedCB != nil && present {
		c.onEvicted(k, v)
	}
	return
}

// Resize changes the cache size.
func (c *Cache) Resize(size int) (evicted int) {
	var ks, vs []interface{}
	c.lock.Lock()
	evicted = c.lru.Resize(size)
	if c.onEvictedCB != nil && evicted > 0 {
		ks, vs = c.evictedKeys, c.evictedVals
		c.initEvictBuffers()
	}
	c.lock.Unlock()
	if c.onEvictedCB != nil && evicted > 0 {
		for i := 0; i < len(ks); i++ {
			c.onEvictedCB(ks[i], vs[i])
		}
	}
	return evicted
}

// RemoveOldest removes the oldest item from the cache.
func (c *Cache) RemoveOldest() (key, value interface{}, ok bool) {
	var k, v interface{}
	c.lock.Lock()
	key, value, ok = c.lru.RemoveOldest()
	if c.onEvictedCB != nil && ok {
		k, v = c.evictedKeys[0], c.evictedVals[0]
		c.evictedKeys, c.evictedVals = c.evictedKeys[:0], c.evictedVals[:0]
	}
	c.lock.Unlock()
	if c.onEvictedCB != nil && ok {
		c.onEvictedCB(k, v)
	}
	return
}

// GetOldest returns the oldest entry
func (c *Cache) GetOldest() (key, value interface{}, ok bool) {
	c.lock.RLock()
	key, value, ok = c.lru.GetOldest()
	c.lock.RUnlock()
	return
}

// Keys returns a slice of the keys in the cache, from oldest to newest.
func (c *Cache) Keys() []interface{} {
	c.lock.RLock()
	keys := c.lru.Keys()
	c.lock.RUnlock()
	return keys
}

// Len returns the number of items in the cache.
func (c *Cache) Len() int {
	c.lock.RLock()
	length := c.lru.Len()
	c.lock.RUnlock()
	return length
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"path"
	"runtime"
	"syscall"

	"github.com/intelsdilabs/pulse/control"
)

var (
	// PulsePath is the local file path to a pulse build
	PulsePath = os.Getenv("PULSE_PATH")
	// CollectorPath is the path to collector plugins within a pulse build
	CollectorPath = path.Join(PulsePath, "plugin", "collector")
)

// Pulse Flags for command line
var version = flag.Bool("version", false, "print Pulse version")
var maxProcs = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Default is use all cores.")
var pluginController = flag.Bool("plugin_controller", false, "Enable Pulse Plugin Controller")

var gitversion string

type CoreModule interface {
	Start()
	Stop()
}

type PulseControl struct {
	pluginController CoreModule
}

func main() {
	flag.Parse()
	if *version {
		fmt.Println("Pulse version:", gitversion)
		os.Exit(0)
	}

	setMaxProcs()

	pulseControl := &PulseControl{}

	if *pluginController {
		pulseControl.pluginController = control.New()
	}
	//TODO: Start pulse modules
	//TODO: Set module order for starting and stopping
	startInterruptHandling()
	select {} //run forever and ever
}

func setMaxProcs() {
	var _maxProcs int
	numProcs := runtime.NumCPU()
	if *maxProcs <= 0 {
		if *maxProcs < 0 {
			log.Printf("WARNING: max_procs set to less than zero. Setting GOMAXPROCS to %v", numProcs)
		}
		_maxProcs = numProcs
	} else if *maxProcs > numProcs {
		log.Printf("WARNING: Not allowed to set GOMAXPROCS above number of processors in system. Setting GOMAXPROCS to %v", numProcs)
		_maxProcs = numProcs
	} else {
		_maxProcs = *maxProcs
	}
	log.Printf("Setting GOMAXPROCS to %v\n", _maxProcs)
	runtime.GOMAXPROCS(_maxProcs)

	//Verify setting worked
	actualNumProcs := runtime.GOMAXPROCS(0)
	if actualNumProcs != _maxProcs {
		log.Printf("WARNING: Specified max procs of %v but using %v", _maxProcs, actualNumProcs)
	}
}

func startInterruptHandling() {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGTERM)

	//Let's block until someone tells us to quit
	go func() {
		sig := <-c
		//TODO: Stop pulse modules on exit signals
		log.Printf("Exiting given signal: %v", sig)
		os.Exit(0)
	}()
}
<commit_msg>Add starting and stopping of modules to pulse.go<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"runtime"
	"syscall"

	"github.com/intelsdilabs/pulse/control"
	"github.com/intelsdilabs/pulse/schedule"
)

// Pulse Flags for command line
var version = flag.Bool("version", false, "print Pulse version")
var maxProcs = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Default is use all cores.")

var gitversion string

type CoreModule interface {
	Start() error
	Stop()
}

//type PulseControl struct {
//	pluginController CoreModule
//	scheduler        CoreModule
//}

func main() {
	flag.Parse()
	if *version {
		fmt.Println("Pulse version:", gitversion)
		os.Exit(0)
	}

	setMaxProcs()

	//pulseControl := &PulseControl{}

	c := control.New()
	s := schedule.New()
	s.MetricManager = c

	//  Start our modules
	if err := startModule("Plugin Controller", c); err != nil {
		printErrorAndExit("Plugin Controller", err)
	}
	if err := startModule("Scheduler", s); err != nil {
		if c.Started {
			c.Stop()
		}
		printErrorAndExit("Scheduler", err)
	}

	startInterruptHandling(c, s)
	select {} //run forever and ever
}

func setMaxProcs() {
	var _maxProcs int
	numProcs := runtime.NumCPU()
	if *maxProcs <= 0 {
		if *maxProcs < 0 {
			log.Printf("WARNING: max_procs set to less than zero. Setting GOMAXPROCS to %v", numProcs)
		}
		_maxProcs = numProcs
	} else if *maxProcs > numProcs {
		log.Printf("WARNING: Not allowed to set GOMAXPROCS above number of processors in system. Setting GOMAXPROCS to %v", numProcs)
		_maxProcs = numProcs
	} else {
		_maxProcs = *maxProcs
	}
	log.Printf("Setting GOMAXPROCS to %v\n", _maxProcs)
	runtime.GOMAXPROCS(_maxProcs)

	//Verify setting worked
	actualNumProcs := runtime.GOMAXPROCS(0)
	if actualNumProcs != _maxProcs {
		log.Printf("WARNING: Specified max procs of %v but using %v", _maxProcs, actualNumProcs)
	}
}

func startModule(name string, m CoreModule) error {
	log.Printf("Starting Pulse Agent %s module", name)
	return m.Start()
}

func printErrorAndExit(name string, err error) {
	log.Println("ERROR:", err)
	log.Println("ERROR: Error starting Pulse Agent %s module. Exiting now.")
	os.Exit(1)
}

func startInterruptHandling(modules ...CoreModule) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGTERM)

	//Let's block until someone tells us to quit
	go func() {
		sig := <-c
		log.Println("Stopping Pulse Agent modules")
		for _, m := range modules {
			m.Stop()
		}
		log.Printf("Exiting given signal: %v", sig)
		os.Exit(0)
	}()
}
<|endoftext|>