<commit_before>package controllers

import (
	"errors"

	"github.com/wheatandcat/dotstamp_server/utils/log"

	"github.com/astaxie/beego"
)

// noUserID ユーザ無しID
const noUserID = 0

// BaseController ベースコントローラ
type BaseController struct {
	beego.Controller
}

// ErrorResponse エラー発生レスポンス
type ErrorResponse struct {
	Message string
	ErrCode int
}

// Accessor ベースアクセサー
type Accessor interface {
	GetUserID() int
	ServerError()
}

const (
	// ErrCodeCommon 汎用エラー
	ErrCodeCommon = 1
	// ErrCodeUserNotFound ユーザ情報が取得できない or 不一致
	ErrCodeUserNotFound = 2
	// ErrCodeLoginNotFound ログインしていない
	ErrCodeLoginNotFound = 3
	// ErrCreateUser ユーザ登録に失敗
	ErrCreateUser = 4
	// ErrParameter パラメータエラー
	ErrParameter = 5
	// ErrImageConversion 画像変換エラー
	ErrImageConversion = 6
	// ErrImageResize 画像縮小エラー
	ErrImageResize = 7
	// ErrContributionNew 投稿失敗
	ErrContributionNew = 8
	// ErrContributionSave 投稿保存失敗
	ErrContributionSave = 9
	// ErrContributionTagSave 投稿タグ保存失敗
	ErrContributionTagSave = 10
	// ErrUserSave ユーザ保存失敗
	ErrUserSave = 11
	// ErrUserOrPasswordDifferent ユーザかパスワードが異なる
	ErrUserOrPasswordDifferent = 12
	// ErrContributionSearch 検索取得に失敗
	ErrContributionSearch = 13
	// ErrFollowed フォロー済み
	ErrFollowed = 14
	// ErrAddFollow フォロー追加失敗
	ErrAddFollow = 15
	// ErrContributionNotFound 投稿が存在しない
	ErrContributionNotFound = 16
	// ErrDeleteFollow フォロー削除失敗
	ErrDeleteFollow = 17
	// ErrTagMaxNumberOver タグの最大数を超えている
	ErrTagMaxNumberOver = 18
	// ErrTagNameOverlap 重複したタグ名が存在する
	ErrTagNameOverlap = 19
	// ErrContributionNoUser 投稿したユーザではない
	ErrContributionNoUser = 20
	// ErrPasswordMinLength パスワードが最低文字数以下
	ErrPasswordMinLength = 21
)

// errResponseMap エラーレスポンスマップ
var errResponseMap = map[int]ErrorResponse{
	ErrCodeCommon: {
		Message: "エラーが発生しました。",
	},
	ErrCodeUserNotFound: {
		Message: "ユーザ情報が取得できませんでした。もう一度、ログインして下さい。",
	},
	ErrCodeLoginNotFound: {
		Message: "この画面は、ログインしていないユーザーに使用できません",
	},
	ErrCreateUser: {
		Message: "ユーザ作成に失敗しました。もう一度登録お願い致します。",
	},
	ErrParameter: {
		Message: "不正なパラメータが送信されました。",
	},
	ErrImageConversion: {
		Message: "画像の変換に失敗しました。",
	},
	ErrImageResize: {
		Message: "画像のリサイズに失敗しました。",
	},
	ErrContributionNew: {
		Message: "投稿失敗しました。",
	},
	ErrContributionSave: {
		Message: "保存に失敗しました。",
	},
	ErrContributionTagSave: {
		Message: "タグ保存に失敗しました。",
	},
	ErrUserSave: {
		Message: "ユーザ保存に失敗しました。",
	},
	ErrUserOrPasswordDifferent: {
		Message: "メールアドレスとパスワードが一致しません。もう一度入力お願い致します。",
	},
	ErrContributionSearch: {
		Message: "検索結果の取得に失敗した。",
	},
	ErrFollowed: {
		Message: "既にフォロー済みです。",
	},
	ErrAddFollow: {
		Message: "フォローの登録に失敗しました。お手数ですが、もう一度追加お願い致します。",
	},
	ErrContributionNotFound: {
		Message: "存在しない投稿データです。",
	},
	ErrDeleteFollow: {
		Message: "フォローの削除に失敗しました。お手数ですが、もう一度操作お願い致します。",
	},
	ErrTagMaxNumberOver: {
		Message: "設定できるタグの数を超えました。追加する場合は、どれか削除してください。",
	},
	ErrTagNameOverlap: {
		Message: "既に同じタグが登録されています。",
	},
	ErrContributionNoUser: {
		Message: "自身の投稿ではないので、その操作は行なえません。",
	},
	ErrPasswordMinLength: {
		Message: "パスワードは8文字以上で設定して下さい。",
	},
}

// getErroResponse エラーレスポンスを取得する
func getErroResponse(errCode int) ErrorResponse {

	err := errResponseMap[errCode]
	err.ErrCode = errCode

	return err
}

// IsNoLogin ログインしているか判定する
func (c *BaseController) IsNoLogin(userID int) bool {
	if userID == noUserID {
		return false
	}

	return true
}

// ServerLoginNotFound ログイン無しで観覧できない
func (c *BaseController) ServerLoginNotFound() {
	c.ServerError(errors.New("login not found"), ErrCodeLoginNotFound, noUserID)
}

// ServerError サーバーエラーにする
func (c *BaseController) ServerError(err error, errCode int, userID int) {
	beego.Error("Error :", err.Error())
	logs.Err(err.Error(), userID)

	c.Ctx.ResponseWriter.WriteHeader(500)
	c.Data["json"] = getErroResponse(errCode)

	c.ServeJSON()
}

// isTest テスト環境か判定する
func isTest() bool {
	if beego.AppConfig.String("runmode") == "test" {
		return true
	}

	return false
}

// RedirectError エラーにリダレクトする
func (c *BaseController) RedirectError(err error, userID int) {

	logs.Err(err.Error(), userID)

	c.Redirect(beego.AppConfig.String("errorUrl"), 302)
}
<commit_msg>add error code<commit_after>package controllers

import (
	"errors"

	"github.com/wheatandcat/dotstamp_server/utils/log"

	"github.com/astaxie/beego"
)

// noUserID ユーザ無しID
const noUserID = 0

// BaseController ベースコントローラ
type BaseController struct {
	beego.Controller
}

// ErrorResponse エラー発生レスポンス
type ErrorResponse struct {
	Message string `json:"message"`
	ErrCode int    `json:"errCode"`
}

// Accessor ベースアクセサー
type Accessor interface {
	GetUserID() int
	ServerError()
}

const (
	// ErrCodeCommon 汎用エラー
	ErrCodeCommon = 1
	// ErrCodeUserNotFound ユーザ情報が取得できない or 不一致
	ErrCodeUserNotFound = 2
	// ErrCodeLoginNotFound ログインしていない
	ErrCodeLoginNotFound = 3
	// ErrCreateUser ユーザ登録に失敗
	ErrCreateUser = 4
	// ErrParameter パラメータエラー
	ErrParameter = 5
	// ErrImageConversion 画像変換エラー
	ErrImageConversion = 6
	// ErrImageResize 画像縮小エラー
	ErrImageResize = 7
	// ErrContributionNew 投稿失敗
	ErrContributionNew = 8
	// ErrContributionSave 投稿保存失敗
	ErrContributionSave = 9
	// ErrContributionTagSave 投稿タグ保存失敗
	ErrContributionTagSave = 10
	// ErrUserSave ユーザ保存失敗
	ErrUserSave = 11
	// ErrUserOrPasswordDifferent ユーザかパスワードが異なる
	ErrUserOrPasswordDifferent = 12
	// ErrContributionSearch 検索取得に失敗
	ErrContributionSearch = 13
	// ErrFollowed フォロー済み
	ErrFollowed = 14
	// ErrAddFollow フォロー追加失敗
	ErrAddFollow = 15
	// ErrContributionNotFound 投稿が存在しない
	ErrContributionNotFound = 16
	// ErrDeleteFollow フォロー削除失敗
	ErrDeleteFollow = 17
	// ErrTagMaxNumberOver タグの最大数を超えている
	ErrTagMaxNumberOver = 18
	// ErrTagNameOverlap 重複したタグ名が存在する
	ErrTagNameOverlap = 19
	// ErrContributionNoUser 投稿したユーザではない
	ErrContributionNoUser = 20
	// ErrPasswordMinLength パスワードが最低文字数以下
	ErrPasswordMinLength = 21
)

// errResponseMap エラーレスポンスマップ
var errResponseMap = map[int]ErrorResponse{
	ErrCodeCommon: {
		Message: "エラーが発生しました。",
	},
	ErrCodeUserNotFound: {
		Message: "ユーザ情報が取得できませんでした。もう一度、ログインして下さい。",
	},
	ErrCodeLoginNotFound: {
		Message: "この画面は、ログインしていないユーザーに使用できません",
	},
	ErrCreateUser: {
		Message: "ユーザ作成に失敗しました。もう一度登録お願い致します。",
	},
	ErrParameter: {
		Message: "不正なパラメータが送信されました。",
	},
	ErrImageConversion: {
		Message: "画像の変換に失敗しました。",
	},
	ErrImageResize: {
		Message: "画像のリサイズに失敗しました。",
	},
	ErrContributionNew: {
		Message: "投稿失敗しました。",
	},
	ErrContributionSave: {
		Message: "保存に失敗しました。",
	},
	ErrContributionTagSave: {
		Message: "タグ保存に失敗しました。",
	},
	ErrUserSave: {
		Message: "ユーザ保存に失敗しました。",
	},
	ErrUserOrPasswordDifferent: {
		Message: "メールアドレスとパスワードが一致しません。もう一度入力お願い致します。",
	},
	ErrContributionSearch: {
		Message: "検索結果の取得に失敗した。",
	},
	ErrFollowed: {
		Message: "既にフォロー済みです。",
	},
	ErrAddFollow: {
		Message: "フォローの登録に失敗しました。お手数ですが、もう一度追加お願い致します。",
	},
	ErrContributionNotFound: {
		Message: "存在しない投稿データです。",
	},
	ErrDeleteFollow: {
		Message: "フォローの削除に失敗しました。お手数ですが、もう一度操作お願い致します。",
	},
	ErrTagMaxNumberOver: {
		Message: "設定できるタグの数を超えました。追加する場合は、どれか削除してください。",
	},
	ErrTagNameOverlap: {
		Message: "既に同じタグが登録されています。",
	},
	ErrContributionNoUser: {
		Message: "自身の投稿ではないので、その操作は行なえません。",
	},
	ErrPasswordMinLength: {
		Message: "パスワードは8文字以上で設定して下さい。",
	},
}

// getErroResponse エラーレスポンスを取得する
func getErroResponse(errCode int) ErrorResponse {

	err := errResponseMap[errCode]
	err.ErrCode = errCode

	return err
}

// IsNoLogin ログインしているか判定する
func (c *BaseController) IsNoLogin(userID int) bool {
	if userID == noUserID {
		return false
	}

	return true
}

// ServerLoginNotFound ログイン無しで観覧できない
func (c *BaseController) ServerLoginNotFound() {
	c.ServerError(errors.New("login not found"), ErrCodeLoginNotFound, noUserID)
}

// ServerError サーバーエラーにする
func (c *BaseController) ServerError(err error, errCode int, userID int) {
	beego.Error("Error :", err.Error())
	logs.Err(err.Error(), userID)

	c.Ctx.ResponseWriter.WriteHeader(500)
	c.Data["json"] = getErroResponse(errCode)

	c.ServeJSON()
}

// isTest テスト環境か判定する
func isTest() bool {
	if beego.AppConfig.String("runmode") == "test" {
		return true
	}

	return false
}

// RedirectError エラーにリダレクトする
func (c *BaseController) RedirectError(err error, userID int) {

	logs.Err(err.Error(), userID)

	c.Redirect(beego.AppConfig.String("errorUrl"), 302)
}
<|endoftext|>


<commit_before>package controllers

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

	"github.com/tealeg/xlsx"

	"github.com/shwinpiocess/cc/models"
)

// oprations for Host
type HostController struct {
	BaseController
}

func (this *HostController) ImportPrivateHostByExcel() {
	out := make(map[string]interface{})
	fmt.Println("jing...............................")
	f, h, err := this.GetFile("importPrivateHost")
	fmt.Println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxjjjjjjjjjjjjjjjjjjjjjj f", f)
	if f == nil {
		out["success"] = false
		out["message"] = "请先提供后缀名为xlsx的Excel文件再进行上传操作！"
		out["name"] = "importToCC"
		goto render
	}
	defer f.Close()
	fmt.Println("uuuuuuuuuuuuuuuuuuuuuulllllllllllllllllllll")
	if err != nil {
		fmt.Println("111111111111111111111111111")
		out["success"] = false
		out["message"] = "主机导入失败！上传文件不合法！"
		out["name"] = "importToCC"
		goto render
	} else {
		if suffix := path.Ext(h.Filename); suffix != ".xlsx" {
			out["success"] = false
			out["message"] = "请提供后缀名为xlsx的Excel文件！"
			out["name"] = "importToCC"
			goto render
		}
		excelFileName := "static/upload/" + h.Filename
		this.SaveToFile("importPrivateHost", excelFileName)

		if xlFile, err := xlsx.OpenFile(excelFileName); err == nil {
			fmt.Println("222222222222222222222222222")
			var hosts []*models.Host
			var ips string
			var sns string

			defApp, w := models.GetDefAppByUserId(this.userId)
			fmt.Println("defApp=", defApp, "w=", w)

			for _, sheet := range xlFile.Sheets {
				for index, row := range sheet.Rows {
					fmt.Println("len(row.cells", len(row.Cells))
					if index > 0 && len(row.Cells) >= 6 {
						fmt.Println("3333333333333333333333333")
						Sn, err1 := row.Cells[0].Int64()
						Hostname, err2 := row.Cells[1].String()
						InnerIp, err3 := row.Cells[2].String()
						OuterIp, err4 := row.Cells[3].String()
						Operator, err5 := row.Cells[4].String()
						OsName, err6 := row.Cells[5].String()
						if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil || err6 != nil {
							fmt.Println("444444444444444444444")
							out["success"] = false
							out["message"] = "主机导入失败！上传文件内容格式不正确！"
							out["name"] = "importToCC"
							goto render
						} else {
							fmt.Println("5555555555555555555555555")
							if models.GetHostByInnerIp(InnerIp) {
								fmt.Println("err=", err)
								fmt.Println("6666666666666666666666")
								ips = ips + "
" + InnerIp + "
"
							}
							if models.GetHostBySn(Sn) {
								fmt.Println("7777777777777777777777777777777777")
								sns = sns + fmt.Sprintf("`SN`%d已存在
", Sn)
							}
							host := new(models.Host)
							host.SN = Sn
							host.HostName = Hostname
							host.InnerIP = InnerIp
							host.OuterIP = OuterIp
							host.Operator = Operator
							host.OSName = OsName
							host.Source = 3
							host.ApplicationID = defApp["AppId"].(int)
							host.ApplicationName = defApp["AppName"].(string)
							host.SetID = defApp["SetId"].(int)
							host.SetName = defApp["SetName"].(string)
							host.ModuleID = defApp["ModuleId"].(int)
							host.ModuleName = defApp["ModuleName"].(string)
							hosts = append(hosts, host)
						}
					}
				}
			}

			if ips != "" {
				fmt.Println("888888888888888888888888")
				out["success"] = false
				out["message"] = `有内网IP在私有云中已经存在,请先修改这些IP的平台再做导入,具体如下：<ul class="">` + ips + "
"
				out["name"] = "importToCC"
				goto render
			}

			if sns != "" {
				fmt.Println("999999999999999999999999999999999999")
				out["success"] = false
				out["message"] = sns
				out["name"] = "importToCC"
				goto render
			}

			if err := models.AddHost(hosts); err == nil {
				fmt.Println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa err=", err)
				out["success"] = true
				out["message"] = "导入成功！"
				out["name"] = "importToCC"
			} else {
				fmt.Println("bbbbbbbbbbbbbbbbbbbbbbbbbbbbberr=", err)
				out["success"] = false
				out["message"] = "主机导入数据库出现问题，请联系管理员！"
				out["name"] = "importToCC"
			}
		} else {
			fmt.Println("cccccccccccccccccccccccccccccccccccccccccccccccccccccc")
			out["success"] = false
			out["message"] = "主机导入失败！上传文件格式不正确！"
			out["name"] = "importToCC"
		}
    }

	render:
	fmt.Println("ddddddddddddddddddddddddddddddddddddddddd")
	this.Data["result"] = out
	this.TplName = "host/upload.html"
}

// @Title Get
// @Description get Host by id
// @Param	id		path 	string	true		"The key for staticblock"
// @Success 200 {object} models.Host
// @Failure 403 :id is empty
// @router /:id [get]
func (this *HostController) Details() {
	//ApplicationID	5295
	// HostID	3668910
	id, _ := this.GetInt("HostID")
	_, err := models.GetHostById(id)
	if err != nil {
		this.TplName = "host/details.html"
	} else {
		this.TplName = "host/details.html"
	}
}

func (this *HostController) GetHost4QuickImport() {
	isDistributed, _ := this.GetBool("IsDistributed")
	source := this.GetString("Source")
	applicationId := this.GetString("ApplicationID")

	var fields []string
	var sortby []string
	var order []string
	var query = make(map[string]interface{})
	var limit int64 = 0
	var offset int64 = 0

	query["is_distributed"] = isDistributed
	query["source"] = source

	if isDistributed {
		query["application_id"] = applicationId
	}

	fmt.Println("query=", query)

	// fields: col1,col2,entity.col3
	if v := this.GetString("fields"); v != "" {
		fields = strings.Split(v, ",")
	}
	// limit: 10 (default is 10)
	if v, err := this.GetInt64("limit"); err == nil {
		limit = v
	}
	// offset: 0 (default is 0)
	if v, err := this.GetInt64("offset"); err == nil {
		offset = v
	}
	// sortby: col1,col2
	if v := this.GetString("sortby"); v != "" {
		sortby = strings.Split(v, ",")
	}
	// order: desc,asc
	if v := this.GetString("order"); v != "" {
		order = strings.Split(v, ",")
	}
	// query: k:v,k:v
	if v := this.GetString("query"); v != "" {
		for _, cond := range strings.Split(v, ",") {
			kv := strings.Split(cond, ":")
			if len(kv) != 2 {
				this.Data["json"] = errors.New("Error: invalid query key/value pair")
				this.ServeJSON()
				return
			}
			k, v := kv[0], kv[1]
			query[k] = v
		}
	}

	l, err := models.GetAllHost(query, fields, sortby, order, offset, limit)

	out := make(map[string]interface{})
	if err != nil {
		out["success"] = false
		this.jsonResult(out)
	} else {
		out["success"] = true
		out["data"] = l
		out["total"] = len(l)
		this.jsonResult(out)
	}
}

func (this *HostController) Put() {
	idStr := this.Ctx.Input.Param(":id")
	id, _ := strconv.Atoi(idStr)
	v := models.Host{HostID: id}
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &v); err == nil {
		if err := models.UpdateHostById(&v); err == nil {
			this.Data["json"] = "OK"
		} else {
			this.Data["json"] = err.Error()
		}
	} else {
		this.Data["json"] = err.Error()
	}
	this.ServeJSON()
}

// 删除主机
func (this *HostController) DelPrivateDefaultApplicationHost() {
	idStr := this.GetString("HostID")
	var ids []int
	for _, v := range strings.Split(idStr, ",") {
		if id, err := strconv.Atoi(v); err == nil {
			ids = append(ids, id)
		}
	}

	out := make(map[string]interface{})
	if _, err := models.DeleteHosts(ids); err == nil {
		out["success"] = true
		out["message"] = "删除成功!"
		this.jsonResult(out)
	} else {
		out["success"] = false
		out["errInfo"] = err.Error()
		this.jsonResult(out)
	}
}

// 分配主机
func (this *HostController) QuickDistribute() {
	// HostID:29,30
	// ApplicationID:4043
	// ToApplicationID:4041
	out := make(map[string]interface{})
	idStr := this.GetString("HostID")
	var ids []int
	for _, v := range strings.Split(idStr, ",") {
		if id, err := strconv.Atoi(v); err == nil {
			ids = append(ids, id)
		}
	}

	if toApplicationID, err := this.GetInt("ToApplicationID"); err != nil {
		out["success"] = false
		out["errInfo"] = err.Error()
		this.jsonResult(out)
	} else {
		if _, err := models.UpdateHostToApp(ids, toApplicationID); err != nil {
			out["success"] = false
			out["errInfo"] = err
			this.jsonResult(out)
		}

		out["success"] = true
		out["message"] = "分配成功"
		this.jsonResult(out)
	}
}

// 上交主机
func (this *HostController) ResHostModule() {
	// ApplicationID:4048
	// HostID:34
	out := make(map[string]interface{})
	idStr := this.GetString("HostID")
	var ids []int
	for _, v := range strings.Split(idStr, ",") {
		if id, err := strconv.Atoi(v); err == nil {
			ids = append(ids, id)
		}
	}

	if appID, err := this.GetInt("ApplicationID"); err != nil {
		out["success"] = false
		out["errInfo"] = err.Error()
		out["message"] = err.Error()
		this.jsonResult(out)
	}else {
		if _, err := models.ResHostModule(ids, appID); err != nil {
			out["success"] = false
			out["errInfo"] = err
			out["message"] = err
			this.jsonResult(out)
		}

		out["success"] = true
		out["message"] = "上交成功"
		this.jsonResult(out)
	}
}

// 主机管理
func (this *HostController) HostQuery() {
	out := make(map[string]interface{})
	this.Data["data"], _ = models.GetEmptyById(this.defaultApp.Id)
	fmt.Println("777777777777777777-------------->>>>>", out)
	if this.defaultApp.Level == 3 {
		this.TplName = "host/hostQuery_set.html"
	} else {
		this.TplName = "host/hostQuery_mod.html"
	}
}

// 快速分配
func (this *HostController) QuickImport() {
	this.TplName = "host/quickImport.html"
}

func (this *HostController) GetHostById() {
	out := make(map[string]interface{})
//	var data []interface{}
	var fields []string
	var sortby []string
	var order []string
	var query = make(map[string]interface{})
	var limit int64 = 0
	var offset int64 = 0

	appId := this.GetString("ApplicationID")
	modId := this.GetString("ModuleID")
	query["application_id"] = appId
	query["module_id"] = modId

	data, _ := models.GetAllHost(query, fields, sortby, order, offset, limit)
	out["data"] = data
	out["total"] = len(data)
	this.jsonResult(out)
}
<commit_msg>修改上交主机代码逻辑，添加获取业务拓扑<commit_after>package controllers

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

	"github.com/tealeg/xlsx"

	"github.com/shwinpiocess/cc/models"
)

// oprations for Host
type HostController struct {
	BaseController
}

// 导入主机
func (this *HostController) ImportPrivateHostByExcel() {
	out := make(map[string]interface{})
	fmt.Println("jing...............................")
	f, h, err := this.GetFile("importPrivateHost")
	fmt.Println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxjjjjjjjjjjjjjjjjjjjjjj f", f)
	if f == nil {
		out["success"] = false
		out["message"] = "请先提供后缀名为xlsx的Excel文件再进行上传操作！"
		out["name"] = "importToCC"
		goto render
	}
	defer f.Close()
	fmt.Println("uuuuuuuuuuuuuuuuuuuuuulllllllllllllllllllll")
	if err != nil {
		fmt.Println("111111111111111111111111111")
		out["success"] = false
		out["message"] = "主机导入失败！上传文件不合法！"
		out["name"] = "importToCC"
		goto render
	} else {
		if suffix := path.Ext(h.Filename); suffix != ".xlsx" {
			out["success"] = false
			out["message"] = "请提供后缀名为xlsx的Excel文件！"
			out["name"] = "importToCC"
			goto render
		}
		excelFileName := "static/upload/" + h.Filename
		this.SaveToFile("importPrivateHost", excelFileName)

		if xlFile, err := xlsx.OpenFile(excelFileName); err == nil {
			fmt.Println("222222222222222222222222222")
			var hosts []*models.Host
			var ips string
			var sns string

			defApp, w := models.GetDefAppByUserId(this.userId)
			fmt.Println("defApp=", defApp, "w=", w)

			for _, sheet := range xlFile.Sheets {
				for index, row := range sheet.Rows {
					fmt.Println("len(row.cells", len(row.Cells))
					if index > 0 && len(row.Cells) >= 6 {
						fmt.Println("3333333333333333333333333")
						Sn, err1 := row.Cells[0].Int64()
						Hostname, err2 := row.Cells[1].String()
						InnerIp, err3 := row.Cells[2].String()
						OuterIp, err4 := row.Cells[3].String()
						Operator, err5 := row.Cells[4].String()
						OsName, err6 := row.Cells[5].String()
						if err1 != nil || err2 != nil || err3 != nil || err4 != nil || err5 != nil || err6 != nil {
							fmt.Println("444444444444444444444")
							out["success"] = false
							out["message"] = "主机导入失败！上传文件内容格式不正确！"
							out["name"] = "importToCC"
							goto render
						} else {
							fmt.Println("5555555555555555555555555")
							if models.GetHostByInnerIp(InnerIp) {
								fmt.Println("err=", err)
								fmt.Println("6666666666666666666666")
								ips = ips + "
" + InnerIp + "
"
							}
							if models.GetHostBySn(Sn) {
								fmt.Println("7777777777777777777777777777777777")
								sns = sns + fmt.Sprintf("`SN`%d已存在
", Sn)
							}
							host := new(models.Host)
							host.SN = Sn
							host.HostName = Hostname
							host.InnerIP = InnerIp
							host.OuterIP = OuterIp
							host.Operator = Operator
							host.OSName = OsName
							host.Source = 3
							host.ApplicationID = defApp["AppId"].(int)
							host.ApplicationName = defApp["AppName"].(string)
							host.SetID = defApp["SetId"].(int)
							host.SetName = defApp["SetName"].(string)
							host.ModuleID = defApp["ModuleId"].(int)
							host.ModuleName = defApp["ModuleName"].(string)
							hosts = append(hosts, host)
						}
					}
				}
			}

			if ips != "" {
				fmt.Println("888888888888888888888888")
				out["success"] = false
				out["message"] = `有内网IP在私有云中已经存在,请先修改这些IP的平台再做导入,具体如下：<ul class="">` + ips + "
"
				out["name"] = "importToCC"
				goto render
			}

			if sns != "" {
				fmt.Println("999999999999999999999999999999999999")
				out["success"] = false
				out["message"] = sns
				out["name"] = "importToCC"
				goto render
			}

			if err := models.AddHost(hosts); err == nil {
				fmt.Println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa err=", err)
				out["success"] = true
				out["message"] = "导入成功！"
				out["name"] = "importToCC"
			} else {
				fmt.Println("bbbbbbbbbbbbbbbbbbbbbbbbbbbbberr=", err)
				out["success"] = false
				out["message"] = "主机导入数据库出现问题，请联系管理员！"
				out["name"] = "importToCC"
			}
		} else {
			fmt.Println("cccccccccccccccccccccccccccccccccccccccccccccccccccccc")
			out["success"] = false
			out["message"] = "主机导入失败！上传文件格式不正确！"
			out["name"] = "importToCC"
		}
    }

	render:
	fmt.Println("ddddddddddddddddddddddddddddddddddddddddd")
	this.Data["result"] = out
	this.TplName = "host/upload.html"
}

// @Title Get
// @Description get Host by id
// @Param	id		path 	string	true		"The key for staticblock"
// @Success 200 {object} models.Host
// @Failure 403 :id is empty
// @router /:id [get]
func (this *HostController) Details() {
	//ApplicationID	5295
	// HostID	3668910
	id, _ := this.GetInt("HostID")
	_, err := models.GetHostById(id)
	if err != nil {
		this.TplName = "host/details.html"
	} else {
		this.TplName = "host/details.html"
	}
}

func (this *HostController) GetHost4QuickImport() {
	isDistributed, _ := this.GetBool("IsDistributed")
	source := this.GetString("Source")
	applicationId := this.GetString("ApplicationID")

	var fields []string
	var sortby []string
	var order []string
	var query = make(map[string]interface{})
	var limit int64 = 0
	var offset int64 = 0

	query["is_distributed"] = isDistributed
	query["source"] = source

	if isDistributed {
		query["application_id"] = applicationId
	}

	fmt.Println("query=", query)

	// fields: col1,col2,entity.col3
	if v := this.GetString("fields"); v != "" {
		fields = strings.Split(v, ",")
	}
	// limit: 10 (default is 10)
	if v, err := this.GetInt64("limit"); err == nil {
		limit = v
	}
	// offset: 0 (default is 0)
	if v, err := this.GetInt64("offset"); err == nil {
		offset = v
	}
	// sortby: col1,col2
	if v := this.GetString("sortby"); v != "" {
		sortby = strings.Split(v, ",")
	}
	// order: desc,asc
	if v := this.GetString("order"); v != "" {
		order = strings.Split(v, ",")
	}
	// query: k:v,k:v
	if v := this.GetString("query"); v != "" {
		for _, cond := range strings.Split(v, ",") {
			kv := strings.Split(cond, ":")
			if len(kv) != 2 {
				this.Data["json"] = errors.New("Error: invalid query key/value pair")
				this.ServeJSON()
				return
			}
			k, v := kv[0], kv[1]
			query[k] = v
		}
	}

	l, err := models.GetAllHost(query, fields, sortby, order, offset, limit)

	out := make(map[string]interface{})
	if err != nil {
		out["success"] = false
		this.jsonResult(out)
	} else {
		out["success"] = true
		out["data"] = l
		out["total"] = len(l)
		this.jsonResult(out)
	}
}

func (this *HostController) Put() {
	idStr := this.Ctx.Input.Param(":id")
	id, _ := strconv.Atoi(idStr)
	v := models.Host{HostID: id}
	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &v); err == nil {
		if err := models.UpdateHostById(&v); err == nil {
			this.Data["json"] = "OK"
		} else {
			this.Data["json"] = err.Error()
		}
	} else {
		this.Data["json"] = err.Error()
	}
	this.ServeJSON()
}

// 删除主机
func (this *HostController) DelPrivateDefaultApplicationHost() {
	idStr := this.GetString("HostID")
	var ids []int
	for _, v := range strings.Split(idStr, ",") {
		if id, err := strconv.Atoi(v); err == nil {
			ids = append(ids, id)
		}
	}

	out := make(map[string]interface{})
	if _, err := models.DeleteHosts(ids); err == nil {
		out["success"] = true
		out["message"] = "删除成功!"
		this.jsonResult(out)
	} else {
		out["success"] = false
		out["errInfo"] = err.Error()
		this.jsonResult(out)
	}
}

// 分配主机
func (this *HostController) QuickDistribute() {
	// HostID:29,30
	// ApplicationID:4043
	// ToApplicationID:4041
	out := make(map[string]interface{})
	idStr := this.GetString("HostID")
	var ids []int
	for _, v := range strings.Split(idStr, ",") {
		if id, err := strconv.Atoi(v); err == nil {
			ids = append(ids, id)
		}
	}

	if toApplicationID, err := this.GetInt("ToApplicationID"); err != nil {
		out["success"] = false
		out["errInfo"] = err.Error()
		this.jsonResult(out)
	} else {
		if _, err := models.UpdateHostToApp(ids, toApplicationID); err != nil {
			out["success"] = false
			out["errInfo"] = err
			this.jsonResult(out)
		}

		out["success"] = true
		out["message"] = "分配成功"
		this.jsonResult(out)
	}
}

// 上交主机
func (this *HostController) ResHostModule() {
	// ApplicationID:4048
	// HostID:34
	out := make(map[string]interface{})
	idStr := this.GetString("HostID")
	var ids []int
	for _, v := range strings.Split(idStr, ",") {
		if id, err := strconv.Atoi(v); err == nil {
			ids = append(ids, id)
		}
	}

	if defApp, err := models.GetDefAppByUserId(this.userId); err != nil {
		out["success"] = false
		this.jsonResult(out)
	} else {
		if _, err := this.GetInt("ApplicationID"); err != nil {
			out["success"] = false
			out["errInfo"] = err.Error()
			out["message"] = err.Error()
			this.jsonResult(out)
		}else {
			//TODO 判断指定的业务是否存在
			if _, err := models.ResHostModule(ids, defApp["AppId"].(int)); err != nil {
				out["success"] = false
				out["errInfo"] = err
				out["message"] = err
				this.jsonResult(out)
			}

			out["success"] = true
			out["message"] = "上交成功"
			this.jsonResult(out)
		}
	}
}

// 主机管理
func (this *HostController) HostQuery() {
	out := make(map[string]interface{})
	this.Data["data"], _ = models.GetEmptyById(this.defaultApp.Id)
	fmt.Println("777777777777777777-------------->>>>>", out)
	if this.defaultApp.Level == 3 {
		this.TplName = "host/hostQuery_set.html"
	} else {
		this.TplName = "host/hostQuery_mod.html"
	}
}

// 快速分配
func (this *HostController) QuickImport() {
	this.TplName = "host/quickImport.html"
}

func (this *HostController) GetHostById() {
	out := make(map[string]interface{})
//	var data []interface{}
	var fields []string
	var sortby []string
	var order []string
	var query = make(map[string]interface{})
	var limit int64 = 0
	var offset int64 = 0

	appId := this.GetString("ApplicationID")
	modId := this.GetString("ModuleID")
	query["application_id"] = appId
	query["module_id"] = modId

	data, _ := models.GetAllHost(query, fields, sortby, order, offset, limit)
	out["data"] = data
	out["total"] = len(data)
	this.jsonResult(out)
}

func (this *HostController) GetTopoTree4view() {
	out := make(map[string]interface{})
	if appID, err := this.GetInt("ApplicationID"); err != nil {
		out["success"] = false
		out["message"] = "参数不合法！"
		this.jsonResult(out)
	} else {
		if data, err := models.GetEmptyById(appID); err != nil {
			out["success"] = false
			out["message"] = err
			this.jsonResult(out)
		} else {
			out = data
			this.jsonResult(out)
		}
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"github.com/ellcrys/util"
	"github.com/ncodes/cocoon/core/ledgerchain/impl"
	"github.com/ncodes/cocoon/core/orderer"
	logging "github.com/op/go-logging"
	"github.com/spf13/cobra"
)

// ordererCmd represents the orderer command
var ordererCmd = &cobra.Command{
	Use:   "orderer",
	Short: "The orderer is the gateway to the immutable data store",
	Long:  `The orderer manages interaction between the data store and the rest of the cluster.`,
	Run: func(cmd *cobra.Command, args []string) {

		var log = logging.MustGetLogger("orderer")
		log.Info("Orderer has started")
		addr := util.Env("ORDERER_ADDR", "127.0.0.1:9000")
		ledgerChainConStr := util.Env("LEDGER_CHAIN_CONNECTION_STRING", "host=localhosts user=ned dbname=cocoonchain sslmode=disable password=")

		endedCh := make(chan bool)
		newOrderer := orderer.NewOrderer()
		newOrderer.SetLedgerChain(new(impl.PostgresLedgerChain))
		go newOrderer.Start(addr, ledgerChainConStr, endedCh)

		<-endedCh
	},
}

func init() {
	RootCmd.AddCommand(ordererCmd)
}
<commit_msg>set correct dev default connection string<commit_after>package cmd

import (
	"github.com/ellcrys/util"
	"github.com/ncodes/cocoon/core/ledgerchain/impl"
	"github.com/ncodes/cocoon/core/orderer"
	logging "github.com/op/go-logging"
	"github.com/spf13/cobra"
)

// ordererCmd represents the orderer command
var ordererCmd = &cobra.Command{
	Use:   "orderer",
	Short: "The orderer is the gateway to the immutable data store",
	Long:  `The orderer manages interaction between the data store and the rest of the cluster.`,
	Run: func(cmd *cobra.Command, args []string) {

		var log = logging.MustGetLogger("orderer")
		log.Info("Orderer has started")
		addr := util.Env("ORDERER_ADDR", "127.0.0.1:9000")
		ledgerChainConStr := util.Env("LEDGER_CHAIN_CONNECTION_STRING", "host=localhost user=ned dbname=cocoonchain sslmode=disable password=")

		endedCh := make(chan bool)
		newOrderer := orderer.NewOrderer()
		newOrderer.SetLedgerChain(new(impl.PostgresLedgerChain))
		go newOrderer.Start(addr, ledgerChainConStr, endedCh)

		<-endedCh
	},
}

func init() {
	RootCmd.AddCommand(ordererCmd)
}
<|endoftext|>


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

package core

import (
	"encoding/json"
	"io/ioutil"
	"strings"
	"testing"
)

func TestConfigBasic(t *testing.T) {
	ctx := NewContext()
	c := NewConfig(ctx)
	c.SetDefaults()

	if c.Workers != 0 {
		t.Error("workers failed.")
	}

	if c.Listen != RtmpListen {
		t.Error("listen failed.")
	}

	if c.Go.GcInterval != 0 {
		t.Error("go gc interval failed.")
	}

	if c.Log.Tank != "file" {
		t.Error("log tank failed.")
	}

	if c.Log.Level != "trace" {
		t.Error("log level failed.")
	}

	if c.Log.File != "oryx.log" {
		t.Error("log file failed.")
	}

	if c.Heartbeat.Enabled {
		t.Error("log heartbeat enabled failed")
	}

	if c.Heartbeat.Interval != 9.3 {
		t.Error("log heartbeat interval failed")
	}

	if c.Heartbeat.Url != "http://127.0.0.1:8085/api/v1/servers" {
		t.Error("log heartbeat url failed")
	}

	if c.Heartbeat.Summary {
		t.Error("log heartbeat summary failed")
	}

	if c.Stat.Network != 0 {
		t.Error("log stat network failed")
	}

	if len(c.Vhosts) != 0 {
		t.Error("vhosts is not empty")
	}
}

func BenchmarkConfigBasic(b *testing.B) {
	ctx := NewContext()
	pc := NewConfig(ctx)
	cc := NewConfig(ctx)
	if err := pc.Reload(cc); err != nil {
		b.Error("reload failed.")
	}
}

func TestJsonCommentReader(t *testing.T) {
	r := NewReader(strings.NewReader("winlin//comment\nyang/*abc*/2015'str/*//*/'"))
	b, err := ioutil.ReadAll(r)
	if err != nil {
		t.Error("failed, err is", err)
	}
	if string(b) != `winlinyang2015'str/*//*/'` {
		t.Error("failed, str is", string(b))
	}
}

func TestConfigReader(t *testing.T) {
	f := func(vs []string, eh func(string, string, string), ef func(error)) {
		for i := 0; i < len(vs)-1; i += 2 {
			o := vs[i]
			e := vs[i+1]

			if b, err := ioutil.ReadAll(NewReader(strings.NewReader(o))); err != nil {
				t.Error("read", o, "failed, err is", err)
				ef(err)
			} else {
				eh(o, e, string(b))
			}
		}
		return
	}

	f([]string{
		"//comments", "",
		"/*comments*/", "",
		"//comments\nabc", "abc",
		"/*comments*/abc", "abc",
		"a/*comments*/b", "ab",
		"a//comments\nb", "ab",
	}, func(v string, e string, o string) {
		if e != o {
			t.Error("for", v, "expect", len(e), "size", e, "but got", len(o), "size", o)
		}
	}, func(err error) {
		t.Error(err)
	})
}

func TestConfigComments(t *testing.T) {
	f := func(vs []string, eh func(string, interface{}, error)) {
		for _, v := range vs {
			j := json.NewDecoder(NewReader(strings.NewReader(v)))
			var o interface{}
			err := j.Decode(&o)
			eh(v, o, err)
		}
	}

	f([]string{
		`
        {
            // the RTMP listen port.
            "listen": 1935,
            // whether start in daemon for unix-like os.
            "daemon": false,
            /**
            * the go runtime config.
            * for go-oryx specified.
            */
            "go": {
                "gc_interval": 300,
                "max_threads": 0 // where 0 is use default.
            }
        }
        `,
	}, func(v string, o interface{}, err error) {
		if err != nil {
			t.Error("show pass for", v, "actual err is", err)
		}
	})

	f([]string{
		"{}//empty",
		"{}/*empty*/",

		`//c++ style
        {"listen": 1935}`,

		`/*c style*/
        {"listen": 1935}`,

		`/*c style*/{"listen": 1935}`,

		`//c++ style
        {"listen": 1935}
        //c++ style`,

		`/*c style*/
        {"listen": 1935}/*c style*/`,

		`/*c style*/ {"listen": /* c style */1935}`,

		`{"url": "http://server/api"}`,
	}, func(v string, o interface{}, err error) {
		if err != nil {
			t.Error("show pass for", v, "actual err is", err)
		}
	})

	f([]string{
		`{"listen": 1935}`,
		`{"listen": 1935, "daemon": true}`,
	}, func(v string, o interface{}, err error) {
		if err != nil {
			t.Error("show pass for", v, "actual err is", err)
		}
	})

	f([]string{
		"/*comments",
		`{"listen":1935/*comments}`,
	}, func(v string, o interface{}, err error) {
		if err == nil {
			t.Error("show failed for", v)
		}
	})
}

func TestSrsConfCommentReader(t *testing.T) {
	f := func(vs []string, eh func(string, string, error)) {
		for _, v := range vs {
			p := NewSrsConfCommentReader(strings.NewReader(v))
			str, err := ioutil.ReadAll(p)
			eh(v, string(str), err)
		}
	}

	f([]string{
		`string#`,
		`string#comments`,
		`string# comments `,
		`string# comments # xxx`,
	}, func(v, pv string, err error) {
		if err != nil {
			t.Error("should pass for", v, "and parsed to", pv, "actual err is", err)
		}
		if pv != "string" {
			t.Error("failed for", v, "and parsed to", pv)
		}
	})

	f([]string{
		`'string #vvv'`,
		`'string #vvv'# comments`,
		`'string #vvv'# comments # xxx`,
		`"string #vvv"`,
		`"string #vvv"# comments`,
	}, func(v, pv string, err error) {
		if err != nil {
			t.Error("should pass for", v, "and parsed to", pv, "actual err is", err)
		}
		pv = strings.Trim(pv, `"'`)
		if pv != "string #vvv" {
			t.Error("failed for", v, "and parsed to", pv)
		}
	})
}

func TestSrsConfStyle(t *testing.T) {
	f := func(vs []string, eh func(string, *Config, error)) {
		for _, v := range vs {
			p := NewSrsConfParser(strings.NewReader(v))
			ctx := NewContext()
			c := NewConfig(ctx)
			err := p.Decode(c)
			eh(v, c, err)
		}
	}

	f([]string{
		`listen 1935`,
		//`heartbeat { enabled on; interval 9.3; device_id "my-srs-device";`,
	}, func(v string, c *Config, err error) {
		if err == nil {
			t.Error("should failed for", v)
		}
	})

	f([]string{
		`listen 1935;`,
		`listen    1935;`,
		`listen 1935; # comments`,
		`# comments
		listen 1935;`,
		`# comments
		listen 1935; # comments`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if c.Listen != 1935 {
			t.Errorf("failed '%v', expect listen=1935, actual is %v", v, c.Listen)
		}
	})

	f([]string{
		`srs_log_file "./objs/#srs.log";`,
		`srs_log_file './objs/#srs.log';`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if c.Log.File != "./objs/#srs.log" {
			t.Errorf("failed '%v', expect log file='./objs/#srs.log', actual is %v", v, c.Log.File)
		}
	})

	f([]string{
		`listen 1935; chunk_size 60000;`,
		`listen 1935;
		chunk_size 60000;`,
		`listen 1935;

		chunk_size 60000;`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if c.Listen != 1935 {
			t.Errorf("should pass for '%v', expect listen=1935, actual is %v", v, c.Listen)
		}
		if c.ChunkSize != 60000 {
			t.Errorf("failed '%v', expect chunk_size=60000, actual is %v", v, c.ChunkSize)
		}
	})

	f([]string{
		`heartbeat {
			enabled on; interval 9.3; device_id "my-srs-device";
		}`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if !c.Heartbeat.Enabled {
			t.Error("failed", v, "for disabled.")
		}
		if c.Heartbeat.Interval != 9.3 {
			t.Error("failed", v, "for interval", c.Heartbeat.Interval, "!= 9.3")
		}
		if c.Heartbeat.DeviceId != "my-srs-device" {
			t.Error("failed", v, "for device_id", c.Heartbeat.DeviceId, "!= my-srs-device")
		}
	})
}
<commit_msg>refine code<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013-2016 Oryx(ossrs)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package core

import (
	"encoding/json"
	ocore "github.com/ossrs/go-oryx-lib/json"
	"io/ioutil"
	"strings"
	"testing"
)

func TestConfigBasic(t *testing.T) {
	ctx := NewContext()
	c := NewConfig(ctx)
	c.SetDefaults()

	if c.Workers != 0 {
		t.Error("workers failed.")
	}

	if c.Listen != RtmpListen {
		t.Error("listen failed.")
	}

	if c.Go.GcInterval != 0 {
		t.Error("go gc interval failed.")
	}

	if c.Log.Tank != "file" {
		t.Error("log tank failed.")
	}

	if c.Log.Level != "trace" {
		t.Error("log level failed.")
	}

	if c.Log.File != "oryx.log" {
		t.Error("log file failed.")
	}

	if c.Heartbeat.Enabled {
		t.Error("log heartbeat enabled failed")
	}

	if c.Heartbeat.Interval != 9.3 {
		t.Error("log heartbeat interval failed")
	}

	if c.Heartbeat.Url != "http://127.0.0.1:8085/api/v1/servers" {
		t.Error("log heartbeat url failed")
	}

	if c.Heartbeat.Summary {
		t.Error("log heartbeat summary failed")
	}

	if c.Stat.Network != 0 {
		t.Error("log stat network failed")
	}

	if len(c.Vhosts) != 0 {
		t.Error("vhosts is not empty")
	}
}

func BenchmarkConfigBasic(b *testing.B) {
	ctx := NewContext()
	pc := NewConfig(ctx)
	cc := NewConfig(ctx)
	if err := pc.Reload(cc); err != nil {
		b.Error("reload failed.")
	}
}

func TestJsonCommentReader(t *testing.T) {
	r := ocore.NewJsonPlusReader(strings.NewReader("winlin//comment\nyang/*abc*/2015'str/*//*/'"))
	b, err := ioutil.ReadAll(r)
	if err != nil {
		t.Error("failed, err is", err)
	}
	if string(b) != `winlinyang2015'str/*//*/'` {
		t.Error("failed, str is", string(b))
	}
}

func TestConfigReader(t *testing.T) {
	f := func(vs []string, eh func(string, string, string), ef func(error)) {
		for i := 0; i < len(vs)-1; i += 2 {
			o := vs[i]
			e := vs[i+1]

			if b, err := ioutil.ReadAll(ocore.NewJsonPlusReader(strings.NewReader(o))); err != nil {
				t.Error("read", o, "failed, err is", err)
				ef(err)
			} else {
				eh(o, e, string(b))
			}
		}
		return
	}

	f([]string{
		"//comments", "",
		"/*comments*/", "",
		"//comments\nabc", "abc",
		"/*comments*/abc", "abc",
		"a/*comments*/b", "ab",
		"a//comments\nb", "ab",
	}, func(v string, e string, o string) {
		if e != o {
			t.Error("for", v, "expect", len(e), "size", e, "but got", len(o), "size", o)
		}
	}, func(err error) {
		t.Error(err)
	})
}

func TestConfigComments(t *testing.T) {
	f := func(vs []string, eh func(string, interface{}, error)) {
		for _, v := range vs {
			j := json.NewDecoder(ocore.NewJsonPlusReader(strings.NewReader(v)))
			var o interface{}
			err := j.Decode(&o)
			eh(v, o, err)
		}
	}

	f([]string{
		`
        {
            // the RTMP listen port.
            "listen": 1935,
            // whether start in daemon for unix-like os.
            "daemon": false,
            /**
            * the go runtime config.
            * for go-oryx specified.
            */
            "go": {
                "gc_interval": 300,
                "max_threads": 0 // where 0 is use default.
            }
        }
        `,
	}, func(v string, o interface{}, err error) {
		if err != nil {
			t.Error("show pass for", v, "actual err is", err)
		}
	})

	f([]string{
		"{}//empty",
		"{}/*empty*/",

		`//c++ style
        {"listen": 1935}`,

		`/*c style*/
        {"listen": 1935}`,

		`/*c style*/{"listen": 1935}`,

		`//c++ style
        {"listen": 1935}
        //c++ style`,

		`/*c style*/
        {"listen": 1935}/*c style*/`,

		`/*c style*/ {"listen": /* c style */1935}`,

		`{"url": "http://server/api"}`,
	}, func(v string, o interface{}, err error) {
		if err != nil {
			t.Error("show pass for", v, "actual err is", err)
		}
	})

	f([]string{
		`{"listen": 1935}`,
		`{"listen": 1935, "daemon": true}`,
	}, func(v string, o interface{}, err error) {
		if err != nil {
			t.Error("show pass for", v, "actual err is", err)
		}
	})

	f([]string{
		"/*comments",
		`{"listen":1935/*comments}`,
	}, func(v string, o interface{}, err error) {
		if err == nil {
			t.Error("show failed for", v)
		}
	})
}

func TestSrsConfCommentReader(t *testing.T) {
	f := func(vs []string, eh func(string, string, error)) {
		for _, v := range vs {
			p := NewSrsConfCommentReader(strings.NewReader(v))
			str, err := ioutil.ReadAll(p)
			eh(v, string(str), err)
		}
	}

	f([]string{
		`string#`,
		`string#comments`,
		`string# comments `,
		`string# comments # xxx`,
	}, func(v, pv string, err error) {
		if err != nil {
			t.Error("should pass for", v, "and parsed to", pv, "actual err is", err)
		}
		if pv != "string" {
			t.Error("failed for", v, "and parsed to", pv)
		}
	})

	f([]string{
		`'string #vvv'`,
		`'string #vvv'# comments`,
		`'string #vvv'# comments # xxx`,
		`"string #vvv"`,
		`"string #vvv"# comments`,
	}, func(v, pv string, err error) {
		if err != nil {
			t.Error("should pass for", v, "and parsed to", pv, "actual err is", err)
		}
		pv = strings.Trim(pv, `"'`)
		if pv != "string #vvv" {
			t.Error("failed for", v, "and parsed to", pv)
		}
	})
}

func TestSrsConfStyle(t *testing.T) {
	f := func(vs []string, eh func(string, *Config, error)) {
		for _, v := range vs {
			p := NewSrsConfParser(strings.NewReader(v))
			ctx := NewContext()
			c := NewConfig(ctx)
			err := p.Decode(c)
			eh(v, c, err)
		}
	}

	f([]string{
		`listen 1935`,
		//`heartbeat { enabled on; interval 9.3; device_id "my-srs-device";`,
	}, func(v string, c *Config, err error) {
		if err == nil {
			t.Error("should failed for", v)
		}
	})

	f([]string{
		`listen 1935;`,
		`listen    1935;`,
		`listen 1935; # comments`,
		`# comments
		listen 1935;`,
		`# comments
		listen 1935; # comments`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if c.Listen != 1935 {
			t.Errorf("failed '%v', expect listen=1935, actual is %v", v, c.Listen)
		}
	})

	f([]string{
		`srs_log_file "./objs/#srs.log";`,
		`srs_log_file './objs/#srs.log';`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if c.Log.File != "./objs/#srs.log" {
			t.Errorf("failed '%v', expect log file='./objs/#srs.log', actual is %v", v, c.Log.File)
		}
	})

	f([]string{
		`listen 1935; chunk_size 60000;`,
		`listen 1935;
		chunk_size 60000;`,
		`listen 1935;

		chunk_size 60000;`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if c.Listen != 1935 {
			t.Errorf("should pass for '%v', expect listen=1935, actual is %v", v, c.Listen)
		}
		if c.ChunkSize != 60000 {
			t.Errorf("failed '%v', expect chunk_size=60000, actual is %v", v, c.ChunkSize)
		}
	})

	f([]string{
		`heartbeat {
			enabled on; interval 9.3; device_id "my-srs-device";
		}`,
	}, func(v string, c *Config, err error) {
		if err != nil {
			t.Error("should pass for", v, "actual err is", err)
		}
		if !c.Heartbeat.Enabled {
			t.Error("failed", v, "for disabled.")
		}
		if c.Heartbeat.Interval != 9.3 {
			t.Error("failed", v, "for interval", c.Heartbeat.Interval, "!= 9.3")
		}
		if c.Heartbeat.DeviceId != "my-srs-device" {
			t.Error("failed", v, "for device_id", c.Heartbeat.DeviceId, "!= my-srs-device")
		}
	})
}
<|endoftext|>


<commit_before>package engine

import (
	"crypto/sha256"
	"fmt"
	"strings"
	"time"

	jsonw "github.com/keybase/go-jsonw"
	"github.com/keybase/go/libkb"
	keybase_1 "github.com/keybase/protocol/go"
	"golang.org/x/crypto/scrypt"
)

type KexStrongID [32]byte
type KexWeakID [16]byte

type KexContext struct {
	UserID   libkb.UID
	WeakID   KexWeakID
	StrongID KexStrongID
	Src      libkb.DeviceID
	Dst      libkb.DeviceID
}

func (c *KexContext) Swap() {
	c.Src, c.Dst = c.Dst, c.Src
}

type KexServer interface {
	StartKexSession(ctx *KexContext, id KexStrongID) error
	StartReverseKexSession(ctx *KexContext) error
	Hello(ctx *KexContext, devID libkb.DeviceID, devKeyID libkb.KID) error
	PleaseSign(ctx *KexContext, eddsa libkb.NaclSigningKeyPublic, sig, devType, devDesc string) error
	Done(ctx *KexContext, mt libkb.MerkleTriple) error

	// XXX get rid of this when real client comm works
	RegisterTestDevice(srv KexServer, device libkb.DeviceID) error
}

type Kex struct {
	server        KexServer
	user          *libkb.User
	deviceID      libkb.DeviceID
	deviceSibkey  libkb.GenericKey
	sigKey        libkb.GenericKey
	sessionID     KexStrongID
	helloReceived chan bool
	doneReceived  chan bool
	debugName     string
	xDevKeyID     libkb.KID
	uig           *libkb.UIGroup
	lks           *libkb.LKSec
	getSecret     func() string // testing only
}

var kexTimeout = 5 * time.Minute

func NewKex(s KexServer, lksCli []byte, uig *libkb.UIGroup, options ...func(*Kex)) *Kex {
	k := &Kex{server: s, uig: uig, helloReceived: make(chan bool, 1), doneReceived: make(chan bool, 1)}
	k.lks = libkb.NewLKSecClientHalf(lksCli)
	for _, opt := range options {
		opt(k)
	}
	return k
}

func SetDebugName(name string) func(k *Kex) {
	return func(k *Kex) {
		k.debugName = name
	}
}

func (k *Kex) StartForward(u *libkb.User, src, dst libkb.DeviceID, devType, devDesc string) error {
	k.user = u
	k.deviceID = src

	// XXX this is just for testing
	k.server.RegisterTestDevice(k, src)

	// make random secret S
	words, id, err := k.secret()
	if err != nil {
		return err
	}

	k.sessionID = id

	ctx := &KexContext{
		UserID:   k.user.GetUid(),
		StrongID: id,
		Src:      src,
		Dst:      dst,
	}
	copy(ctx.WeakID[:], id[0:16])

	// tell user the command to enter on existing device (X)
	// note: this has to happen before StartKexSession call for tests to work.
	if err := k.uig.Doctor.DisplaySecretWords(keybase_1.DisplaySecretWordsArg{XDevDescription: devDesc, Secret: strings.Join(words, " ")}); err != nil {
		return err
	}

	if err := k.server.StartKexSession(ctx, id); err != nil {
		return err
	}

	// wait for Hello() from X
	if err := k.waitHello(); err != nil {
		return err
	}

	// E_y
	eddsa, err := libkb.GenerateNaclSigningKeyPair()
	if err != nil {
		return err
	}
	eddsaPair, ok := eddsa.(libkb.NaclSigningKeyPair)
	if !ok {
		return fmt.Errorf("invalid key type %T", eddsa)
	}

	// M_y
	dh, err := libkb.GenerateNaclDHKeyPair()
	if err != nil {
		return err
	}

	// store E_y, M_y in lks
	if _, err := libkb.WriteLksSKBToKeyring(k.user.GetName(), eddsa, k.lks, k.uig.Log); err != nil {
		return err
	}
	if _, err := libkb.WriteLksSKBToKeyring(k.user.GetName(), dh, k.lks, k.uig.Log); err != nil {
		return err
	}

	// The signature sent to PleaseSign is a reverse sig
	// of X's dev key id.
	rsp := libkb.ReverseSigPayload{k.xDevKeyID.String()}
	sig, _, _, err := libkb.SignJson(jsonw.NewWrapper(rsp), eddsa)
	if err != nil {
		return err
	}

	ctx.Src = src
	ctx.Dst = dst
	if err := k.server.PleaseSign(ctx, eddsaPair.Public, sig, devType, devDesc); err != nil {
		return err
	}

	// wait for Done() from X
	if err := k.waitDone(); err != nil {
		return err
	}

	// Device y signs M_y into Alice's sigchain as a subkey.
	devY := libkb.Device{
		Id:          k.deviceID.String(),
		Type:        devType,
		Description: &devDesc,
	}
	g := func() (libkb.NaclKeyPair, error) {
		return dh, nil
	}
	arg := libkb.NaclKeyGenArg{
		Signer:      eddsa,
		ExpireIn:    libkb.NACL_DH_EXPIRE_IN,
		Sibkey:      false,
		Me:          k.user,
		EldestKeyID: k.user.GetEldestFOKID().Kid,
		Generator:   g,
		Device:      &devY,
	}
	gen := libkb.NewNaclKeyGen(arg)
	if err := gen.Generate(); err != nil {
		return fmt.Errorf("gen.Generate() error: %s", err)
	}
	if _, err := gen.Push(); err != nil {
		return fmt.Errorf("gen.Push() error: %s", err)
	}

	// store the new device id
	if wr := G.Env.GetConfigWriter(); wr != nil {
		if err := wr.SetDeviceID(&k.deviceID); err != nil {
			return err
		} else if err := wr.Write(); err != nil {
			return err
		} else {
			G.Log.Info("Setting Device ID to %s", k.deviceID)
		}
	}

	return nil
}

// XXX temporary...
// this is to get around the fact that the globals won't work well
// in the test with two devices communicating in the same process.
func (k *Kex) Listen(u *libkb.User, src libkb.DeviceID) {
	k.user = u
	k.deviceID = src
	var err error
	k.deviceSibkey, err = k.user.GetComputedKeyFamily().GetSibkeyForDevice(src)
	if err != nil {
		G.Log.Warning("kex.Listen: error getting device sibkey: %s", err)
	}
	k.sigKey, err = G.Keyrings.GetSecretKey("new device install", k.uig.Secret, k.user)
	if err != nil {
		G.Log.Warning("GetSecretKey error: %s", err)
	}
}

func (k *Kex) waitHello() error {
	G.Log.Info("[%s] waitHello start", k.debugName)
	defer G.Log.Info("[%s] waitHello done", k.debugName)
	select {
	case <-k.helloReceived:
		G.Log.Info("[%s] hello received", k.debugName)
		return nil
	case <-time.After(kexTimeout):
		return fmt.Errorf("timeout waiting for Hello")
	}
}

func (k *Kex) waitDone() error {
	G.Log.Info("[%s] waitDone start", k.debugName)
	defer G.Log.Info("[%s] waitDone done", k.debugName)
	select {
	case <-k.doneReceived:
		G.Log.Info("[%s] done received", k.debugName)
		return nil
	case <-time.After(kexTimeout):
		return fmt.Errorf("timeout waiting for Done")
	}
}

func (k *Kex) secret() (words []string, id [32]byte, err error) {
	words, err = libkb.SecWordList(5)
	if err != nil {
		return
	}
	id, err = k.wordsToID(strings.Join(words, " "))
	if err != nil {
		return
	}

	return words, id, err
}

func (k *Kex) wordsToID(words string) ([32]byte, error) {
	key, err := scrypt.Key([]byte(words), []byte(k.user.GetName()), 32768, 8, 1, 32)
	if err != nil {
		return [32]byte{}, err
	}
	return sha256.Sum256(key), nil
}

func (k *Kex) StartKexSession(ctx *KexContext, id KexStrongID) error {
	G.Log.Info("[%s] StartKexSession: %x", k.debugName, id)
	defer G.Log.Info("[%s] StartKexSession done", k.debugName)

	if err := k.verifyDst(ctx); err != nil {
		return err
	}

	// generate secret
	if k.getSecret != nil {
		// this is for testing.
		words := k.getSecret()
		G.Log.Info("[%s] secret: %q", k.debugName, words)
		id, err := k.wordsToID(words)
		if err != nil {
			return err
		}
		k.sessionID = id
	}

	if err := k.verifySession(ctx); err != nil {
		return err
	}

	ctx.Swap()
	pair, ok := k.deviceSibkey.(libkb.NaclSigningKeyPair)
	if !ok {
		return fmt.Errorf("invalid device sibkey type %T", k.deviceSibkey)
	}
	return k.server.Hello(ctx, ctx.Src, pair.GetKid())
}

func (k *Kex) StartReverseKexSession(ctx *KexContext) error { return nil }

func (k *Kex) Hello(ctx *KexContext, devID libkb.DeviceID, devKeyID libkb.KID) error {
	G.Log.Info("[%s] Hello Receive", k.debugName)
	defer G.Log.Info("[%s] Hello Receive done", k.debugName)
	if err := k.verifyRequest(ctx); err != nil {
		return err
	}

	k.xDevKeyID = devKeyID

	k.helloReceived <- true
	return nil
}

// sig is the reverse sig.
func (k *Kex) PleaseSign(ctx *KexContext, eddsa libkb.NaclSigningKeyPublic, sig, devType, devDesc string) error {
	G.Log.Info("[%s] PleaseSign Receive", k.debugName)
	defer G.Log.Info("[%s] PleaseSign Receive done", k.debugName)
	if err := k.verifyRequest(ctx); err != nil {
		return err
	}

	rs := &libkb.ReverseSig{Sig: sig, Type: "kb"}

	// make device object for Y
	devY := libkb.Device{
		Id:          ctx.Src.String(),
		Type:        devType,
		Description: &devDesc,
	}

	// generator function that just copies the public eddsa key into a
	// NaclKeyPair (which implements GenericKey).
	g := func() (libkb.NaclKeyPair, error) {
		var ret libkb.NaclSigningKeyPair
		copy(ret.Public[:], eddsa[:])
		return ret, nil
	}

	// need the private device sibkey
	// k.deviceSibkey is public only
	// going to use keyring.go:GetSecretKey()
	// however, it could return any key.
	// there is a ticket to add preferences to it so we could only
	// get a device key.
	// but it should currently return a device key first...
	if k.sigKey == nil {
		var err error
		k.sigKey, err = G.Keyrings.GetSecretKey("new device install", k.uig.Secret, k.user)
		if err != nil {
			return err
		}
	}

	// use naclkeygen to sign eddsa with device X (this device) sibkey
	// and push it to the server
	arg := libkb.NaclKeyGenArg{
		Signer:      k.sigKey,
		ExpireIn:    libkb.NACL_EDDSA_EXPIRE_IN,
		Sibkey:      true,
		Me:          k.user,
		Device:      &devY,
		EldestKeyID: k.user.GetEldestFOKID().Kid,
		RevSig:      rs,
		Generator:   g,
	}
	gen := libkb.NewNaclKeyGen(arg)
	if err := gen.Generate(); err != nil {
		return fmt.Errorf("gen.Generate() error: %s", err)
	}
	mt, err := gen.Push()
	if err != nil {
		return fmt.Errorf("gen.Push() error: %s", err)
	}

	ctx.Swap()
	return k.server.Done(ctx, mt)
}

func (k *Kex) Done(ctx *KexContext, mt libkb.MerkleTriple) error {
	G.Log.Info("[%s] Done Receive", k.debugName)
	defer G.Log.Info("[%s] Done Receive done", k.debugName)
	if err := k.verifyRequest(ctx); err != nil {
		return err
	}

	// device X changed the sigchain, so bump it here
	k.user.SigChainBumpMT(mt)

	k.doneReceived <- true
	return nil
}

func (k *Kex) RegisterTestDevice(srv KexServer, device libkb.DeviceID) error { return nil }

func (k *Kex) verifyDst(ctx *KexContext) error {
	if ctx.Dst != k.deviceID {
		return fmt.Errorf("destination device id (%s) invalid.  this is device (%s).", ctx.Dst, k.deviceID)
	}
	return nil
}

func (k *Kex) verifySession(ctx *KexContext) error {
	if ctx.StrongID != k.sessionID {
		return fmt.Errorf("%s: context StrongID (%x) != sessionID (%x)", k.debugName, ctx.StrongID, k.sessionID)
	}
	return nil
}

func (k *Kex) verifyRequest(ctx *KexContext) error {
	if err := k.verifyDst(ctx); err != nil {
		return err
	}
	if err := k.verifySession(ctx); err != nil {
		return err
	}
	return nil
}
<commit_msg>comments<commit_after>package engine

import (
	"crypto/sha256"
	"fmt"
	"strings"
	"time"

	jsonw "github.com/keybase/go-jsonw"
	"github.com/keybase/go/libkb"
	keybase_1 "github.com/keybase/protocol/go"
	"golang.org/x/crypto/scrypt"
)

type KexStrongID [32]byte
type KexWeakID [16]byte

type KexContext struct {
	UserID   libkb.UID
	WeakID   KexWeakID   // `w` in doc
	StrongID KexStrongID // `I` in doc
	Src      libkb.DeviceID
	Dst      libkb.DeviceID
}

func (c *KexContext) Swap() {
	c.Src, c.Dst = c.Dst, c.Src
}

type KexServer interface {
	StartKexSession(ctx *KexContext, id KexStrongID) error
	StartReverseKexSession(ctx *KexContext) error
	Hello(ctx *KexContext, devID libkb.DeviceID, devKeyID libkb.KID) error
	PleaseSign(ctx *KexContext, eddsa libkb.NaclSigningKeyPublic, sig, devType, devDesc string) error
	Done(ctx *KexContext, mt libkb.MerkleTriple) error

	// XXX get rid of this when real client comm works
	RegisterTestDevice(srv KexServer, device libkb.DeviceID) error
}

type Kex struct {
	server        KexServer
	user          *libkb.User
	deviceID      libkb.DeviceID
	deviceSibkey  libkb.GenericKey
	sigKey        libkb.GenericKey
	sessionID     KexStrongID
	helloReceived chan bool
	doneReceived  chan bool
	debugName     string
	xDevKeyID     libkb.KID
	uig           *libkb.UIGroup
	lks           *libkb.LKSec
	getSecret     func() string // testing only
}

var kexTimeout = 5 * time.Minute

func NewKex(s KexServer, lksCli []byte, uig *libkb.UIGroup, options ...func(*Kex)) *Kex {
	k := &Kex{server: s, uig: uig, helloReceived: make(chan bool, 1), doneReceived: make(chan bool, 1)}
	k.lks = libkb.NewLKSecClientHalf(lksCli)
	for _, opt := range options {
		opt(k)
	}
	return k
}

func SetDebugName(name string) func(k *Kex) {
	return func(k *Kex) {
		k.debugName = name
	}
}

func (k *Kex) StartForward(u *libkb.User, src, dst libkb.DeviceID, devType, devDesc string) error {
	k.user = u
	k.deviceID = src

	// XXX this is just for testing
	k.server.RegisterTestDevice(k, src)

	// make random secret S
	words, id, err := k.secret()
	if err != nil {
		return err
	}

	k.sessionID = id

	ctx := &KexContext{
		UserID:   k.user.GetUid(),
		StrongID: id,
		Src:      src,
		Dst:      dst,
	}
	copy(ctx.WeakID[:], id[0:16])

	// tell user the command to enter on existing device (X)
	// note: this has to happen before StartKexSession call for tests to work.
	if err := k.uig.Doctor.DisplaySecretWords(keybase_1.DisplaySecretWordsArg{XDevDescription: devDesc, Secret: strings.Join(words, " ")}); err != nil {
		return err
	}

	if err := k.server.StartKexSession(ctx, id); err != nil {
		return err
	}

	// wait for Hello() from X
	if err := k.waitHello(); err != nil {
		return err
	}

	// E_y
	eddsa, err := libkb.GenerateNaclSigningKeyPair()
	if err != nil {
		return err
	}
	eddsaPair, ok := eddsa.(libkb.NaclSigningKeyPair)
	if !ok {
		return fmt.Errorf("invalid key type %T", eddsa)
	}

	// M_y
	dh, err := libkb.GenerateNaclDHKeyPair()
	if err != nil {
		return err
	}

	// store E_y, M_y in lks
	if _, err := libkb.WriteLksSKBToKeyring(k.user.GetName(), eddsa, k.lks, k.uig.Log); err != nil {
		return err
	}
	if _, err := libkb.WriteLksSKBToKeyring(k.user.GetName(), dh, k.lks, k.uig.Log); err != nil {
		return err
	}

	// The signature sent to PleaseSign is a reverse sig
	// of X's dev key id.
	rsp := libkb.ReverseSigPayload{k.xDevKeyID.String()}
	sig, _, _, err := libkb.SignJson(jsonw.NewWrapper(rsp), eddsa)
	if err != nil {
		return err
	}

	ctx.Src = src
	ctx.Dst = dst
	if err := k.server.PleaseSign(ctx, eddsaPair.Public, sig, devType, devDesc); err != nil {
		return err
	}

	// wait for Done() from X
	if err := k.waitDone(); err != nil {
		return err
	}

	// Device y signs M_y into Alice's sigchain as a subkey.
	devY := libkb.Device{
		Id:          k.deviceID.String(),
		Type:        devType,
		Description: &devDesc,
	}
	g := func() (libkb.NaclKeyPair, error) {
		return dh, nil
	}
	arg := libkb.NaclKeyGenArg{
		Signer:      eddsa,
		ExpireIn:    libkb.NACL_DH_EXPIRE_IN,
		Sibkey:      false,
		Me:          k.user,
		EldestKeyID: k.user.GetEldestFOKID().Kid,
		Generator:   g,
		Device:      &devY,
	}
	gen := libkb.NewNaclKeyGen(arg)
	if err := gen.Generate(); err != nil {
		return fmt.Errorf("gen.Generate() error: %s", err)
	}
	if _, err := gen.Push(); err != nil {
		return fmt.Errorf("gen.Push() error: %s", err)
	}

	// store the new device id
	if wr := G.Env.GetConfigWriter(); wr != nil {
		if err := wr.SetDeviceID(&k.deviceID); err != nil {
			return err
		} else if err := wr.Write(); err != nil {
			return err
		} else {
			G.Log.Info("Setting Device ID to %s", k.deviceID)
		}
	}

	return nil
}

// XXX temporary...
// this is to get around the fact that the globals won't work well
// in the test with two devices communicating in the same process.
func (k *Kex) Listen(u *libkb.User, src libkb.DeviceID) {
	k.user = u
	k.deviceID = src
	var err error
	k.deviceSibkey, err = k.user.GetComputedKeyFamily().GetSibkeyForDevice(src)
	if err != nil {
		G.Log.Warning("kex.Listen: error getting device sibkey: %s", err)
	}
	k.sigKey, err = G.Keyrings.GetSecretKey("new device install", k.uig.Secret, k.user)
	if err != nil {
		G.Log.Warning("GetSecretKey error: %s", err)
	}
}

func (k *Kex) waitHello() error {
	G.Log.Info("[%s] waitHello start", k.debugName)
	defer G.Log.Info("[%s] waitHello done", k.debugName)
	select {
	case <-k.helloReceived:
		G.Log.Info("[%s] hello received", k.debugName)
		return nil
	case <-time.After(kexTimeout):
		return fmt.Errorf("timeout waiting for Hello")
	}
}

func (k *Kex) waitDone() error {
	G.Log.Info("[%s] waitDone start", k.debugName)
	defer G.Log.Info("[%s] waitDone done", k.debugName)
	select {
	case <-k.doneReceived:
		G.Log.Info("[%s] done received", k.debugName)
		return nil
	case <-time.After(kexTimeout):
		return fmt.Errorf("timeout waiting for Done")
	}
}

func (k *Kex) secret() (words []string, id [32]byte, err error) {
	words, err = libkb.SecWordList(5)
	if err != nil {
		return
	}
	id, err = k.wordsToID(strings.Join(words, " "))
	if err != nil {
		return
	}

	return words, id, err
}

func (k *Kex) wordsToID(words string) ([32]byte, error) {
	key, err := scrypt.Key([]byte(words), []byte(k.user.GetName()), 32768, 8, 1, 32)
	if err != nil {
		return [32]byte{}, err
	}
	return sha256.Sum256(key), nil
}

func (k *Kex) StartKexSession(ctx *KexContext, id KexStrongID) error {
	G.Log.Info("[%s] StartKexSession: %x", k.debugName, id)
	defer G.Log.Info("[%s] StartKexSession done", k.debugName)

	if err := k.verifyDst(ctx); err != nil {
		return err
	}

	// generate secret
	if k.getSecret != nil {
		// this is for testing.
		words := k.getSecret()
		G.Log.Info("[%s] secret: %q", k.debugName, words)
		id, err := k.wordsToID(words)
		if err != nil {
			return err
		}
		k.sessionID = id
	}

	if err := k.verifySession(ctx); err != nil {
		return err
	}

	ctx.Swap()
	pair, ok := k.deviceSibkey.(libkb.NaclSigningKeyPair)
	if !ok {
		return fmt.Errorf("invalid device sibkey type %T", k.deviceSibkey)
	}
	return k.server.Hello(ctx, ctx.Src, pair.GetKid())
}

func (k *Kex) StartReverseKexSession(ctx *KexContext) error { return nil }

func (k *Kex) Hello(ctx *KexContext, devID libkb.DeviceID, devKeyID libkb.KID) error {
	G.Log.Info("[%s] Hello Receive", k.debugName)
	defer G.Log.Info("[%s] Hello Receive done", k.debugName)
	if err := k.verifyRequest(ctx); err != nil {
		return err
	}

	k.xDevKeyID = devKeyID

	k.helloReceived <- true
	return nil
}

// sig is the reverse sig.
func (k *Kex) PleaseSign(ctx *KexContext, eddsa libkb.NaclSigningKeyPublic, sig, devType, devDesc string) error {
	G.Log.Info("[%s] PleaseSign Receive", k.debugName)
	defer G.Log.Info("[%s] PleaseSign Receive done", k.debugName)
	if err := k.verifyRequest(ctx); err != nil {
		return err
	}

	rs := &libkb.ReverseSig{Sig: sig, Type: "kb"}

	// make device object for Y
	devY := libkb.Device{
		Id:          ctx.Src.String(),
		Type:        devType,
		Description: &devDesc,
	}

	// generator function that just copies the public eddsa key into a
	// NaclKeyPair (which implements GenericKey).
	g := func() (libkb.NaclKeyPair, error) {
		var ret libkb.NaclSigningKeyPair
		copy(ret.Public[:], eddsa[:])
		return ret, nil
	}

	// need the private device sibkey
	// k.deviceSibkey is public only
	// going to use keyring.go:GetSecretKey()
	// however, it could return any key.
	// there is a ticket to add preferences to it so we could only
	// get a device key.
	// but it should currently return a device key first...
	if k.sigKey == nil {
		var err error
		k.sigKey, err = G.Keyrings.GetSecretKey("new device install", k.uig.Secret, k.user)
		if err != nil {
			return err
		}
	}

	// use naclkeygen to sign eddsa with device X (this device) sibkey
	// and push it to the server
	arg := libkb.NaclKeyGenArg{
		Signer:      k.sigKey,
		ExpireIn:    libkb.NACL_EDDSA_EXPIRE_IN,
		Sibkey:      true,
		Me:          k.user,
		Device:      &devY,
		EldestKeyID: k.user.GetEldestFOKID().Kid,
		RevSig:      rs,
		Generator:   g,
	}
	gen := libkb.NewNaclKeyGen(arg)
	if err := gen.Generate(); err != nil {
		return fmt.Errorf("gen.Generate() error: %s", err)
	}
	mt, err := gen.Push()
	if err != nil {
		return fmt.Errorf("gen.Push() error: %s", err)
	}

	ctx.Swap()
	return k.server.Done(ctx, mt)
}

func (k *Kex) Done(ctx *KexContext, mt libkb.MerkleTriple) error {
	G.Log.Info("[%s] Done Receive", k.debugName)
	defer G.Log.Info("[%s] Done Receive done", k.debugName)
	if err := k.verifyRequest(ctx); err != nil {
		return err
	}

	// device X changed the sigchain, so bump it here
	k.user.SigChainBumpMT(mt)

	k.doneReceived <- true
	return nil
}

func (k *Kex) RegisterTestDevice(srv KexServer, device libkb.DeviceID) error { return nil }

func (k *Kex) verifyDst(ctx *KexContext) error {
	if ctx.Dst != k.deviceID {
		return fmt.Errorf("destination device id (%s) invalid.  this is device (%s).", ctx.Dst, k.deviceID)
	}
	return nil
}

func (k *Kex) verifySession(ctx *KexContext) error {
	if ctx.StrongID != k.sessionID {
		return fmt.Errorf("%s: context StrongID (%x) != sessionID (%x)", k.debugName, ctx.StrongID, k.sessionID)
	}
	return nil
}

func (k *Kex) verifyRequest(ctx *KexContext) error {
	if err := k.verifyDst(ctx); err != nil {
		return err
	}
	if err := k.verifySession(ctx); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package rpc

import (
	"sync"
)

var (
	defaultClients *clients
	PingService    = "Logic.Ping"
)

type clients struct {
	lock    sync.RWMutex
	clients map[string]*Client
}

func (c *clients) get(addr string) *Client {
	var (
		cli *Client
		ok  bool
		op  ClientOptions
	)

	c.lock.Lock()
	defer c.lock.Unlock()
	if cli, ok = c.clients[addr]; ok {
		return cli
	}
	op.Network = "tcp4"
	op.Addr = addr
	cli = Dial(op)
	c.clients[addr] = cli
	go cli.Ping(PingService)

	return cli
}

func (c *clients) del(addr string) {
	c.lock.Lock()
	defer c.lock.Unlock()
	if cli, ok := c.clients[addr]; ok {
		cli.Close()
	}
	delete(c.clients, addr)
}

func Call(addr string, serviceMethod string, args interface{}, reply interface{}) error {
	if defaultClients == nil {
		defaultClients = &clients{
			clients: make(map[string]*Client),
		}
	}
	return defaultClients.get(addr).Call(serviceMethod, args, reply)
}

func Del(addr string) {
	if defaultClients != nil {
		defaultClients.del(addr)
	}
}
<commit_msg>update<commit_after>package rpc

import (
	"sync"
)

var (
	defaultClients *clients
	PingService    = "Logic.Ping"
)

type clients struct {
	lock    sync.RWMutex
	clients map[string]*Client
}

func (c *clients) get(addr string) *Client {
	var (
		cli *Client
		ok  bool
		op  ClientOptions
	)

	c.lock.Lock()
	defer c.lock.Unlock()
	if cli, ok = c.clients[addr]; ok {
		return cli
	}
	op.Network = "tcp4"
	op.Addr = addr
	cli = Dial(op)
	c.clients[addr] = cli
	go cli.Ping(PingService)

	return cli
}

func (c *clients) del(addr string) {
	c.lock.Lock()
	defer c.lock.Unlock()
	if cli, ok := c.clients[addr]; ok {
		cli.Close()
	}
	delete(c.clients, addr)
}

func Call(addr string, serviceMethod string, args interface{}, reply interface{}) error {
	return defaultClients.get(addr).Call(serviceMethod, args, reply)
}

func Del(addr string) {
	if defaultClients != nil {
		defaultClients.del(addr)
	}
}

func init() {
	defaultClients = &clients{
		clients: make(map[string]*Client),
	}
}
<|endoftext|>


<commit_before><commit_msg>Camel case じゃないと公開されない<commit_after>package main

import (
	"fmt"
	"math"
)

func main() {
	fmt.Println(math.Pi)
}
<|endoftext|>


<commit_before>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"go/build"
	"internal/testenv"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

var tmp, exe string // populated by buildObjdump

func TestMain(m *testing.M) {
	if !testenv.HasGoBuild() {
		return
	}
	var exitcode int
	if err := buildObjdump(); err == nil {
		exitcode = m.Run()
	} else {
		fmt.Println(err)
		exitcode = 1
	}
	os.RemoveAll(tmp)
	os.Exit(exitcode)
}

func buildObjdump() error {
	var err error
	tmp, err = ioutil.TempDir("", "TestObjDump")
	if err != nil {
		return fmt.Errorf("TempDir failed: %v", err)
	}

	exe = filepath.Join(tmp, "testobjdump.exe")
	gotool, err := testenv.GoTool()
	if err != nil {
		return err
	}
	out, err := exec.Command(gotool, "build", "-o", exe, "cmd/objdump").CombinedOutput()
	if err != nil {
		os.RemoveAll(tmp)
		return fmt.Errorf("go build -o %v cmd/objdump: %v\n%s", exe, err, string(out))
	}

	return nil
}

var x86Need = []string{
	"fmthello.go:6",
	"TEXT main.main(SB)",
	"JMP main.main(SB)",
	"CALL fmt.Println(SB)",
	"RET",
}

var armNeed = []string{
	"fmthello.go:6",
	"TEXT main.main(SB)",
	//"B.LS main.main(SB)", // TODO(rsc): restore; golang.org/issue/9021
	"BL fmt.Println(SB)",
	"RET",
}

var ppcNeed = []string{
	"fmthello.go:6",
	"TEXT main.main(SB)",
	"BR main.main(SB)",
	"CALL fmt.Println(SB)",
	"RET",
}

var target = flag.String("target", "", "test disassembly of `goos/goarch` binary")

// objdump is fully cross platform: it can handle binaries
// from any known operating system and architecture.
// We could in principle add binaries to testdata and check
// all the supported systems during this test. However, the
// binaries would be about 1 MB each, and we don't want to
// add that much junk to the hg repository. Instead, build a
// binary for the current system (only) and test that objdump
// can handle that one.

func testDisasm(t *testing.T, flags ...string) {
	goarch := runtime.GOARCH
	if *target != "" {
		f := strings.Split(*target, "/")
		if len(f) != 2 {
			t.Fatalf("-target argument must be goos/goarch")
		}
		defer os.Setenv("GOOS", os.Getenv("GOOS"))
		defer os.Setenv("GOARCH", os.Getenv("GOARCH"))
		os.Setenv("GOOS", f[0])
		os.Setenv("GOARCH", f[1])
		goarch = f[1]
	}

	hello := filepath.Join(tmp, "hello.exe")
	args := []string{"build", "-o", hello}
	args = append(args, flags...)
	args = append(args, "testdata/fmthello.go")
	out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()
	if err != nil {
		t.Fatalf("go build fmthello.go: %v\n%s", err, out)
	}
	need := []string{
		"fmthello.go:6",
		"TEXT main.main(SB)",
	}
	switch goarch {
	case "amd64", "386":
		need = append(need, x86Need...)
	case "arm":
		need = append(need, armNeed...)
	case "ppc64", "ppc64le":
		need = append(need, ppcNeed...)
	}

	out, err = exec.Command(exe, "-s", "main.main", hello).CombinedOutput()
	if err != nil {
		t.Fatalf("objdump fmthello.exe: %v\n%s", err, out)
	}

	text := string(out)
	ok := true
	for _, s := range need {
		if !strings.Contains(text, s) {
			t.Errorf("disassembly missing '%s'", s)
			ok = false
		}
	}
	if !ok {
		t.Logf("full disassembly:\n%s", text)
	}
}

func TestDisasm(t *testing.T) {
	switch runtime.GOARCH {
	case "arm64":
		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
	case "mips", "mipsle", "mips64", "mips64le":
		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
	case "s390x":
		t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
	}
	testDisasm(t)
}

func TestDisasmExtld(t *testing.T) {
	switch runtime.GOOS {
	case "plan9", "windows":
		t.Skipf("skipping on %s", runtime.GOOS)
	}
	switch runtime.GOARCH {
	case "ppc64":
		t.Skipf("skipping on %s, no support for external linking, issue 9038", runtime.GOARCH)
	case "arm64":
		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
	case "mips64", "mips64le":
		t.Skipf("skipping on %s, issue 12559 and 12560", runtime.GOARCH)
	case "s390x":
		t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
	}
	// TODO(jsing): Reenable once openbsd/arm has external linking support.
	if runtime.GOOS == "openbsd" && runtime.GOARCH == "arm" {
		t.Skip("skipping on openbsd/arm, no support for external linking, issue 10619")
	}
	if !build.Default.CgoEnabled {
		t.Skip("skipping because cgo is not enabled")
	}
	testDisasm(t, "-ldflags=-linkmode=external")
}
<commit_msg>cmd/objdump: disable objdump_test with external linking on GOARCH=mips{,le}<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"go/build"
	"internal/testenv"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

var tmp, exe string // populated by buildObjdump

func TestMain(m *testing.M) {
	if !testenv.HasGoBuild() {
		return
	}
	var exitcode int
	if err := buildObjdump(); err == nil {
		exitcode = m.Run()
	} else {
		fmt.Println(err)
		exitcode = 1
	}
	os.RemoveAll(tmp)
	os.Exit(exitcode)
}

func buildObjdump() error {
	var err error
	tmp, err = ioutil.TempDir("", "TestObjDump")
	if err != nil {
		return fmt.Errorf("TempDir failed: %v", err)
	}

	exe = filepath.Join(tmp, "testobjdump.exe")
	gotool, err := testenv.GoTool()
	if err != nil {
		return err
	}
	out, err := exec.Command(gotool, "build", "-o", exe, "cmd/objdump").CombinedOutput()
	if err != nil {
		os.RemoveAll(tmp)
		return fmt.Errorf("go build -o %v cmd/objdump: %v\n%s", exe, err, string(out))
	}

	return nil
}

var x86Need = []string{
	"fmthello.go:6",
	"TEXT main.main(SB)",
	"JMP main.main(SB)",
	"CALL fmt.Println(SB)",
	"RET",
}

var armNeed = []string{
	"fmthello.go:6",
	"TEXT main.main(SB)",
	//"B.LS main.main(SB)", // TODO(rsc): restore; golang.org/issue/9021
	"BL fmt.Println(SB)",
	"RET",
}

var ppcNeed = []string{
	"fmthello.go:6",
	"TEXT main.main(SB)",
	"BR main.main(SB)",
	"CALL fmt.Println(SB)",
	"RET",
}

var target = flag.String("target", "", "test disassembly of `goos/goarch` binary")

// objdump is fully cross platform: it can handle binaries
// from any known operating system and architecture.
// We could in principle add binaries to testdata and check
// all the supported systems during this test. However, the
// binaries would be about 1 MB each, and we don't want to
// add that much junk to the hg repository. Instead, build a
// binary for the current system (only) and test that objdump
// can handle that one.

func testDisasm(t *testing.T, flags ...string) {
	goarch := runtime.GOARCH
	if *target != "" {
		f := strings.Split(*target, "/")
		if len(f) != 2 {
			t.Fatalf("-target argument must be goos/goarch")
		}
		defer os.Setenv("GOOS", os.Getenv("GOOS"))
		defer os.Setenv("GOARCH", os.Getenv("GOARCH"))
		os.Setenv("GOOS", f[0])
		os.Setenv("GOARCH", f[1])
		goarch = f[1]
	}

	hello := filepath.Join(tmp, "hello.exe")
	args := []string{"build", "-o", hello}
	args = append(args, flags...)
	args = append(args, "testdata/fmthello.go")
	out, err := exec.Command(testenv.GoToolPath(t), args...).CombinedOutput()
	if err != nil {
		t.Fatalf("go build fmthello.go: %v\n%s", err, out)
	}
	need := []string{
		"fmthello.go:6",
		"TEXT main.main(SB)",
	}
	switch goarch {
	case "amd64", "386":
		need = append(need, x86Need...)
	case "arm":
		need = append(need, armNeed...)
	case "ppc64", "ppc64le":
		need = append(need, ppcNeed...)
	}

	out, err = exec.Command(exe, "-s", "main.main", hello).CombinedOutput()
	if err != nil {
		t.Fatalf("objdump fmthello.exe: %v\n%s", err, out)
	}

	text := string(out)
	ok := true
	for _, s := range need {
		if !strings.Contains(text, s) {
			t.Errorf("disassembly missing '%s'", s)
			ok = false
		}
	}
	if !ok {
		t.Logf("full disassembly:\n%s", text)
	}
}

func TestDisasm(t *testing.T) {
	switch runtime.GOARCH {
	case "arm64":
		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
	case "mips", "mipsle", "mips64", "mips64le":
		t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
	case "s390x":
		t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
	}
	testDisasm(t)
}

func TestDisasmExtld(t *testing.T) {
	switch runtime.GOOS {
	case "plan9", "windows":
		t.Skipf("skipping on %s", runtime.GOOS)
	}
	switch runtime.GOARCH {
	case "ppc64":
		t.Skipf("skipping on %s, no support for external linking, issue 9038", runtime.GOARCH)
	case "arm64":
		t.Skipf("skipping on %s, issue 10106", runtime.GOARCH)
	case "mips64", "mips64le", "mips", "mipsle":
		t.Skipf("skipping on %s, issue 12559 and 12560", runtime.GOARCH)
	case "s390x":
		t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
	}
	// TODO(jsing): Reenable once openbsd/arm has external linking support.
	if runtime.GOOS == "openbsd" && runtime.GOARCH == "arm" {
		t.Skip("skipping on openbsd/arm, no support for external linking, issue 10619")
	}
	if !build.Default.CgoEnabled {
		t.Skip("skipping because cgo is not enabled")
	}
	testDisasm(t, "-ldflags=-linkmode=external")
}
<|endoftext|>


<commit_before>package cmd

const Version = "3.41.11"
<commit_msg>version bump<commit_after>package cmd

const Version = "3.42.0"
<|endoftext|>


<commit_before>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"github.com/eaciit/dbox"
	"github.com/eaciit/toolkit"
	"os"
	"sync"
)

func setinitialconnection() {
	conn, err := modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}

func main() {
	var mwg sync.WaitGroup
	setinitialconnection()
	defer gdrj.CloseDb()
	tkmmap := toolkit.M{}

	toolkit.Println("START...")

	crx, err := gdrj.Find(new(gdrj.MappingInventory), nil, nil)
	if err != nil {
		toolkit.Println("Error Found : ", err.Error())
		os.Exit(1)
	}

	arrmap := []*gdrj.MappingInventory{}
	_ = crx.Fetch(&arrmap, 0, false)
	for _, v := range arrmap {
		tkmmap.Set(v.SKUID_VDIST, v.ID)
	}
	crx.Close()

	cr, err := gdrj.Find(new(gdrj.SalesDetail), dbox.Eq("skuid_sapbi", ""), nil)
	if err != nil {
		toolkit.Println("Error Found : ", err.Error())
		os.Exit(1)
	}
	defer cr.Close()
	iseof := false

	for !iseof {
		arrsalesdetail := []*gdrj.SalesDetail{}
		err = cr.Fetch(&arrsalesdetail, 1000, false)

		if len(arrsalesdetail) < 1000 {
			iseof = true
		}
		mwg.Add(1)
		go func(xsd []*gdrj.SalesDetail) {
			for _, v := range xsd {
				tv := toolkit.ToString(tkmmap.Get(v.SKUID_VDIST, ""))
				toolkit.Printf(".")
				v.SKUID_SAPBI = tv
				_ = gdrj.Save(v)
			}
			mwg.Done()
		}(arrsalesdetail)

	}
	mwg.Wait()
	toolkit.Println("END...")
}
<commit_msg>changes<commit_after>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"github.com/eaciit/dbox"
	"github.com/eaciit/toolkit"
	"os"
	"sync"
)

func setinitialconnection() {
	conn, err := modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}

func main() {
	var mwg sync.WaitGroup
	setinitialconnection()
	defer gdrj.CloseDb()
	tkmmap := toolkit.M{}

	toolkit.Println("START...")

	crx, err := gdrj.Find(new(gdrj.MappingInventory), nil, nil)
	if err != nil {
		toolkit.Println("Error Found : ", err.Error())
		os.Exit(1)
	}

	arrmap := []*gdrj.MappingInventory{}
	_ = crx.Fetch(&arrmap, 0, false)
	for _, v := range arrmap {
		tkmmap.Set(v.SKUID_VDIST, v.ID)
	}
	crx.Close()

	cr, err := gdrj.Find(new(gdrj.SalesDetail), dbox.Eq("skuid_sapbi", ""), nil)
	if err != nil {
		toolkit.Println("Error Found : ", err.Error())
		os.Exit(1)
	}
	defer cr.Close()
	iseof := false

	c := cr.Count()
	i := 0
	for !iseof {
		arrsalesdetail := []*gdrj.SalesDetail{}
		err = cr.Fetch(&arrsalesdetail, 1000, false)

		if len(arrsalesdetail) < 1000 {
			iseof = true
		}
		mwg.Add(1)
		func(xsd []*gdrj.SalesDetail) {
			defer mwg.Done()
			for _, v := range xsd {
				i++
				toolkit.Printfn("%d of %d == %v : SAP : %v", i, c, v.ID, v.SKUID_SAPBI)
				tv := toolkit.ToString(tkmmap.Get(v.SKUID_VDIST, ""))
				toolkit.Printfn(tv)
				v.SKUID_SAPBI = tv
				_ = gdrj.Save(v)
			}
		}(arrsalesdetail)

	}
	mwg.Wait()
	toolkit.Println("END...")
}
<|endoftext|>


<commit_before>package static

import (
	"bytes"
	"compress/gzip"
	"encoding/base64"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"time"
)

// DirFile contains the static directory and file content info
type DirFile struct {
	Path       string
	Name       string
	Size       int64
	Mode       os.FileMode
	ModTime    int64
	IsDir      bool
	Compressed string
	Files      []*DirFile
}

// Files contains a full instance of a static file collection
type Files struct {
	dir Dir
}

// File contains the static FileInfo
type file struct {
	data         []byte
	path         string
	name         string
	size         int64
	mode         os.FileMode
	modTime      int64
	isDir        bool
	files        []*file
	lastDirIndex int
}

// Dir implements the FileSystem interface
type Dir struct {
	useStaticFiles bool
	files          map[string]*file
}

type httpFile struct {
	*bytes.Reader
	*file
}

// Config contains information about how extracting the data should behave
type Config struct {
	useStaticFiles bool
}

// Open returns the FileSystem DIR
func (dir Dir) Open(name string) (http.File, error) {

	if dir.useStaticFiles {
		f, found := dir.files[path.Clean(name)]
		if !found {
			return nil, os.ErrNotExist
		}

		return f.File()
	}

	return os.Open(name)
}

// File returns an http.File or error
func (f file) File() (http.File, error) {

	// if production read filesystem file
	return &httpFile{
		bytes.NewReader(f.data),
		&f,
	}, nil
}

// Close closes the File, rendering it unusable for I/O. It returns an error, if any.
func (f file) Close() error {
	return nil
}

// Readdir returns nil fileinfo and an error because the static FileSystem does not store directories
func (f file) Readdir(count int) ([]os.FileInfo, error) {

	if !f.IsDir() {
		return nil, errors.New("not a directory")
	}

	var files []os.FileInfo

	if count <= 0 {
		files = make([]os.FileInfo, len(f.files))
		count = len(f.files)
		f.lastDirIndex = 0
	} else {
		files = make([]os.FileInfo, count)
	}

	if f.lastDirIndex >= len(f.files) {
		return nil, io.EOF
	}

	if count+f.lastDirIndex >= len(f.files) {
		count = len(f.files)
	}

	for i := f.lastDirIndex; i < count; i++ {
		files = append(files, *f.files[i])
	}

	return files, nil
}

// Stat returns the FileInfo structure describing file. If there is an error, it will be of type *PathError.
func (f file) Stat() (os.FileInfo, error) {
	return f, nil
}

// Name returns the name of the file as presented to Open.
func (f file) Name() string {
	return f.name
}

// Size length in bytes for regular files; system-dependent for others
func (f file) Size() int64 {
	return f.size
}

// Mode returns file mode bits
func (f file) Mode() os.FileMode {
	mode := os.FileMode(0644)
	if f.IsDir() {
		return mode | os.ModeDir
	}
	return mode
}

// ModTime returns the files modification time
func (f file) ModTime() time.Time {
	return time.Unix(f.modTime, 0)
}

// IsDir reports whether f describes a directory.
func (f file) IsDir() bool {
	return f.isDir
}

// Sys returns the underlying data source (can return nil)
func (f file) Sys() interface{} {
	return f
}

// New create a new static file instance.
func New(config *Config, dirFile *DirFile) (*Files, error) {
	files := map[string]*file{}

	if config.useStaticFiles {
		processFiles(files, dirFile)
	}

	return &Files{
		dir: Dir{
			useStaticFiles: config.useStaticFiles,
			files:          files,
		},
	}, nil
}

func processFiles(files map[string]*file, dirFile *DirFile) *file {

	f := &file{
		path:    dirFile.Path,
		name:    dirFile.Name,
		size:    dirFile.Size,
		mode:    dirFile.Mode,
		modTime: dirFile.ModTime,
		isDir:   dirFile.IsDir,
		files:   []*file{},
	}

	files[f.path] = f

	if dirFile.IsDir {
		for _, nestedFile := range dirFile.Files {
			resultFile := processFiles(files, nestedFile)
			f.files = append(f.files, resultFile)
		}

		return f
	}

	// decompress file contents
	b64 := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(dirFile.Compressed))
	reader, err := gzip.NewReader(b64)
	if err != nil {
		log.Fatal(err)
	}

	f.data, err = ioutil.ReadAll(reader)
	if err != nil {
		log.Fatal(err)
	}

	return f
}

// FS returns an http.FileSystem object for serving files over http
func (f *Files) FS() http.FileSystem {
	return f.dir
}

// GetHTTPFile returns an http.File object
func (f *Files) GetHTTPFile(name string) (http.File, error) {
	return f.dir.Open(name)
}

// ReadFile returns a files contents as []byte from the filesystem, static or local
func (f *Files) ReadFile(path string) ([]byte, error) {

	file, err := f.dir.Open(path)
	if err != nil {
		return nil, err
	}

	return ioutil.ReadAll(file)
}
<commit_msg>Update code in preparation for read all dir files logic.<commit_after>package static

import (
	"bytes"
	"compress/gzip"
	"encoding/base64"
	"errors"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"time"
)

// DirFile contains the static directory and file content info
type DirFile struct {
	Path       string
	Name       string
	Size       int64
	Mode       os.FileMode
	ModTime    int64
	IsDir      bool
	Compressed string
	Files      []*DirFile
}

// Files contains a full instance of a static file collection
type Files struct {
	absPkgPath string
	dir        Dir
}

// File contains the static FileInfo
type file struct {
	data         []byte
	path         string
	name         string
	size         int64
	mode         os.FileMode
	modTime      int64
	isDir        bool
	files        []*file
	lastDirIndex int
}

// Dir implements the FileSystem interface
type Dir struct {
	useStaticFiles bool
	files          map[string]*file
}

type httpFile struct {
	*bytes.Reader
	*file
}

// Config contains information about how extracting the data should behave
type Config struct {
	UseStaticFiles bool
	AbsPkgPath     string // the Absolute package path used for local file reading when UseStaticFiles is false
}

// Open returns the FileSystem DIR
func (dir Dir) Open(name string) (http.File, error) {

	if dir.useStaticFiles {
		f, found := dir.files[path.Clean(name)]
		if !found {
			return nil, os.ErrNotExist
		}

		return f.File()
	}

	return os.Open(name)
}

// File returns an http.File or error
func (f file) File() (http.File, error) {

	// if production read filesystem file
	return &httpFile{
		bytes.NewReader(f.data),
		&f,
	}, nil
}

// Close closes the File, rendering it unusable for I/O. It returns an error, if any.
func (f file) Close() error {
	return nil
}

// Readdir returns nil fileinfo and an error because the static FileSystem does not store directories
func (f file) Readdir(count int) ([]os.FileInfo, error) {

	if !f.IsDir() {
		return nil, errors.New("not a directory")
	}

	var files []os.FileInfo

	if count <= 0 {
		files = make([]os.FileInfo, len(f.files))
		count = len(f.files)
		f.lastDirIndex = 0
	} else {
		files = make([]os.FileInfo, count)
	}

	if f.lastDirIndex >= len(f.files) {
		return nil, io.EOF
	}

	if count+f.lastDirIndex >= len(f.files) {
		count = len(f.files)
	}

	for i := f.lastDirIndex; i < count; i++ {
		files = append(files, *f.files[i])
	}

	return files, nil
}

// Stat returns the FileInfo structure describing file. If there is an error, it will be of type *PathError.
func (f file) Stat() (os.FileInfo, error) {
	return f, nil
}

// Name returns the name of the file as presented to Open.
func (f file) Name() string {
	return f.name
}

// Size length in bytes for regular files; system-dependent for others
func (f file) Size() int64 {
	return f.size
}

// Mode returns file mode bits
func (f file) Mode() os.FileMode {
	mode := os.FileMode(0644)
	if f.IsDir() {
		return mode | os.ModeDir
	}
	return mode
}

// ModTime returns the files modification time
func (f file) ModTime() time.Time {
	return time.Unix(f.modTime, 0)
}

// IsDir reports whether f describes a directory.
func (f file) IsDir() bool {
	return f.isDir
}

// Sys returns the underlying data source (can return nil)
func (f file) Sys() interface{} {
	return f
}

// New create a new static file instance.
func New(config *Config, dirFile *DirFile) (*Files, error) {

	files := map[string]*file{}

	if config.UseStaticFiles {
		processFiles(files, dirFile)
	} else {
		if len(config.AbsPkgPath) == 0 {
			return nil, errors.New("AbsPkgPath is required when not using static files otherwise the static package has no idea where to grab local files from when your package is used from within another package.")
		}
	}

	return &Files{
		absPkgPath: config.AbsPkgPath,
		dir: Dir{
			useStaticFiles: config.UseStaticFiles,
			files:          files,
		},
	}, nil
}

func processFiles(files map[string]*file, dirFile *DirFile) *file {

	f := &file{
		path:    dirFile.Path,
		name:    dirFile.Name,
		size:    dirFile.Size,
		mode:    dirFile.Mode,
		modTime: dirFile.ModTime,
		isDir:   dirFile.IsDir,
		files:   []*file{},
	}

	files[f.path] = f

	if dirFile.IsDir {
		for _, nestedFile := range dirFile.Files {
			resultFile := processFiles(files, nestedFile)
			f.files = append(f.files, resultFile)
		}

		return f
	}

	// decompress file contents
	b64 := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(dirFile.Compressed))
	reader, err := gzip.NewReader(b64)
	if err != nil {
		log.Fatal(err)
	}

	f.data, err = ioutil.ReadAll(reader)
	if err != nil {
		log.Fatal(err)
	}

	return f
}

// FS returns an http.FileSystem object for serving files over http
func (f *Files) FS() http.FileSystem {
	return f.dir
}

// GetHTTPFile returns an http.File object
func (f *Files) GetHTTPFile(name string) (http.File, error) {
	return f.dir.Open(name)
}

// ReadFile returns a files contents as []byte from the filesystem, static or local
func (f *Files) ReadFile(path string) ([]byte, error) {

	file, err := f.dir.Open(path)
	if err != nil {
		return nil, err
	}

	return ioutil.ReadAll(file)
}

// ADD a READ All Dir Files instead of All File

// // ReadFile returns a files contents as []byte from the filesystem, static or local
// func (f *Files) ReadAllFile() ([]byte, error) {

// 	file, err := f.dir.Open(path)
// 	if err != nil {
// 		return nil, err
// 	}

// 	return ioutil.ReadAll(file)
// }
<|endoftext|>


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

package msgpack

import (
	"bytes"
	"io"

	"github.com/m3db/m3metrics/metric"
	"github.com/m3db/m3metrics/policy"
	"github.com/m3db/m3metrics/pool"
	xpool "github.com/m3db/m3x/pool"

	"gopkg.in/vmihailenco/msgpack.v2"
)

const (
	supportedVersion int = 1
)

// BufferedEncoder is an messagePack-based encoder backed by byte buffers
type BufferedEncoder struct {
	*msgpack.Encoder

	Buffer *bytes.Buffer
	pool   BufferedEncoderPool
}

// BufferedEncoderAlloc allocates a bufferer encoder
type BufferedEncoderAlloc func() BufferedEncoder

// BufferedEncoderPool is a pool of buffered encoders
type BufferedEncoderPool interface {
	// Init initializes the buffered encoder pool
	Init(alloc BufferedEncoderAlloc)

	// Get returns a buffered encoder from the pool
	Get() BufferedEncoder

	// Put puts a buffered encoder into the pool
	Put(enc BufferedEncoder)
}

// RawEncoder is a msgpack-based encoder for encoding raw metrics
type RawEncoder interface {
	// EncodeCounter encodes a counter with applicable policies
	EncodeCounter(c metric.Counter, p policy.VersionedPolicies) error

	// EncodeBatchTimer encodes a batched timer with applicable policies
	EncodeBatchTimer(bt metric.BatchTimer, p policy.VersionedPolicies) error

	// EncodeGauge encodes a gauge with applicable policies
	EncodeGauge(g metric.Gauge, p policy.VersionedPolicies) error

	// Buffer returns the encoder buffer
	Encoder() BufferedEncoder

	// Reset resets the encoder
	Reset(buffer BufferedEncoder)
}

// RawIterator iterates over data stream and decodes raw metrics
type RawIterator interface {
	// Next returns true if there are more items to decode
	Next() bool

	// Value returns the current metric and applicable policies
	Value() (*metric.OneOf, policy.VersionedPolicies)

	// Err returns the error encountered during decoding if any
	Err() error

	// Reset resets the iterator
	Reset(reader io.Reader)
}

// RawIteratorOptions provide options for raw iterators
type RawIteratorOptions interface {
	// SetFloatsPool sets the floats pool
	SetFloatsPool(value xpool.FloatsPool) RawIteratorOptions

	// FloatsPool returns the floats pool
	FloatsPool() xpool.FloatsPool

	// SetPoliciesPool sets the policies pool
	SetPoliciesPool(value pool.PoliciesPool) RawIteratorOptions

	// PoliciesPool returns the policies pool
	PoliciesPool() pool.PoliciesPool

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

package msgpack

import (
	"bytes"
	"io"

	"github.com/m3db/m3metrics/metric"
	"github.com/m3db/m3metrics/policy"
	"github.com/m3db/m3metrics/pool"
	xpool "github.com/m3db/m3x/pool"

	"gopkg.in/vmihailenco/msgpack.v2"
)

const (
	supportedVersion int = 1
)

// BufferedEncoder is an messagePack-based encoder backed by byte buffers
type BufferedEncoder struct {
	*msgpack.Encoder

	Buffer *bytes.Buffer
	pool   BufferedEncoderPool
}

// BufferedEncoderAlloc allocates a bufferer encoder
type BufferedEncoderAlloc func() BufferedEncoder

// BufferedEncoderPool is a pool of buffered encoders
type BufferedEncoderPool interface {
	// Init initializes the buffered encoder pool
	Init(alloc BufferedEncoderAlloc)

	// Get returns a buffered encoder from the pool
	Get() BufferedEncoder

	// Put puts a buffered encoder into the pool
	Put(enc BufferedEncoder)
}

// RawEncoder is a msgpack-based encoder for encoding raw metrics
type RawEncoder interface {
	// EncodeCounter encodes a counter with applicable policies
	EncodeCounter(c metric.Counter, p policy.VersionedPolicies) error

	// EncodeBatchTimer encodes a batched timer with applicable policies
	EncodeBatchTimer(bt metric.BatchTimer, p policy.VersionedPolicies) error

	// EncodeGauge encodes a gauge with applicable policies
	EncodeGauge(g metric.Gauge, p policy.VersionedPolicies) error

	// Encoder returns the encoder
	Encoder() BufferedEncoder

	// Reset resets the encoder
	Reset(buffer BufferedEncoder)
}

// RawIterator iterates over data stream and decodes raw metrics
type RawIterator interface {
	// Next returns true if there are more items to decode
	Next() bool

	// Value returns the current metric and applicable policies
	Value() (*metric.OneOf, policy.VersionedPolicies)

	// Err returns the error encountered during decoding if any
	Err() error

	// Reset resets the iterator
	Reset(reader io.Reader)
}

// RawIteratorOptions provide options for raw iterators
type RawIteratorOptions interface {
	// SetFloatsPool sets the floats pool
	SetFloatsPool(value xpool.FloatsPool) RawIteratorOptions

	// FloatsPool returns the floats pool
	FloatsPool() xpool.FloatsPool

	// SetPoliciesPool sets the policies pool
	SetPoliciesPool(value pool.PoliciesPool) RawIteratorOptions

	// PoliciesPool returns the policies pool
	PoliciesPool() pool.PoliciesPool

	// Validate validates the options
	Validate() error
}
<|endoftext|>