<commit_before>package utils

import (
	"database/sql"
	"errors"
	"fmt"

	e "github.com/techjanitor/pram-post/errors"
)

var (
	ErrUserNotConfirmed error = errors.New("Account not confirmed")
	ErrUserBanned       error = errors.New("Account banned")
	ErrUserLocked       error = errors.New("Account locked")
	ErrUserNotExist     error = errors.New("User does not exist")
	userdataWorker      *userWorker
)

// struct for database insert worker
type userWorker struct {
	send    chan *User
	receive chan *User
}

// user struct
type User struct {
	Id              uint   `json:"id"`
	Name            string `json:"name"`
	Email           string `json:"email"`
	Group           uint   `json:"group"`
	IsConfirmed     bool   `json:"-"`
	IsLocked        bool   `json:"-"`
	IsBanned        bool   `json:"-"`
	IsAuthenticated bool   `json:"-"`
	err             error  `json:"-"`
}

func UserInit() {

	fmt.Println("Initializing User Info Worker...")

	// make worker channel
	userdataWorker = &userWorker{
		send:    make(chan *User, 64),
		receive: make(chan *User, 64),
	}

	go func() {

		// Get Database handle
		db, err := GetDb()
		if err != nil {
			fmt.Println(err)
			return
		}

		// prepare query for users table
		ps1, err := db.Prepare("SELECT usergroup_id,user_name,user_email,user_confirmed,user_locked,user_banned FROM users WHERE user_id = ?")
		if err != nil {
			fmt.Println(err)
			return
		}

		// range through tasks channel
		for u := range userdataWorker.send {

			// input data
			err = ps1.QueryRow(u.Id).Scan(&u.Group, &u.Name, &u.Email, &u.IsConfirmed, &u.IsLocked, &u.IsBanned)
			if err != nil {
				u.err = err
			}

			// send back data
			userdataWorker.receive <- u

		}

	}()

}

// get the user info from id
func (u *User) Info() (err error) {

	// this needs an id
	if u.Id == 0 || u.Id == 1 {
		return e.ErrInvalidParam
	}

	// get original uid
	uid := u.Id

	// send to worker
	userdataWorker.send <- u

	// block until done
	<-userdataWorker.receive

	// check error
	if u.err == sql.ErrNoRows {
		return ErrUserNotExist
	} else if u.err != nil {
		return e.ErrInternalError
	}

	// check that theyre still the same just in case
	if u.Id != uid {
		return e.ErrInternalError
	}

	// if account is not confirmed
	if !u.IsConfirmed {
		return ErrUserNotConfirmed
	}

	// if locked
	if u.IsLocked {
		return ErrUserLocked
	}

	// if banned
	if u.IsBanned {
		return ErrUserBanned
	}

	// mark authenticated
	u.IsAuthenticated = true

	return

}
<commit_msg>make channels blocking<commit_after>package utils

import (
	"database/sql"
	"errors"
	"fmt"

	e "github.com/techjanitor/pram-get/errors"
)

var (
	ErrUserNotConfirmed error = errors.New("Account not confirmed")
	ErrUserBanned       error = errors.New("Account banned")
	ErrUserLocked       error = errors.New("Account locked")
	ErrUserNotExist     error = errors.New("User does not exist")
	userdataWorker      *userWorker
)

// struct for database insert worker
type userWorker struct {
	send chan *User
	done chan bool
}

// user struct
type User struct {
	Id              uint   `json:"id"`
	Name            string `json:"name"`
	Email           string `json:"email"`
	Group           uint   `json:"group"`
	IsConfirmed     bool   `json:"-"`
	IsLocked        bool   `json:"-"`
	IsBanned        bool   `json:"-"`
	IsAuthenticated bool   `json:"-"`
	err             error  `json:"-"`
}

func UserInit() {

	fmt.Println("Initializing User Info Worker...")

	// make worker channel
	userdataWorker = &userWorker{
		send: make(chan *User),
		done: make(chan bool),
	}

	go func() {

		// Get Database handle
		db, err := GetDb()
		if err != nil {
			fmt.Println(err)
			return
		}

		// prepare query for users table
		ps1, err := db.Prepare("SELECT usergroup_id,user_name,user_email,user_confirmed,user_locked,user_banned FROM users WHERE user_id = ?")
		if err != nil {
			fmt.Println(err)
			return
		}

		// range through tasks channel
		for u := range userdataWorker.send {

			// input data
			err = ps1.QueryRow(u.Id).Scan(&u.Group, &u.Name, &u.Email, &u.IsConfirmed, &u.IsLocked, &u.IsBanned)
			if err != nil {
				u.err = err
			}

			userdataWorker.done <- true

		}

	}()

}

// get the user info from id
func (u *User) Info() (err error) {

	// this needs an id
	if u.Id == 0 || u.Id == 1 {
		return e.ErrInvalidParam
	}

	// get original uid
	uid := u.Id

	// send to worker
	userdataWorker.send <- u

	// block until done
	<-userdataWorker.done

	// check error
	if u.err == sql.ErrNoRows {
		return ErrUserNotExist
	} else if u.err != nil {
		return e.ErrInternalError
	}

	// check that theyre still the same just in case
	if u.Id != uid {
		return e.ErrInternalError
	}

	// if account is not confirmed
	if !u.IsConfirmed {
		return ErrUserNotConfirmed
	}

	// if locked
	if u.IsLocked {
		return ErrUserLocked
	}

	// if banned
	if u.IsBanned {
		return ErrUserBanned
	}

	// mark authenticated
	u.IsAuthenticated = true

	return

}
<|endoftext|>


<commit_before>/*******************************************************************************
The MIT License (MIT)

Copyright (c) 2013-2014 Hajime Nakagami

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 firebirdsql

import (
	"errors"
	"testing"
)

func TestDSNParse(t *testing.T) {
	var testDSNs = []struct {
		dsn    string
		addr   string
		dbName string
		user   string
		passwd string
	}{
		{"user:password@localhost:3000/dbname", "localhost:3000", "dbname", "user", "password"},
		{"user:password@localhost/dbname", "localhost:3050", "dbname", "user", "password"},
		{"user:password@localhost/dir/dbname", "localhost:3050", "/dir/dbname", "user", "password"},
	}

	for _, d := range testDSNs {
		addr, dbName, user, passwd, err := parseDSN(d.dsn)
		if addr != d.addr || dbName != d.dbName || user != d.user || passwd != d.passwd {
			err = errors.New("parse DSN fail")
		}
		if err != nil {
			t.Error(err.Error())
		}
	}
}
<commit_msg>add windows DSN example test<commit_after>/*******************************************************************************
The MIT License (MIT)

Copyright (c) 2013-2014 Hajime Nakagami

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 firebirdsql

import (
	"errors"
	"testing"
)

func TestDSNParse(t *testing.T) {
	var testDSNs = []struct {
		dsn    string
		addr   string
		dbName string
		user   string
		passwd string
	}{
		{"user:password@localhost:3000/dbname", "localhost:3000", "dbname", "user", "password"},
		{"user:password@localhost/dbname", "localhost:3050", "dbname", "user", "password"},
		{"user:password@localhost/dir/dbname", "localhost:3050", "/dir/dbname", "user", "password"},
		{"user:password@localhost/c:\\fbdata\\database.fdb", "localhost:3050", "c:\\fbdata\\database.fdb", "user", "password"},
	}

	for _, d := range testDSNs {
		addr, dbName, user, passwd, err := parseDSN(d.dsn)
		if addr != d.addr || dbName != d.dbName || user != d.user || passwd != d.passwd {
			err = errors.New("parse DSN fail")
		}
		if err != nil {
			t.Error(err.Error())
		}
	}
}
<|endoftext|>


<commit_before>package market

import (
	"fmt"
	"log"
	"time"
)

const (
	//	雅虎财经的历史分时数据没有超过90天的
	lastestDays          = 90
	companyGCCount       = 64
	retryTimes           = 50
	retryIntervalSeconds = 10
)

//	市场更新
type Market interface {
	//	名称
	Name() string
	//	时区
	Timezone() string
	//	获取上市公司列表
	Companies() ([]Company, error)

	//	抓取任务(每日)
	Crawl(market Market, company Company, day time.Time) error
}

var markets = []Market{}

//	添加市场
func Add(market Market) {
	markets = append(markets, market)

	log.Printf("市场[%s]已经加入监视列表", market.Name())
}

//	监视市场(所有操作的入口)
func Monitor() {
	log.Print("启动监视")

	for _, m := range markets {

		//	启动每日定时任务
		go func(market Market) {
			//	所处时区距明日0点的间隔
			now := locationNow(market)
			du := locationYesterdayZero(market).Add(time.Hour * 48).Sub(now)

			log.Printf("[%s]\t定时任务已启动，将于%s后激活首次任务", market.Name(), du.String())
			time.AfterFunc(du, func() {
				//	立即运行一次
				go dailyTask(market)

				//	每天运行一次
				ticker := time.NewTicker(time.Hour * 24)
				for _ = range ticker.C {
					dailyTask(market)
				}
			})

		}(m)

//		//	启动历史数据获取任务
//		go func(market Market) {
//			historyTask(market, locationYesterdayZero(market))
//		}(m)
	}
}

//	所处时区当前时间
func locationNow(market Market) time.Time {
	now := time.Now()

	//	获取市场所在时区的今天0点
	location, err := time.LoadLocation(market.Timezone())
	if err != nil {
		return now
	}

	return now.In(location)
}

//	昨天0点
func locationYesterdayZero(market Market) time.Time {
	now := locationNow(market)
	year, month, day := now.Add(-time.Hour * 24).Date()

	return time.Date(year, month, day, 0, 0, 0, 0, now.Location())
}

//	每日定时任务
func dailyTask(market Market) {

	//	昨天零点
	yesterday := locationYesterdayZero(market)
	log.Printf("[%s]\t%s数据获取任务已启动", market.Name(), yesterday.Format("20060102"))

	//	获取市场所有上市公司
	companies, err := getCompanies(market)
	if err != nil {
		log.Print(err)
	}

	chanSend := make(chan int, companyGCCount)
	chanReceive := make(chan int)

	for _, c := range companies {
		//	并发抓取
		go func(company Company) {

			err := market.Crawl(market, company, yesterday)
			if err != nil {
				log.Print(err)
			}

			<-chanSend
			chanReceive <- 1
		}(c)

		chanSend <- 1
	}

	//	阻塞，直到抓取所有
	for _, _ = range companies {
		<-chanReceive
	}

	close(chanSend)
	close(chanReceive)

	log.Printf("[%s]\t%s数据获取任务已结束", market.Name(), yesterday.Format("20060102"))
}

//	历史数据获取任务
func historyTask(market Market, yesterday time.Time) {
	//	获取市场所有上市公司
	companies, err := getCompanies(market)
	if err != nil {
		log.Print(err)
		return
	}

	log.Printf("[%s]\t开始抓取%d家上市公司在%s之前的历史", market.Name(), len(companies), yesterday.Format("20060102"))

	chanSend := make(chan int, companyGCCount)
	chanReceive := make(chan int)

	for _, c := range companies {
		//	并发抓取
		go func(company Company) {

			for index := 0; index < lastestDays; index++ {
				day := yesterday.Add(-time.Hour * 24 * time.Duration(index))
				err := market.Crawl(market, company, day)
				if err != nil {
					log.Printf("[%s]\t抓取[%s]在%s的分时数据出错:%s", market.Name(), company.Code, day.Format("20060102"), err)
				}
			}

			<-chanSend
			chanReceive <- 1
		}(c)

		chanSend <- 1
	}

	//	阻塞，直到抓取所有
	for _, _ = range companies {
		<-chanReceive
	}

	close(chanSend)
	close(chanReceive)

	log.Printf("[%s]\t上市公司的历史分时数据已经抓取结束", market.Name())
}

//	抓取市场上市公司信息
func getCompanies(market Market) ([]Company, error) {

	cl := CompanyList{}
	//	尝试更新上市公司列表
	log.Printf("[%s]\t更新上市公司列表-开始", market.Name())
	companies, err := market.Companies()
	if err != nil {

		//	如果更新失败，则尝试从上次的存档文件中读取上市公司列表
		log.Printf("[%s]\t更新上市公司列表失败，尝试从存档读取:%v", market.Name(), err)
		err = cl.Load(market)
		if err != nil {
			return nil, fmt.Errorf("[%s]\t尝试从存档读取上市公司列表-失败:%v", market.Name(), err)
		}

		companies = cl
		log.Printf("[%s]\t尝试从存档读取上市公司列表-成功,共%d家上市公司", market.Name(), len(companies))

		return companies, nil
	}

	//	存档
	cl = CompanyList(companies)
	err = cl.Save(market)
	if err != nil {
		return nil, err
	}

	log.Printf("[%s]\t更新上市公司列表-成功,共%d家上市公司", market.Name(), len(companies))

	return companies, nil
}
<commit_msg>启用历史数据抓取任务<commit_after>package market

import (
	"fmt"
	"log"
	"time"
)

const (
	//	雅虎财经的历史分时数据没有超过90天的
	lastestDays          = 90
	companyGCCount       = 64
	retryTimes           = 50
	retryIntervalSeconds = 10
)

//	市场更新
type Market interface {
	//	名称
	Name() string
	//	时区
	Timezone() string
	//	获取上市公司列表
	Companies() ([]Company, error)

	//	抓取任务(每日)
	Crawl(market Market, company Company, day time.Time) error
}

var markets = []Market{}

//	添加市场
func Add(market Market) {
	markets = append(markets, market)

	log.Printf("市场[%s]已经加入监视列表", market.Name())
}

//	监视市场(所有操作的入口)
func Monitor() {
	log.Print("启动监视")

	for _, m := range markets {

		//	启动每日定时任务
		go func(market Market) {
			//	所处时区距明日0点的间隔
			now := locationNow(market)
			du := locationYesterdayZero(market).Add(time.Hour * 48).Sub(now)

			log.Printf("[%s]\t定时任务已启动，将于%s后激活首次任务", market.Name(), du.String())
			time.AfterFunc(du, func() {
				//	立即运行一次
				go dailyTask(market)

				//	每天运行一次
				ticker := time.NewTicker(time.Hour * 24)
				for _ = range ticker.C {
					dailyTask(market)
				}
			})

		}(m)

		//	启动历史数据获取任务
		go func(market Market) {
			historyTask(market, locationYesterdayZero(market))
		}(m)
	}
}

//	所处时区当前时间
func locationNow(market Market) time.Time {
	now := time.Now()

	//	获取市场所在时区的今天0点
	location, err := time.LoadLocation(market.Timezone())
	if err != nil {
		return now
	}

	return now.In(location)
}

//	昨天0点
func locationYesterdayZero(market Market) time.Time {
	now := locationNow(market)
	year, month, day := now.Add(-time.Hour * 24).Date()

	return time.Date(year, month, day, 0, 0, 0, 0, now.Location())
}

//	每日定时任务
func dailyTask(market Market) {

	//	昨天零点
	yesterday := locationYesterdayZero(market)
	log.Printf("[%s]\t%s数据获取任务已启动", market.Name(), yesterday.Format("20060102"))

	//	获取市场所有上市公司
	companies, err := getCompanies(market)
	if err != nil {
		log.Print(err)
	}

	chanSend := make(chan int, companyGCCount)
	chanReceive := make(chan int)

	for _, c := range companies {
		//	并发抓取
		go func(company Company) {

			err := market.Crawl(market, company, yesterday)
			if err != nil {
				log.Print(err)
			}

			<-chanSend
			chanReceive <- 1
		}(c)

		chanSend <- 1
	}

	//	阻塞，直到抓取所有
	for _, _ = range companies {
		<-chanReceive
	}

	close(chanSend)
	close(chanReceive)

	log.Printf("[%s]\t%s数据获取任务已结束", market.Name(), yesterday.Format("20060102"))
}

//	历史数据获取任务
func historyTask(market Market, yesterday time.Time) {
	//	获取市场所有上市公司
	companies, err := getCompanies(market)
	if err != nil {
		log.Print(err)
		return
	}

	log.Printf("[%s]\t开始抓取%d家上市公司在%s之前的历史", market.Name(), len(companies), yesterday.Format("20060102"))

	chanSend := make(chan int, companyGCCount)
	chanReceive := make(chan int)

	for _, c := range companies {
		//	并发抓取
		go func(company Company) {

			for index := 0; index < lastestDays; index++ {
				day := yesterday.Add(-time.Hour * 24 * time.Duration(index))
				err := market.Crawl(market, company, day)
				if err != nil {
					log.Printf("[%s]\t抓取[%s]在%s的分时数据出错:%s", market.Name(), company.Code, day.Format("20060102"), err)
				}
			}

			<-chanSend
			chanReceive <- 1
		}(c)

		chanSend <- 1
	}

	//	阻塞，直到抓取所有
	for _, _ = range companies {
		<-chanReceive
	}

	close(chanSend)
	close(chanReceive)

	log.Printf("[%s]\t上市公司的历史分时数据已经抓取结束", market.Name())
}

//	抓取市场上市公司信息
func getCompanies(market Market) ([]Company, error) {

	cl := CompanyList{}
	//	尝试更新上市公司列表
	log.Printf("[%s]\t更新上市公司列表-开始", market.Name())
	companies, err := market.Companies()
	if err != nil {

		//	如果更新失败，则尝试从上次的存档文件中读取上市公司列表
		log.Printf("[%s]\t更新上市公司列表失败，尝试从存档读取:%v", market.Name(), err)
		err = cl.Load(market)
		if err != nil {
			return nil, fmt.Errorf("[%s]\t尝试从存档读取上市公司列表-失败:%v", market.Name(), err)
		}

		companies = cl
		log.Printf("[%s]\t尝试从存档读取上市公司列表-成功,共%d家上市公司", market.Name(), len(companies))

		return companies, nil
	}

	//	存档
	cl = CompanyList(companies)
	err = cl.Save(market)
	if err != nil {
		return nil, err
	}

	log.Printf("[%s]\t更新上市公司列表-成功,共%d家上市公司", market.Name(), len(companies))

	return companies, nil
}
<|endoftext|>


<commit_before>package impl

import (
	"fmt"
	"github.com/vitesse-ftian/dggo/vitessedata/proto/xdrive"
	//"os"
	//"time"
	"strings"
	"vitessedata/plugin"
)

// the reference URI search protocol can be found on the below link.
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
//
// DoRead servies XDrive read requests.   It read a ReadRequest from stdin and reply
// a sequence of PluginDataReply to stdout.   It should end the data stream with a
// trivial (Errcode == 0, but there is no data) message.
func DoRead() error {
	var req xdrive.ReadRequest
	err := plugin.DelimRead(&req)
	if err != nil {
		plugin.DbgLogIfErr(err, "Delim read req failed.")
		return err
	}

	// Check/validate frag info.  Again, not necessary, as xdriver server should always
	// fill in good value.
	if req.FragCnt <= 0 || req.FragId < 0 || req.FragId >= req.FragCnt {
		plugin.DbgLog("Invalid read req %v", req)
		plugin.ReplyError(-3, fmt.Sprintf("Read request frag (%d, %d) is not valid.", req.FragId, req.FragCnt))
		return fmt.Errorf("Invalid read request")
	}

	var es ESClient
	es.CreateUsingRinfo()

	shards := es.GetShards(req.FragId, req.FragCnt)

	if len(shards) == 0 {
		// return 0 record
		return nil
	}
	preference := es.GetPreferenceShards(shards)
	plugin.DbgLog("shards preference: %s", preference)

	params := make(map[string]string)
	params["preference"] = preference
	params["timeout"] = "30000"
	//
	// Filter:
	// req may contains a list of Filters that got pushed down from XDrive server.
	// As per plugin protocol, plugin can ignore all of them if they choose to be
	// lazy.  See comments in csvhandler.go.
	//
	// All filters are derived from SQL (where clause).  There is a special kind of
	// filter called "QUERY", which allow users to send any query to plugin.  Here as
	// an example, we implement a poorman's fault injection.
	//
	var query, _type string
	for _, f := range req.Filter {
		// f cannot be nil
		if f.Op == "QUERY" {
			query= f.Args[0]
			p := strings.Split(query, "&")

			for _, pp := range p {
				plugin.DbgLog(pp)
				ppp := strings.SplitN(pp, "=", 2)
				if len(ppp) == 2 {
					params[ppp[0]] = ppp[1]
				}
			}

		} else if f.Column == "_type" && f.Op == "==" {
			_type = f.Args[0]
		} else {
			params[f.Column] = f.Args[0]
		}
	}

	body, err := es.Search(es.Index, _type, params)
	if err != nil {
		plugin.DbgLogIfErr(err, "ElasticSearch failed. Error %v", err)
		plugin.ReplyError(-2, "elasticSearch access failed: " + err.Error())
		return err
	}
/*
	plugin.DbgLog("type=%s",  _type)

	body := []byte(`{"timed_out":false, "took":1, "_shards":{}, "hits":{ "total":1, "hits":[{"_id":"1", "_type":"online", "_score":"1", "_routing":"vip", "_source":{ "age":12, "gender":"female", "name":"eric"}}]}}`)
*/
	plugin.DbgLog(string(body))

	var reader ESReader
	reader.Init(req.Filespec, req.Columndesc, req.Columnlist)

	err = reader.process(body)
	if err != nil {
		plugin.DbgLogIfErr(err, "Parse Json result failed.")
		plugin.ReplyError(-20, "JSON result has invalid data")
		return err
	}

	// Done!   Fill in an empty reply, indicating end of stream.
	plugin.ReplyError(0, "")
	return nil
}
<commit_msg>esplugin<commit_after>package impl

import (
	"fmt"
	"github.com/vitesse-ftian/dggo/vitessedata/proto/xdrive"
	//"os"
	//"time"
	"strings"
	"vitessedata/plugin"
)

// the reference URI search protocol can be found on the below link.
// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
//
// DoSample servies XDrive read requests.   It read a ReadRequest from stdin and reply
// a sequence of PluginDataReply to stdout.   It should end the data stream with a
// trivial (Errcode == 0, but there is no data) message.
func DoSample() error {
	var req xdrive.ReadRequest
	err := plugin.DelimRead(&req)
	if err != nil {
		plugin.DbgLogIfErr(err, "Delim read req failed.")
		return err
	}

	// Check/validate frag info.  Again, not necessary, as xdriver server should always
	// fill in good value.
	if req.FragCnt <= 0 || req.FragId < 0 || req.FragId >= req.FragCnt {
		plugin.DbgLog("Invalid read req %v", req)
		plugin.ReplyError(-3, fmt.Sprintf("Read request frag (%d, %d) is not valid.", req.FragId, req.FragCnt))
		return fmt.Errorf("Invalid read request")
	}

	var es ESClient
	es.CreateUsingRinfo()

	shards := es.GetShards(req.FragId, req.FragCnt)

	if len(shards) == 0 {
		// return 0 record
		return nil
	}
	preference := es.GetPreferenceShards(shards)
	plugin.DbgLog("shards preference: %s", preference)

	params := make(map[string]string)
	params["preference"] = preference
	params["timeout"] = "30000"
	//
	// Filter:
	// req may contains a list of Filters that got pushed down from XDrive server.
	// As per plugin protocol, plugin can ignore all of them if they choose to be
	// lazy.  See comments in csvhandler.go.
	//
	// All filters are derived from SQL (where clause).  There is a special kind of
	// filter called "QUERY", which allow users to send any query to plugin.  Here as
	// an example, we implement a poorman's fault injection.
	//
	var query, _type string
	for _, f := range req.Filter {
		// f cannot be nil
		if f.Op == "QUERY" {
			query= f.Args[0]
			p := strings.Split(query, "&")

			for _, pp := range p {
				plugin.DbgLog(pp)
				ppp := strings.SplitN(pp, "=", 2)
				if len(ppp) == 2 {
					params[ppp[0]] = ppp[1]
				}
			}

		} else if f.Column == "_type" && f.Op == "==" {
			_type = f.Args[0]
		} else {
			params[f.Column] = f.Args[0]
		}
	}

	body, err := es.Search(es.Index, _type, params)
	if err != nil {
		plugin.DbgLogIfErr(err, "ElasticSearch failed. Error %v", err)
		plugin.ReplyError(-2, "elasticSearch access failed: " + err.Error())
		return err
	}
/*
	plugin.DbgLog("type=%s",  _type)

	body := []byte(`{"timed_out":false, "took":1, "_shards":{}, "hits":{ "total":1, "hits":[{"_id":"1", "_type":"online", "_score":"1", "_routing":"vip", "_source":{ "age":12, "gender":"female", "name":"eric"}}]}}`)
*/
	plugin.DbgLog(string(body))

	var reader ESReader
	reader.Init(req.Filespec, req.Columndesc, req.Columnlist)

	err = reader.process(body)
	if err != nil {
		plugin.DbgLogIfErr(err, "Parse Json result failed.")
		plugin.ReplyError(-20, "JSON result has invalid data")
		return err
	}

	// Done!   Fill in an empty reply, indicating end of stream.
	plugin.ReplyError(0, "")
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016-2020 The Libsacloud Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package libsacloud

// Version バージョン
const Version = "2.1.7"
<commit_msg>Bump to v2.1.8<commit_after>// Copyright 2016-2020 The Libsacloud Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package libsacloud

// Version バージョン
const Version = "2.1.8"
<|endoftext|>


<commit_before>package gforms

import (
	"errors"
	"fmt"
	"reflect"
	"regexp"
)

type Validator interface {
	Name() string
	Validate(*FieldInstance, *FormInstance) error
}

type Validators []Validator

type required struct {
	Message string
	Validator
}

// Returns error if the field is not provided.
func Required(message ...string) required {
	vl := required{}
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = "This field is required"
	}
	return vl
}

func (vl required) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || (v.Kind == reflect.String && v.Value == "") {
		return errors.New(vl.Message)
	}
	return nil
}

type maxLengthValidator struct {
	Length  int
	Message string
	Validator
}

// Returns error if the length of value is greater than length argument.
func MaxLengthValidator(length int, message ...string) maxLengthValidator {
	vl := maxLengthValidator{}
	vl.Length = length
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value has at most %v characters.", vl.Length)
	}
	return vl
}

func (vl maxLengthValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.String || v.Value == "" {
		return nil
	}
	s := v.Value.(string)
	if len(s) > vl.Length {
		return errors.New(vl.Message)
	}
	return nil
}

type minLengthValidator struct {
	Length  int
	Message string
	Validator
}

// Returns error if the length of value is less than length argument.
func MinLengthValidator(length int, message ...string) minLengthValidator {
	vl := minLengthValidator{}
	vl.Length = length
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value has at least %v characters", vl.Length)
	}
	return vl
}

func (vl minLengthValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.String || v.Value == "" {
		return nil
	}
	s := v.Value.(string)
	if len(s) < vl.Length {
		return errors.New(vl.Message)
	}
	return nil
}

type maxValueValidator struct {
	Value   int
	Message string
	Validator
}

func MaxValueValidator(value int, message ...string) maxValueValidator {
	vl := maxValueValidator{}
	vl.Value = value
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value is less than or equal to %v.", vl.Value)
	}
	return vl
}

func (vl maxValueValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.Int {
		return nil
	}
	iv := v.Value.(int)
	if iv > vl.Value {
		return errors.New(vl.Message)
	}
	return nil
}

type minValueValidator struct {
	Value   int
	Message string
	Validator
}

func MinValueValidator(value int, message ...string) minValueValidator {
	vl := minValueValidator{}
	vl.Value = value
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value is greater than or equal to %v.", vl.Value)
	}
	return vl
}

func (vl minValueValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.Int {
		return nil
	}
	iv := v.Value.(int)
	if iv < vl.Value {
		return errors.New(vl.Message)
	}
	return nil
}

type regexpValidator struct {
	re      *regexp.Regexp
	Message string
	Validator
}

func (vl regexpValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.String || v.Value == "" {
		return nil
	}
	sv := v.Value.(string)
	if !vl.re.MatchString(sv) {
		return errors.New(vl.Message)
	}
	return nil
}

// The regular expression pattern to search for the provided value.
// Returns error if regxp#MatchString is False.
func RegexpValidator(regex string, message ...string) regexpValidator {
	vl := regexpValidator{}
	re, err := regexp.Compile(regex)
	if err != nil {
		panic(err)
	}
	vl.re = re
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Enter a valid value.")
	}
	return vl
}

// An EmailValidator that ensures a value looks like an email address.
func EmailValidator(message ...string) regexpValidator {
	regex := `^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`
	if len(message) > 0 {
		return RegexpValidator(regex, message[0])
	} else {
		return RegexpValidator(regex, "Enter a valid email address.")
	}
}

// An URLValidator that ensures a value looks like an url.
func URLValidator(message ...string) regexpValidator {
	regex := `^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$`
	if len(message) > 0 {
		return RegexpValidator(regex, message[0])
	} else {
		return RegexpValidator(regex, "Enter a valid url.")
	}
}
<commit_msg>Fixed validator error message.<commit_after>package gforms

import (
	"errors"
	"fmt"
	"reflect"
	"regexp"
)

type Validator interface {
	Name() string
	Validate(*FieldInstance, *FormInstance) error
}

type Validators []Validator

type required struct {
	Message string
	Validator
}

// Returns error if the field is not provided.
func Required(message ...string) required {
	vl := required{}
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = "This field is required."
	}
	return vl
}

func (vl required) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || (v.Kind == reflect.String && v.Value == "") {
		return errors.New(vl.Message)
	}
	return nil
}

type maxLengthValidator struct {
	Length  int
	Message string
	Validator
}

// Returns error if the length of value is greater than length argument.
func MaxLengthValidator(length int, message ...string) maxLengthValidator {
	vl := maxLengthValidator{}
	vl.Length = length
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value has at most %v characters.", vl.Length)
	}
	return vl
}

func (vl maxLengthValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.String || v.Value == "" {
		return nil
	}
	s := v.Value.(string)
	if len(s) > vl.Length {
		return errors.New(vl.Message)
	}
	return nil
}

type minLengthValidator struct {
	Length  int
	Message string
	Validator
}

// Returns error if the length of value is less than length argument.
func MinLengthValidator(length int, message ...string) minLengthValidator {
	vl := minLengthValidator{}
	vl.Length = length
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value has at least %v characters", vl.Length)
	}
	return vl
}

func (vl minLengthValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.String || v.Value == "" {
		return nil
	}
	s := v.Value.(string)
	if len(s) < vl.Length {
		return errors.New(vl.Message)
	}
	return nil
}

type maxValueValidator struct {
	Value   int
	Message string
	Validator
}

func MaxValueValidator(value int, message ...string) maxValueValidator {
	vl := maxValueValidator{}
	vl.Value = value
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value is less than or equal to %v.", vl.Value)
	}
	return vl
}

func (vl maxValueValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.Int {
		return nil
	}
	iv := v.Value.(int)
	if iv > vl.Value {
		return errors.New(vl.Message)
	}
	return nil
}

type minValueValidator struct {
	Value   int
	Message string
	Validator
}

func MinValueValidator(value int, message ...string) minValueValidator {
	vl := minValueValidator{}
	vl.Value = value
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Ensure this value is greater than or equal to %v.", vl.Value)
	}
	return vl
}

func (vl minValueValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.Int {
		return nil
	}
	iv := v.Value.(int)
	if iv < vl.Value {
		return errors.New(vl.Message)
	}
	return nil
}

type regexpValidator struct {
	re      *regexp.Regexp
	Message string
	Validator
}

func (vl regexpValidator) Validate(fi *FieldInstance, fo *FormInstance) error {
	v := fi.V
	if v.IsNil || v.Kind != reflect.String || v.Value == "" {
		return nil
	}
	sv := v.Value.(string)
	if !vl.re.MatchString(sv) {
		return errors.New(vl.Message)
	}
	return nil
}

// The regular expression pattern to search for the provided value.
// Returns error if regxp#MatchString is False.
func RegexpValidator(regex string, message ...string) regexpValidator {
	vl := regexpValidator{}
	re, err := regexp.Compile(regex)
	if err != nil {
		panic(err)
	}
	vl.re = re
	if len(message) > 0 {
		vl.Message = message[0]
	} else {
		vl.Message = fmt.Sprintf("Enter a valid value.")
	}
	return vl
}

// An EmailValidator that ensures a value looks like an email address.
func EmailValidator(message ...string) regexpValidator {
	regex := `^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`
	if len(message) > 0 {
		return RegexpValidator(regex, message[0])
	} else {
		return RegexpValidator(regex, "Enter a valid email address.")
	}
}

// An URLValidator that ensures a value looks like an url.
func URLValidator(message ...string) regexpValidator {
	regex := `^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$`
	if len(message) > 0 {
		return RegexpValidator(regex, message[0])
	} else {
		return RegexpValidator(regex, "Enter a valid url.")
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 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.

// +build appengine

package build

import (
	"net/http"
	"strings"

	"appengine"
)

// Dashboard describes a unique build dashboard.
type Dashboard struct {
	Name     string     // This dashboard's name and namespace
	RelPath  string     // The relative url path
	Packages []*Package // The project's packages to build
}

// dashboardForRequest returns the appropriate dashboard for a given URL path.
func dashboardForRequest(r *http.Request) *Dashboard {
	if strings.HasPrefix(r.URL.Path, gccgoDash.RelPath) {
		return gccgoDash
	}
	return goDash
}

// Context returns a namespaced context for this dashboard, or panics if it
// fails to create a new context.
func (d *Dashboard) Context(c appengine.Context) appengine.Context {
	// No namespace needed for the original Go dashboard.
	if d.Name == "Go" {
		return c
	}
	n, err := appengine.Namespace(c, d.Name)
	if err != nil {
		panic(err)
	}
	return n
}

// the currently known dashboards.
var dashboards = []*Dashboard{goDash, gccgoDash}

// goDash is the dashboard for the main go repository.
var goDash = &Dashboard{
	Name:     "Go",
	RelPath:  "/",
	Packages: goPackages,
}

// goPackages is a list of all of the packages built by the main go repository.
var goPackages = []*Package{
	{
		Kind: "go",
		Name: "Go",
	},
	{
		Kind: "subrepo",
		Name: "go.blog",
		Path: "code.google.com/p/go.blog",
	},
	{
		Kind: "subrepo",
		Name: "go.codereview",
		Path: "code.google.com/p/go.codereview",
	},
	{
		Kind: "subrepo",
		Name: "go.crypto",
		Path: "code.google.com/p/go.crypto",
	},
	{
		Kind: "subrepo",
		Name: "go.exp",
		Path: "code.google.com/p/go.exp",
	},
	{
		Kind: "subrepo",
		Name: "go.image",
		Path: "code.google.com/p/go.image",
	},
	{
		Kind: "subrepo",
		Name: "go.net",
		Path: "code.google.com/p/go.net",
	},
	{
		Kind: "subrepo",
		Name: "go.talks",
		Path: "code.google.com/p/go.talks",
	},
	{
		Kind: "subrepo",
		Name: "go.tools",
		Path: "code.google.com/p/go.tools",
	},
}

// gccgoDash is the dashboard for gccgo.
var gccgoDash = &Dashboard{
	Name:    "Gccgo",
	RelPath: "/gccgo/",
	Packages: []*Package{
		{
			Kind: "gccgo",
			Name: "Gccgo",
		},
	},
}
<commit_msg>go.tools/dashboard/app: add go.sys to builder package list<commit_after>// Copyright 2013 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.

// +build appengine

package build

import (
	"net/http"
	"strings"

	"appengine"
)

// Dashboard describes a unique build dashboard.
type Dashboard struct {
	Name     string     // This dashboard's name and namespace
	RelPath  string     // The relative url path
	Packages []*Package // The project's packages to build
}

// dashboardForRequest returns the appropriate dashboard for a given URL path.
func dashboardForRequest(r *http.Request) *Dashboard {
	if strings.HasPrefix(r.URL.Path, gccgoDash.RelPath) {
		return gccgoDash
	}
	return goDash
}

// Context returns a namespaced context for this dashboard, or panics if it
// fails to create a new context.
func (d *Dashboard) Context(c appengine.Context) appengine.Context {
	// No namespace needed for the original Go dashboard.
	if d.Name == "Go" {
		return c
	}
	n, err := appengine.Namespace(c, d.Name)
	if err != nil {
		panic(err)
	}
	return n
}

// the currently known dashboards.
var dashboards = []*Dashboard{goDash, gccgoDash}

// goDash is the dashboard for the main go repository.
var goDash = &Dashboard{
	Name:     "Go",
	RelPath:  "/",
	Packages: goPackages,
}

// goPackages is a list of all of the packages built by the main go repository.
var goPackages = []*Package{
	{
		Kind: "go",
		Name: "Go",
	},
	{
		Kind: "subrepo",
		Name: "go.blog",
		Path: "code.google.com/p/go.blog",
	},
	{
		Kind: "subrepo",
		Name: "go.codereview",
		Path: "code.google.com/p/go.codereview",
	},
	{
		Kind: "subrepo",
		Name: "go.crypto",
		Path: "code.google.com/p/go.crypto",
	},
	{
		Kind: "subrepo",
		Name: "go.exp",
		Path: "code.google.com/p/go.exp",
	},
	{
		Kind: "subrepo",
		Name: "go.image",
		Path: "code.google.com/p/go.image",
	},
	{
		Kind: "subrepo",
		Name: "go.net",
		Path: "code.google.com/p/go.net",
	},
	{
		Kind: "subrepo",
		Name: "go.sys",
		Path: "code.google.com/p/go.sys",
	},
	{
		Kind: "subrepo",
		Name: "go.talks",
		Path: "code.google.com/p/go.talks",
	},
	{
		Kind: "subrepo",
		Name: "go.tools",
		Path: "code.google.com/p/go.tools",
	},
}

// gccgoDash is the dashboard for gccgo.
var gccgoDash = &Dashboard{
	Name:    "Gccgo",
	RelPath: "/gccgo/",
	Packages: []*Package{
		{
			Kind: "gccgo",
			Name: "Gccgo",
		},
	},
}
<|endoftext|>


<commit_before>// memory is a package which allows sunspec devices to be simulated in memory
// so that such devices canbe accessed with the SunSpec API implemented
// by http://github.com/crabmusket/gosunspec
package memory

import (
	"encoding/binary"
	"errors"
	"github.com/crabmusket/gosunspec"
	"github.com/crabmusket/gosunspec/impl"
	"github.com/crabmusket/gosunspec/layout"
	"github.com/crabmusket/gosunspec/models/model1"
	"github.com/crabmusket/gosunspec/smdx"
	"github.com/crabmusket/gosunspec/spi"
)

var (
	errNoModel        = errors.New("no model")
	errBadEyeCatcher  = errors.New("bad eyecatcher")
	errBufferTooShort = errors.New("buffer too short")
	eyeCatcher        = []byte{0x53, 0x75, 0x6e, 0x53} // "SunS"
)

type memoryDriver struct {
	buffer []byte
}

func (d *memoryDriver) iterator(b spi.BlockSPI, pointIds ...string) func(f func(buffer []byte, p spi.PointSPI) error) error {
	return func(f func(buffer []byte, p spi.PointSPI) error) error {
		var firstErr error

		points := []spi.PointSPI{}

		setError := func(e error) {
			if firstErr == nil && e != nil {
				firstErr = e
			}
		}

		for _, v := range pointIds {

			if p, err := b.Point(v); err != nil {
				setError(err)
			} else {
				points = append(points, p.(spi.PointSPI))
			}
		}

		if firstErr != nil {
			return firstErr
		}

		if len(points) == 0 {
			b.Do(spi.WithPointSPI(func(p spi.PointSPI) {
				points = append(points, p.(spi.PointSPI))
			}))
		}

		buffer := d.buffer[b.Anchor().(uint16)*2:]

		for _, p := range points {
			if p.Offset()+p.Length() > b.Length() {
				err := errBufferTooShort
				p.SetError(err)
				setError(err)
				continue
			}
			err := f(buffer[p.Offset()*2:(p.Offset()+p.Length())*2], p)
			if err != nil {
				p.SetError(err)
				setError(err)
			}
		}

		return firstErr
	}

}

func (d *memoryDriver) Read(b spi.BlockSPI, pointIds ...string) error {
	if points, err := b.Plan(pointIds...); err != nil {
		return err
	} else {
		var firstErr error
		buffer := d.buffer[b.Anchor().(uint16)*2:]
		for _, p := range points {
			if p.Offset()+p.Length() > b.Length() {
				err := errBufferTooShort
				p.SetError(err)
				if firstErr == nil {
					firstErr = err
				}
				continue
			}
			err := p.Unmarshal(buffer[p.Offset()*2 : (p.Offset()+p.Length())*2])
			if err != nil {
				p.SetError(err)
				if firstErr == nil {
					firstErr = err
				}
			}
		}
		return firstErr
	}
}

func (d *memoryDriver) Write(b spi.BlockSPI, pointIds ...string) error {
	return d.iterator(b, pointIds...)(func(buffer []byte, p spi.PointSPI) error {
		if p.Error() == nil {
			return p.Marshal(buffer)
		} else {
			return nil
		}
	})
}

func (d *memoryDriver) ReadWords(a uint16, l uint16) ([]byte, error) {
	return d.buffer[a*2 : (a+l)*2], nil
}

func (d *memoryDriver) BaseOffsets() []uint16 {
	return []uint16{0}
}

// Open a memory mapped Sunspec device from the specified
// byte slice or return an error if this cannot be done.
func Open(bytes []byte) (sunspec.Array, error) {
	return OpenWithLayout(bytes, &layout.SunSpecLayout{})
}

// Open a memory mapped Sunspec device from the specified
// byte slice, using the layout specified to match regions
// of the slice to particular devices and models.
func OpenWithLayout(bytes []byte, l layout.AddressSpaceLayout) (sunspec.Array, error) {
	return l.Open(&memoryDriver{buffer: bytes})
}

// SlabBuilder creates a slab of memory (actually a byte slice)
// to which a Sunspec device can be mapped.
//
// The main purpose of this type is to enable unit testing of the API
// without an actual Modbus device.
type SlabBuilder interface {
	AddDevice() SlabBuilder
	AddModel(id sunspec.ModelId) SlabBuilder
	AddRepeat(id sunspec.ModelId) SlabBuilder
	Build() ([]byte, error) // generates a byte slice containing the memory mapped device.
}

// Create a new device map builder.
func NewSlabBuilder() SlabBuilder {
	b := &builder{
		array: impl.NewArray(),
	}
	b.device = impl.NewDevice()
	b.AddModel(model1.ModelID) // all maps include the common model
	b.array.AddDevice(b.device)
	return b
}

type builder struct {
	array  spi.ArraySPI
	device spi.DeviceSPI
	err    error
}

func (b *builder) record(err error) {
	if err != nil && b.err == nil {
		b.err = err
	}
}

// Add the specified model to the device
func (b *builder) AddModel(id sunspec.ModelId) SlabBuilder {
	me := smdx.GetModel(uint16(id))
	if me != nil {
		m := impl.NewModel(me, 0, nil)
		b.record(b.device.AddModel(m))
	} else {
		b.record(errNoModel)
	}
	return b
}

func (b *builder) AddDevice() SlabBuilder {
	b.device = impl.NewDevice()
	b.AddModel(model1.ModelID) // all maps include the common model
	b.array.AddDevice(b.device)
	return b
}

// Add a repeat to the specified model
func (b *builder) AddRepeat(id sunspec.ModelId) SlabBuilder {
	// Note: this assumes all models of the same identifier
	// in the same address space have the same number of repeats
	// In principle, this might not be true. In practice,
	// it is likely to be true. We can live with the simplification
	// for now.
	b.device.Do(func(m sunspec.Model) {
		if m.Id() == id {
			b.record(m.(spi.ModelSPI).AddRepeat())
		}
	})
	return b
}

// Build a fresh byte slice in which the Sunspec device definition
// has been encoded. This byte slice can be accessed with the API
// by passing it to the Open function.
func (b *builder) Build() ([]byte, error) {

	if b.err != nil {
		return nil, b.err
	}

	// calculate the total size

	total := uint16(4) // eyecatcher + endmarker
	b.array.Do(spi.WithDeviceSPI(func(d spi.DeviceSPI) {
		d.Do(spi.WithModelSPI(func(m spi.ModelSPI) {
			total += 2 + m.Length() // header + model
		}))
	}))
	output := make([]byte, total*2)

	// render the eyecatcher and model/length markers

	copy(output, eyeCatcher)
	offset := 4
	b.array.Do(spi.WithDeviceSPI(func(d spi.DeviceSPI) {
		d.Do(spi.WithModelSPI(func(m spi.ModelSPI) {
			binary.BigEndian.PutUint16(output[offset:], uint16(m.Id()))
			binary.BigEndian.PutUint16(output[offset+2:], m.Length())
			offset += 4 + int(m.Length())*2
		}))
	}))

	// render the end marker

	binary.BigEndian.PutUint16(output[offset:], 0xffff)
	binary.BigEndian.PutUint16(output[offset+2:], 0)
	return output, nil
}
<commit_msg>fix: fix silent overflow of uint16 value.<commit_after>// memory is a package which allows sunspec devices to be simulated in memory
// so that such devices canbe accessed with the SunSpec API implemented
// by http://github.com/crabmusket/gosunspec
package memory

import (
	"encoding/binary"
	"errors"
	"github.com/crabmusket/gosunspec"
	"github.com/crabmusket/gosunspec/impl"
	"github.com/crabmusket/gosunspec/layout"
	"github.com/crabmusket/gosunspec/models/model1"
	"github.com/crabmusket/gosunspec/smdx"
	"github.com/crabmusket/gosunspec/spi"
)

var (
	errNoModel        = errors.New("no model")
	errBadEyeCatcher  = errors.New("bad eyecatcher")
	errBufferTooShort = errors.New("buffer too short")
	eyeCatcher        = []byte{0x53, 0x75, 0x6e, 0x53} // "SunS"
)

type memoryDriver struct {
	buffer []byte
}

func (d *memoryDriver) iterator(b spi.BlockSPI, pointIds ...string) func(f func(buffer []byte, p spi.PointSPI) error) error {
	return func(f func(buffer []byte, p spi.PointSPI) error) error {
		var firstErr error

		points := []spi.PointSPI{}

		setError := func(e error) {
			if firstErr == nil && e != nil {
				firstErr = e
			}
		}

		for _, v := range pointIds {

			if p, err := b.Point(v); err != nil {
				setError(err)
			} else {
				points = append(points, p.(spi.PointSPI))
			}
		}

		if firstErr != nil {
			return firstErr
		}

		if len(points) == 0 {
			b.Do(spi.WithPointSPI(func(p spi.PointSPI) {
				points = append(points, p.(spi.PointSPI))
			}))
		}

		buffer := d.buffer[uint32(b.Anchor().(uint16))*2:]

		for _, p := range points {
			if p.Offset()+p.Length() > b.Length() {
				err := errBufferTooShort
				p.SetError(err)
				setError(err)
				continue
			}
			err := f(buffer[p.Offset()*2:(p.Offset()+p.Length())*2], p)
			if err != nil {
				p.SetError(err)
				setError(err)
			}
		}

		return firstErr
	}

}

func (d *memoryDriver) Read(b spi.BlockSPI, pointIds ...string) error {
	if points, err := b.Plan(pointIds...); err != nil {
		return err
	} else {
		var firstErr error
		buffer := d.buffer[uint32(b.Anchor().(uint16))*2:]
		for _, p := range points {
			if p.Offset()+p.Length() > b.Length() {
				err := errBufferTooShort
				p.SetError(err)
				if firstErr == nil {
					firstErr = err
				}
				continue
			}
			err := p.Unmarshal(buffer[p.Offset()*2 : (p.Offset()+p.Length())*2])
			if err != nil {
				p.SetError(err)
				if firstErr == nil {
					firstErr = err
				}
			}
		}
		return firstErr
	}
}

func (d *memoryDriver) Write(b spi.BlockSPI, pointIds ...string) error {
	return d.iterator(b, pointIds...)(func(buffer []byte, p spi.PointSPI) error {
		if p.Error() == nil {
			return p.Marshal(buffer)
		} else {
			return nil
		}
	})
}

func (d *memoryDriver) ReadWords(a uint16, l uint16) ([]byte, error) {
	return d.buffer[a*2 : (a+l)*2], nil
}

func (d *memoryDriver) BaseOffsets() []uint16 {
	return []uint16{0}
}

// Open a memory mapped Sunspec device from the specified
// byte slice or return an error if this cannot be done.
func Open(bytes []byte) (sunspec.Array, error) {
	return OpenWithLayout(bytes, &layout.SunSpecLayout{})
}

// Open a memory mapped Sunspec device from the specified
// byte slice, using the layout specified to match regions
// of the slice to particular devices and models.
func OpenWithLayout(bytes []byte, l layout.AddressSpaceLayout) (sunspec.Array, error) {
	return l.Open(&memoryDriver{buffer: bytes})
}

// SlabBuilder creates a slab of memory (actually a byte slice)
// to which a Sunspec device can be mapped.
//
// The main purpose of this type is to enable unit testing of the API
// without an actual Modbus device.
type SlabBuilder interface {
	AddDevice() SlabBuilder
	AddModel(id sunspec.ModelId) SlabBuilder
	AddRepeat(id sunspec.ModelId) SlabBuilder
	Build() ([]byte, error) // generates a byte slice containing the memory mapped device.
}

// Create a new device map builder.
func NewSlabBuilder() SlabBuilder {
	b := &builder{
		array: impl.NewArray(),
	}
	b.device = impl.NewDevice()
	b.AddModel(model1.ModelID) // all maps include the common model
	b.array.AddDevice(b.device)
	return b
}

type builder struct {
	array  spi.ArraySPI
	device spi.DeviceSPI
	err    error
}

func (b *builder) record(err error) {
	if err != nil && b.err == nil {
		b.err = err
	}
}

// Add the specified model to the device
func (b *builder) AddModel(id sunspec.ModelId) SlabBuilder {
	me := smdx.GetModel(uint16(id))
	if me != nil {
		m := impl.NewModel(me, 0, nil)
		b.record(b.device.AddModel(m))
	} else {
		b.record(errNoModel)
	}
	return b
}

func (b *builder) AddDevice() SlabBuilder {
	b.device = impl.NewDevice()
	b.AddModel(model1.ModelID) // all maps include the common model
	b.array.AddDevice(b.device)
	return b
}

// Add a repeat to the specified model
func (b *builder) AddRepeat(id sunspec.ModelId) SlabBuilder {
	// Note: this assumes all models of the same identifier
	// in the same address space have the same number of repeats
	// In principle, this might not be true. In practice,
	// it is likely to be true. We can live with the simplification
	// for now.
	b.device.Do(func(m sunspec.Model) {
		if m.Id() == id {
			b.record(m.(spi.ModelSPI).AddRepeat())
		}
	})
	return b
}

// Build a fresh byte slice in which the Sunspec device definition
// has been encoded. This byte slice can be accessed with the API
// by passing it to the Open function.
func (b *builder) Build() ([]byte, error) {

	if b.err != nil {
		return nil, b.err
	}

	// calculate the total size

	total := uint16(4) // eyecatcher + endmarker
	b.array.Do(spi.WithDeviceSPI(func(d spi.DeviceSPI) {
		d.Do(spi.WithModelSPI(func(m spi.ModelSPI) {
			total += 2 + m.Length() // header + model
		}))
	}))
	output := make([]byte, total*2)

	// render the eyecatcher and model/length markers

	copy(output, eyeCatcher)
	offset := 4
	b.array.Do(spi.WithDeviceSPI(func(d spi.DeviceSPI) {
		d.Do(spi.WithModelSPI(func(m spi.ModelSPI) {
			binary.BigEndian.PutUint16(output[offset:], uint16(m.Id()))
			binary.BigEndian.PutUint16(output[offset+2:], m.Length())
			offset += 4 + int(m.Length())*2
		}))
	}))

	// render the end marker

	binary.BigEndian.PutUint16(output[offset:], 0xffff)
	binary.BigEndian.PutUint16(output[offset+2:], 0)
	return output, nil
}
<|endoftext|>


<commit_before>package layercake

import (
	"sync"

	"github.com/docker/docker/image"

	"github.com/pivotal-golang/lager"
)

type OvenCleaner struct {
	Cake

	Logger lager.Logger

	EnableImageCleanup bool

	images   map[string]int
	imagesMu sync.RWMutex

	mu map[ID]*sync.RWMutex
}

func (g *OvenCleaner) Get(id ID) (*image.Image, error) {
	g.l(id).RLock() // avoid saying image is there if we might be in the process of deleting it
	defer g.l(id).RUnlock()

	return g.Cake.Get(id)
}

func (g *OvenCleaner) Remove(id ID) error {
	g.l(id).Lock()
	defer g.l(id).Unlock()

	log := g.Logger.Session("remove", lager.Data{"ID": id})
	log.Info("start")

	if g.isHeld(id) {
		log.Info("layer-is-held")
		return nil
	}

	img, err := g.Cake.Get(id)
	if err != nil {
		log.Error("get-image", err)
		return nil
	}

	if err := g.Cake.Remove(id); err != nil {
		return err
	}

	if !g.EnableImageCleanup {
		return nil
	}

	if img.Parent == "" {
		return nil
	}
	if leaf, err := g.Cake.IsLeaf(DockerImageID(img.Parent)); err == nil && leaf {
		return g.Remove(DockerImageID(img.Parent))
	}

	return nil
}

func (g *OvenCleaner) Retain(id ID) {
	g.imagesMu.Lock()
	defer g.imagesMu.Unlock()

	if g.images == nil {
		g.images = make(map[string]int)
	}

	g.images[id.GraphID()]++
}

func (g *OvenCleaner) isHeld(id ID) bool {
	g.imagesMu.Lock()
	defer g.imagesMu.Unlock()

	if g.images == nil {
		g.images = make(map[string]int)
	}

	_, ok := g.images[id.GraphID()]
	return ok
}

func (g *OvenCleaner) l(id ID) *sync.RWMutex {
	if g.mu == nil {
		g.mu = make(map[ID]*sync.RWMutex)
	}

	if m, ok := g.mu[id]; ok {
		return m
	}

	g.mu[id] = &sync.RWMutex{}
	return g.mu[id]
}
<commit_msg>Make OvenCleaner thread safe<commit_after>package layercake

import (
	"sync"

	"github.com/docker/docker/image"

	"github.com/pivotal-golang/lager"
)

type OvenCleaner struct {
	Cake

	Logger lager.Logger

	EnableImageCleanup bool

	images   map[string]int
	imagesMu sync.RWMutex

	mu   map[ID]*sync.RWMutex
	muMu sync.RWMutex
}

func (g *OvenCleaner) Get(id ID) (*image.Image, error) {
	g.l(id).RLock() // avoid saying image is there if we might be in the process of deleting it
	defer g.l(id).RUnlock()

	return g.Cake.Get(id)
}

func (g *OvenCleaner) Remove(id ID) error {
	g.l(id).Lock()
	defer g.l(id).Unlock()

	log := g.Logger.Session("remove", lager.Data{"ID": id})
	log.Info("start")

	if g.isHeld(id) {
		log.Info("layer-is-held")
		return nil
	}

	img, err := g.Cake.Get(id)
	if err != nil {
		log.Error("get-image", err)
		return nil
	}

	if err := g.Cake.Remove(id); err != nil {
		return err
	}

	if !g.EnableImageCleanup {
		return nil
	}

	if img.Parent == "" {
		return nil
	}
	if leaf, err := g.Cake.IsLeaf(DockerImageID(img.Parent)); err == nil && leaf {
		return g.Remove(DockerImageID(img.Parent))
	}

	return nil
}

func (g *OvenCleaner) Retain(id ID) {
	g.imagesMu.Lock()
	defer g.imagesMu.Unlock()

	if g.images == nil {
		g.images = make(map[string]int)
	}

	g.images[id.GraphID()]++
}

func (g *OvenCleaner) isHeld(id ID) bool {
	g.imagesMu.Lock()
	defer g.imagesMu.Unlock()

	if g.images == nil {
		g.images = make(map[string]int)
	}

	_, ok := g.images[id.GraphID()]
	return ok
}

func (g *OvenCleaner) l(id ID) *sync.RWMutex {
	g.muMu.Lock()
	defer g.muMu.Unlock()

	if g.mu == nil {
		g.mu = make(map[ID]*sync.RWMutex)
	}

	if m, ok := g.mu[id]; ok {
		return m
	}

	g.mu[id] = &sync.RWMutex{}
	return g.mu[id]
}
<|endoftext|>


<commit_before>package core

import (
	"time"

	"github.com/MustWin/baremetal-sdk-go"
	"github.com/MustWin/terraform-Oracle-BareMetal-Provider/client"
	"github.com/hashicorp/terraform/helper/schema"
)

type IPSecDatasourceCrud struct {
	D        *schema.ResourceData
	Client   client.BareMetalClient
	Resource *baremetal.ListIPSecConnections
}

func (s *IPSecDatasourceCrud) Get() (e error) {
	compartmentID := s.D.Get("compartment_id").(string)
	opts := getCoreOptionsFromResourceData(s.D, "drg_id", "cpe_id")

	s.Resource, e = s.Client.ListIPSecConnections(compartmentID, opts...)
	return

}

func (s IPSecDatasourceCrud) SetData() {
	if s.Resource != nil {
		s.D.SetId(time.Now().UTC().String())
		resources := []map[string]interface{}{}

		for _, v := range s.Resource.Connections {

			resource := map[string]interface{}{
				"compartment_id": v.CompartmentID,
				"drg_id":         v.DrgID,
				"cpe_id":         v.CpeID,
				"display_name":   v.DisplayName,
				"id":             v.ID,
				"state":          v.State,
				"static_routes":  v.StaticRoutes,
				"time_created":   v.TimeCreated.String(),
			}

			resources = append(resources, resource)
		}

		s.D.Set("connections", resources)

	}

	return
}

type IPSecDatasourceStatusCrud struct {
	D        *schema.ResourceData
	Client   client.BareMetalClient
	Resource *baremetal.IPSecConnectionDeviceStatus
}

func (s *IPSecDatasourceStatusCrud) Get() (e error) {
	ipsecID := s.D.Get("ipsec_id").(string)
	s.Resource, e = s.Client.GetIPSecConnectionDeviceStatus(ipsecID)
	return
}

func (s *IPSecDatasourceStatusCrud) SetData() {
	if s.Resource != nil {
		s.D.SetId(s.Resource.ID)
		s.D.Set("compartment_id", s.Resource.CompartmentID)
		s.D.Set("id", s.Resource.ID)
		s.D.Set("time_created", s.Resource.TimeCreated)

		tunnels := []map[string]interface{}{}

		for _, val := range s.Resource.Tunnels {
			tunnel := map[string]interface{}{
				"ip_address":         val.IPAddress,
				"state":              val.State,
				"time_created":       val.TimeCreated.String(),
				"time_state_modifed": val.TimeStateModified.String(),
			}

			tunnels = append(tunnels, tunnel)
		}

		s.D.Set("tunnels", tunnels)

	}
}

type IPSecDatasourceConfigCrud struct {
	D        *schema.ResourceData
	Client   client.BareMetalClient
	Resource *baremetal.IPSecConnectionDeviceConfig
}

func (s *IPSecDatasourceConfigCrud) Get() (e error) {
	ipsecID := s.D.Get("ipsec_id").(string)
	s.Resource, e = s.Client.GetIPSecConnectionDeviceConfig(ipsecID)
	return
}

func (s *IPSecDatasourceConfigCrud) SetData() {
	if s.Resource != nil {
		s.D.SetId(s.Resource.ID)
		s.D.Set("compartment_id", s.Resource.CompartmentID)
		s.D.Set("id", s.Resource.ID)
		s.D.Set("time_created", s.Resource.TimeCreated)

		tunnels := []map[string]interface{}{}

		for _, val := range s.Resource.Tunnels {
			tunnel := map[string]interface{}{
				"ip_address":    val.IPAddress,
				"shared_secret": val.SharedSecret,
				"time_created":  val.TimeCreated.String(),
			}

			tunnels = append(tunnels, tunnel)
		}

		s.D.Set("tunnels", tunnels)

	}
}
<commit_msg>Missed commit of this file<commit_after>package core

import (
	"time"

	"github.com/MustWin/baremetal-sdk-go"
	"github.com/MustWin/terraform-Oracle-BareMetal-Provider/client"
	"github.com/hashicorp/terraform/helper/schema"
)

type IPSecDatasourceCrud struct {
	D        *schema.ResourceData
	Client   client.BareMetalClient
	Resource *baremetal.ListIPSecConnections
}

func (s *IPSecDatasourceCrud) Get() (e error) {
	compartmentID := s.D.Get("compartment_id").(string)
	opts := getCoreOptionsFromResourceData(s.D, "drg_id", "cpe_id")

	s.Resource, e = s.Client.ListIPSecConnections(compartmentID, opts...)
	return

}

func (s IPSecDatasourceCrud) SetData() {
	if s.Resource != nil {
		s.D.SetId(time.Now().UTC().String())
		resources := []map[string]interface{}{}

		for _, v := range s.Resource.Connections {

			resource := map[string]interface{}{
				"compartment_id": v.CompartmentID,
				"drg_id":         v.DrgID,
				"cpe_id":         v.CpeID,
				"display_name":   v.DisplayName,
				"id":             v.ID,
				"state":          v.State,
				"static_routes":  v.StaticRoutes,
				"time_created":   v.TimeCreated.String(),
			}

			resources = append(resources, resource)
		}

		s.D.Set("connections", resources)

	}

	return
}
<|endoftext|>


<commit_before>package lfs

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"io"
	"os"
)

type cleanedAsset struct {
	Filename string
	*Pointer
}

type CleanedPointerError struct {
	Pointer *Pointer
	Bytes   []byte
}

func (e *CleanedPointerError) Error() string {
	return "Cannot clean a Git LFS pointer.  Skipping."
}

func PointerClean(reader io.Reader, fileName string, fileSize int64, cb CopyCallback) (*cleanedAsset, error) {
	extensions, err := SortExtensions(Config.Extensions())
	if err != nil {
		return nil, err
	}

	var oid string
	var size int64
	var tmp *os.File
	// Initialise to empty set rather than nil for consistency with pointer decode
	var exts []*PointerExtension = make([]*PointerExtension, 0)
	if len(extensions) > 0 {
		request := &pipeRequest{"clean", reader, fileName, extensions}

		var response pipeResponse
		if response, err = pipeExtensions(request); err != nil {
			return nil, err
		}

		oid = response.results[len(response.results)-1].oidOut
		tmp = response.file
		var stat os.FileInfo
		if stat, err = os.Stat(tmp.Name()); err != nil {
			return nil, err
		}
		size = stat.Size()

		for _, result := range response.results {
			if result.oidIn != result.oidOut {
				ext := NewPointerExtension(result.name, len(exts), result.oidIn)
				exts = append(exts, ext)
			}
		}
	} else {
		oid, size, tmp, err = copyToTemp(reader, fileSize, cb)
		if err != nil {
			return nil, err
		}
	}

	pointer := NewPointer(oid, size, exts)
	return &cleanedAsset{tmp.Name(), pointer}, err
}

func copyToTemp(reader io.Reader, fileSize int64, cb CopyCallback) (oid string, size int64, tmp *os.File, err error) {
	tmp, err = TempFile("")
	if err != nil {
		return
	}

	defer tmp.Close()

	oidHash := sha256.New()
	writer := io.MultiWriter(oidHash, tmp)

	if fileSize == 0 {
		cb = nil
	}

	by, ptr, err := DecodeFrom(reader)
	if err == nil && len(by) < 512 {
		err = &CleanedPointerError{ptr, by}
		return
	}

	multi := io.MultiReader(bytes.NewReader(by), reader)
	size, err = CopyWithCallback(writer, multi, fileSize, cb)

	if err != nil {
		return
	}

	oid = hex.EncodeToString(oidHash.Sum(nil))
	return
}

func (a *cleanedAsset) Teardown() error {
	return os.Remove(a.Filename)
}
<commit_msg>アアー アアアア アー<commit_after>package lfs

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"io"
	"os"
)

type cleanedAsset struct {
	Filename string
	*Pointer
}

type CleanedPointerError struct {
	Pointer *Pointer
	Bytes   []byte
}

func (e *CleanedPointerError) Error() string {
	return "Cannot clean a Git LFS pointer.  Skipping."
}

func PointerClean(reader io.Reader, fileName string, fileSize int64, cb CopyCallback) (*cleanedAsset, error) {
	extensions, err := SortExtensions(Config.Extensions())
	if err != nil {
		return nil, err
	}

	var oid string
	var size int64
	var tmp *os.File
	var exts []*PointerExtension
	if len(extensions) > 0 {
		request := &pipeRequest{"clean", reader, fileName, extensions}

		var response pipeResponse
		if response, err = pipeExtensions(request); err != nil {
			return nil, err
		}

		oid = response.results[len(response.results)-1].oidOut
		tmp = response.file
		var stat os.FileInfo
		if stat, err = os.Stat(tmp.Name()); err != nil {
			return nil, err
		}
		size = stat.Size()

		for _, result := range response.results {
			if result.oidIn != result.oidOut {
				ext := NewPointerExtension(result.name, len(exts), result.oidIn)
				exts = append(exts, ext)
			}
		}
	} else {
		oid, size, tmp, err = copyToTemp(reader, fileSize, cb)
		if err != nil {
			return nil, err
		}
	}

	pointer := NewPointer(oid, size, exts)
	return &cleanedAsset{tmp.Name(), pointer}, err
}

func copyToTemp(reader io.Reader, fileSize int64, cb CopyCallback) (oid string, size int64, tmp *os.File, err error) {
	tmp, err = TempFile("")
	if err != nil {
		return
	}

	defer tmp.Close()

	oidHash := sha256.New()
	writer := io.MultiWriter(oidHash, tmp)

	if fileSize == 0 {
		cb = nil
	}

	by, ptr, err := DecodeFrom(reader)
	if err == nil && len(by) < 512 {
		err = &CleanedPointerError{ptr, by}
		return
	}

	multi := io.MultiReader(bytes.NewReader(by), reader)
	size, err = CopyWithCallback(writer, multi, fileSize, cb)

	if err != nil {
		return
	}

	oid = hex.EncodeToString(oidHash.Sum(nil))
	return
}

func (a *cleanedAsset) Teardown() error {
	return os.Remove(a.Filename)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/globalaccelerator"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsGlobalAcceleratorEndpointGroup() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsGlobalAcceleratorEndpointGroupCreate,
		Read:   resourceAwsGlobalAcceleratorEndpointGroupRead,
		Update: resourceAwsGlobalAcceleratorEndpointGroupUpdate,
		Delete: resourceAwsGlobalAcceleratorEndpointGroupDelete,

		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"listener_arn": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"endpoint_group_region": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"health_check_interval_seconds": {
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      30,
				ValidateFunc: validation.IntBetween(10, 30),
			},
			"health_check_path": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  "/",
			},
			"health_check_port": {
				Type:     schema.TypeInt,
				Optional: true,
			},
			"health_check_protocol": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  globalaccelerator.HealthCheckProtocolTcp,
				ValidateFunc: validation.StringInSlice([]string{
					globalaccelerator.HealthCheckProtocolTcp,
					globalaccelerator.HealthCheckProtocolHttp,
					globalaccelerator.HealthCheckProtocolHttps,
				}, false),
			},
			"threshold_count": {
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      3,
				ValidateFunc: validation.IntBetween(1, 10),
			},
			"traffic_dial_percentage": {
				Type:         schema.TypeFloat,
				Optional:     true,
				Default:      100,
				ValidateFunc: validation.IntBetween(0, 100),
			},
			"endpoint_configuration": {
				Type:     schema.TypeSet,
				Optional: true,
				MaxItems: 10,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"endpoint_id": {
							Type:     schema.TypeString,
							Optional: true,
						},
						"weight": {
							Type:     schema.TypeInt,
							Optional: true,
						},
					},
				},
			},
		},
	}
}

func resourceAwsGlobalAcceleratorEndpointGroupCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn
	region := meta.(*AWSClient).region

	opts := &globalaccelerator.CreateEndpointGroupInput{
		ListenerArn:         aws.String(d.Get("listener_arn").(string)),
		IdempotencyToken:    aws.String(resource.UniqueId()),
		EndpointGroupRegion: aws.String(region),
	}

	if v, ok := d.GetOk("endpoint_group_region"); ok {
		opts.EndpointGroupRegion = aws.String(v.(string))
	}

	if v, ok := d.GetOk("health_check_interval_seconds"); ok {
		opts.HealthCheckIntervalSeconds = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_path"); ok {
		opts.HealthCheckPath = aws.String(v.(string))
	}

	if v, ok := d.GetOk("health_check_port"); ok {
		opts.HealthCheckPort = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_protocol"); ok {
		opts.HealthCheckProtocol = aws.String(v.(string))
	}

	if v, ok := d.GetOk("threshold_count"); ok {
		opts.ThresholdCount = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("traffic_dial_percentage"); ok {
		opts.TrafficDialPercentage = aws.Float64(v.(float64))
	}

	if v, ok := d.GetOk("endpoint_configuration"); ok {
		opts.EndpointConfigurations = resourceAwsGlobalAcceleratorEndpointGroupExpandEndpointConfigurations(v.([]interface{}))
	}

	log.Printf("[DEBUG] Create Global Accelerator endpoint group: %s", opts)

	resp, err := conn.CreateEndpointGroup(opts)
	if err != nil {
		return fmt.Errorf("Error creating Global Accelerator endpoint group: %s", err)
	}

	d.SetId(*resp.EndpointGroup.EndpointGroupArn)

	acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())

	if err != nil {
		return err
	}

	err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)

	if err != nil {
		return err
	}

	return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)

	// Creating an endpoint group triggers the accelerator to change status to InPending
	stateConf := &resource.StateChangeConf{
		Pending: []string{globalaccelerator.AcceleratorStatusInProgress},
		Target:  []string{globalaccelerator.AcceleratorStatusDeployed},
		Refresh: resourceAwsGlobalAcceleratorAcceleratorStateRefreshFunc(conn, acceleratorArn),
		Timeout: 5 * time.Minute,
	}

	log.Printf("[DEBUG] Waiting for Global Accelerator endpoint group (%s) availability", d.Id())
	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for Global Accelerator endpoint group (%s) availability: %s", d.Id(), err)
	}

	return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)
}

func resourceAwsGlobalAcceleratorEndpointGroupRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn

	endpointGroup, err := resourceAwsGlobalAcceleratorEndpointGroupRetrieve(conn, d.Id())

	if err != nil {
		return fmt.Errorf("Error reading Global Accelerator endpoint group: %s", err)
	}

	if endpointGroup == nil {
		log.Printf("[WARN] Global Accelerator endpoint group (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	listenerArn, err := resourceAwsGlobalAcceleratorEndpointGroupParseListenerArn(d.Id())

	if err != nil {
		return err
	}

	d.Set("listener_arn", listenerArn)
	d.Set("endpoint_group_region", endpointGroup.EndpointGroupRegion)
	d.Set("health_check_interval_seconds", endpointGroup.HealthCheckIntervalSeconds)
	d.Set("health_check_path", endpointGroup.HealthCheckPath)
	d.Set("health_check_port", endpointGroup.HealthCheckPort)
	d.Set("health_check_protocol", endpointGroup.HealthCheckProtocol)
	d.Set("threshold_count", endpointGroup.ThresholdCount)
	d.Set("traffic_dial_percentage", endpointGroup.TrafficDialPercentage)
	if err := d.Set("endpoint_configuration", resourceAwsGlobalAcceleratorEndpointGroupFlattenEndpointDescriptions(endpointGroup.EndpointDescriptions)); err != nil {
		return fmt.Errorf("error setting endpoint_configuration: %s", err)
	}

	return nil
}

func resourceAwsGlobalAcceleratorEndpointGroupParseListenerArn(endpointGroupArn string) (string, error) {
	parts := strings.Split(endpointGroupArn, "/")
	if len(parts) < 6 {
		return "", fmt.Errorf("Unable to parse listener ARN from %s", endpointGroupArn)
	}
	return strings.Join(parts[0:4], "/"), nil
}

func resourceAwsGlobalAcceleratorEndpointGroupExpandEndpointConfigurations(configurations []interface{}) []*globalaccelerator.EndpointConfiguration {
	out := make([]*globalaccelerator.EndpointConfiguration, len(configurations))

	for i, raw := range configurations {
		configuration := raw.(map[string]interface{})
		m := globalaccelerator.EndpointConfiguration{}

		m.EndpointId = aws.String(configuration["endpoint_id"].(string))
		m.Weight = aws.Int64(int64(configuration["weight"].(int)))

		out[i] = &m
	}

	log.Printf("[DEBUG] Expand endpoint_configuration: %s", out)
	return out
}

func resourceAwsGlobalAcceleratorEndpointGroupFlattenEndpointDescriptions(configurations []*globalaccelerator.EndpointDescription) []interface{} {
	out := make([]interface{}, len(configurations))

	for i, configuration := range configurations {
		m := make(map[string]interface{})

		m["endpoint_id"] = aws.StringValue(configuration.EndpointId)
		m["weight"] = aws.Int64Value(configuration.Weight)

		out[i] = m
	}

	log.Printf("[DEBUG] Flatten endpoint_configuration: %s", out)
	return out
}

func resourceAwsGlobalAcceleratorEndpointGroupRetrieve(conn *globalaccelerator.GlobalAccelerator, endpointGroupArn string) (*globalaccelerator.EndpointGroup, error) {
	resp, err := conn.DescribeEndpointGroup(&globalaccelerator.DescribeEndpointGroupInput{
		EndpointGroupArn: aws.String(endpointGroupArn),
	})

	if err != nil {
		if isAWSErr(err, globalaccelerator.ErrCodeEndpointGroupNotFoundException, "") {
			return nil, nil
		}
		return nil, err
	}

	return resp.EndpointGroup, nil
}

func resourceAwsGlobalAcceleratorEndpointGroupUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn

	opts := &globalaccelerator.UpdateEndpointGroupInput{
		EndpointGroupArn: aws.String(d.Id()),
	}

	if v, ok := d.GetOk("health_check_interval_seconds"); ok {
		opts.HealthCheckIntervalSeconds = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_path"); ok {
		opts.HealthCheckPath = aws.String(v.(string))
	}

	if v, ok := d.GetOk("health_check_port"); ok {
		opts.HealthCheckPort = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_protocol"); ok {
		opts.HealthCheckProtocol = aws.String(v.(string))
	}

	if v, ok := d.GetOk("threshold_count"); ok {
		opts.ThresholdCount = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("traffic_dial_percentage"); ok {
		opts.TrafficDialPercentage = aws.Float64(v.(float64))
	}

	if v, ok := d.GetOk("endpoint_configuration"); ok {
		opts.EndpointConfigurations = resourceAwsGlobalAcceleratorEndpointGroupExpandEndpointConfigurations(v.([]interface{}))
	} else {
		opts.EndpointConfigurations = []*globalaccelerator.EndpointConfiguration{}
	}

	log.Printf("[DEBUG] Update Global Accelerator endpoint group: %s", opts)

	_, err := conn.UpdateEndpointGroup(opts)
	if err != nil {
		return fmt.Errorf("Error updating Global Accelerator endpoint group: %s", err)
	}

	acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())

	if err != nil {
		return err
	}

	err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)

	if err != nil {
		return err
	}

	return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)

	// Creating an endpoint group triggers the accelerator to change status to InPending
	stateConf := &resource.StateChangeConf{
		Pending: []string{globalaccelerator.AcceleratorStatusInProgress},
		Target:  []string{globalaccelerator.AcceleratorStatusDeployed},
		Refresh: resourceAwsGlobalAcceleratorAcceleratorStateRefreshFunc(conn, acceleratorArn),
		Timeout: 5 * time.Minute,
	}

	log.Printf("[DEBUG] Waiting for Global Accelerator endpoint group (%s) availability", d.Id())
	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for Global Accelerator endpoint group (%s) availability: %s", d.Id(), err)
	}

	return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)
}

func resourceAwsGlobalAcceleratorEndpointGroupDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn

	opts := &globalaccelerator.DeleteEndpointGroupInput{
		EndpointGroupArn: aws.String(d.Id()),
	}

	_, err := conn.DeleteEndpointGroup(opts)
	if err != nil {
		if isAWSErr(err, globalaccelerator.ErrCodeEndpointGroupNotFoundException, "") {
			return nil
		}
		return fmt.Errorf("Error deleting Global Accelerator endpoint group: %s", err)
	}

	acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())

	if err != nil {
		return err
	}

	err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)

	if err != nil {
		return err
	}

	return nil

	// Deleting an endpoint group triggers the accelerator to change status to InPending
	stateConf := &resource.StateChangeConf{
		Pending: []string{globalaccelerator.AcceleratorStatusInProgress},
		Target:  []string{globalaccelerator.AcceleratorStatusDeployed},
		Refresh: resourceAwsGlobalAcceleratorAcceleratorStateRefreshFunc(conn, acceleratorArn),
		Timeout: 5 * time.Minute,
	}

	log.Printf("[DEBUG] Waiting for Global Accelerator endpoint group (%s) deletion", d.Id())
	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for Global Accelerator endpoint group (%s) deletion: %s", d.Id(), err)
	}

	return nil
}
<commit_msg>Removing prematue returns<commit_after>package aws

import (
	"fmt"
	"log"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/globalaccelerator"

	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
)

func resourceAwsGlobalAcceleratorEndpointGroup() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsGlobalAcceleratorEndpointGroupCreate,
		Read:   resourceAwsGlobalAcceleratorEndpointGroupRead,
		Update: resourceAwsGlobalAcceleratorEndpointGroupUpdate,
		Delete: resourceAwsGlobalAcceleratorEndpointGroupDelete,

		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"listener_arn": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"endpoint_group_region": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"health_check_interval_seconds": {
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      30,
				ValidateFunc: validation.IntBetween(10, 30),
			},
			"health_check_path": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  "/",
			},
			"health_check_port": {
				Type:     schema.TypeInt,
				Optional: true,
			},
			"health_check_protocol": {
				Type:     schema.TypeString,
				Optional: true,
				Default:  globalaccelerator.HealthCheckProtocolTcp,
				ValidateFunc: validation.StringInSlice([]string{
					globalaccelerator.HealthCheckProtocolTcp,
					globalaccelerator.HealthCheckProtocolHttp,
					globalaccelerator.HealthCheckProtocolHttps,
				}, false),
			},
			"threshold_count": {
				Type:         schema.TypeInt,
				Optional:     true,
				Default:      3,
				ValidateFunc: validation.IntBetween(1, 10),
			},
			"traffic_dial_percentage": {
				Type:         schema.TypeFloat,
				Optional:     true,
				Default:      100,
				ValidateFunc: validation.IntBetween(0, 100),
			},
			"endpoint_configuration": {
				Type:     schema.TypeSet,
				Optional: true,
				MaxItems: 10,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"endpoint_id": {
							Type:     schema.TypeString,
							Optional: true,
						},
						"weight": {
							Type:     schema.TypeInt,
							Optional: true,
						},
					},
				},
			},
		},
	}
}

func resourceAwsGlobalAcceleratorEndpointGroupCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn
	region := meta.(*AWSClient).region

	opts := &globalaccelerator.CreateEndpointGroupInput{
		ListenerArn:         aws.String(d.Get("listener_arn").(string)),
		IdempotencyToken:    aws.String(resource.UniqueId()),
		EndpointGroupRegion: aws.String(region),
	}

	if v, ok := d.GetOk("endpoint_group_region"); ok {
		opts.EndpointGroupRegion = aws.String(v.(string))
	}

	if v, ok := d.GetOk("health_check_interval_seconds"); ok {
		opts.HealthCheckIntervalSeconds = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_path"); ok {
		opts.HealthCheckPath = aws.String(v.(string))
	}

	if v, ok := d.GetOk("health_check_port"); ok {
		opts.HealthCheckPort = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_protocol"); ok {
		opts.HealthCheckProtocol = aws.String(v.(string))
	}

	if v, ok := d.GetOk("threshold_count"); ok {
		opts.ThresholdCount = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("traffic_dial_percentage"); ok {
		opts.TrafficDialPercentage = aws.Float64(v.(float64))
	}

	if v, ok := d.GetOk("endpoint_configuration"); ok {
		opts.EndpointConfigurations = resourceAwsGlobalAcceleratorEndpointGroupExpandEndpointConfigurations(v.([]interface{}))
	}

	log.Printf("[DEBUG] Create Global Accelerator endpoint group: %s", opts)

	resp, err := conn.CreateEndpointGroup(opts)
	if err != nil {
		return fmt.Errorf("Error creating Global Accelerator endpoint group: %s", err)
	}

	d.SetId(*resp.EndpointGroup.EndpointGroupArn)

	acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())

	if err != nil {
		return err
	}

	err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)

	if err != nil {
		return err
	}

	// Creating an endpoint group triggers the accelerator to change status to InPending
	stateConf := &resource.StateChangeConf{
		Pending: []string{globalaccelerator.AcceleratorStatusInProgress},
		Target:  []string{globalaccelerator.AcceleratorStatusDeployed},
		Refresh: resourceAwsGlobalAcceleratorAcceleratorStateRefreshFunc(conn, acceleratorArn),
		Timeout: 5 * time.Minute,
	}

	log.Printf("[DEBUG] Waiting for Global Accelerator endpoint group (%s) availability", d.Id())
	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for Global Accelerator endpoint group (%s) availability: %s", d.Id(), err)
	}

	return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)
}

func resourceAwsGlobalAcceleratorEndpointGroupRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn

	endpointGroup, err := resourceAwsGlobalAcceleratorEndpointGroupRetrieve(conn, d.Id())

	if err != nil {
		return fmt.Errorf("Error reading Global Accelerator endpoint group: %s", err)
	}

	if endpointGroup == nil {
		log.Printf("[WARN] Global Accelerator endpoint group (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	listenerArn, err := resourceAwsGlobalAcceleratorEndpointGroupParseListenerArn(d.Id())

	if err != nil {
		return err
	}

	d.Set("listener_arn", listenerArn)
	d.Set("endpoint_group_region", endpointGroup.EndpointGroupRegion)
	d.Set("health_check_interval_seconds", endpointGroup.HealthCheckIntervalSeconds)
	d.Set("health_check_path", endpointGroup.HealthCheckPath)
	d.Set("health_check_port", endpointGroup.HealthCheckPort)
	d.Set("health_check_protocol", endpointGroup.HealthCheckProtocol)
	d.Set("threshold_count", endpointGroup.ThresholdCount)
	d.Set("traffic_dial_percentage", endpointGroup.TrafficDialPercentage)
	if err := d.Set("endpoint_configuration", resourceAwsGlobalAcceleratorEndpointGroupFlattenEndpointDescriptions(endpointGroup.EndpointDescriptions)); err != nil {
		return fmt.Errorf("error setting endpoint_configuration: %s", err)
	}

	return nil
}

func resourceAwsGlobalAcceleratorEndpointGroupParseListenerArn(endpointGroupArn string) (string, error) {
	parts := strings.Split(endpointGroupArn, "/")
	if len(parts) < 6 {
		return "", fmt.Errorf("Unable to parse listener ARN from %s", endpointGroupArn)
	}
	return strings.Join(parts[0:4], "/"), nil
}

func resourceAwsGlobalAcceleratorEndpointGroupExpandEndpointConfigurations(configurations []interface{}) []*globalaccelerator.EndpointConfiguration {
	out := make([]*globalaccelerator.EndpointConfiguration, len(configurations))

	for i, raw := range configurations {
		configuration := raw.(map[string]interface{})
		m := globalaccelerator.EndpointConfiguration{}

		m.EndpointId = aws.String(configuration["endpoint_id"].(string))
		m.Weight = aws.Int64(int64(configuration["weight"].(int)))

		out[i] = &m
	}

	log.Printf("[DEBUG] Expand endpoint_configuration: %s", out)
	return out
}

func resourceAwsGlobalAcceleratorEndpointGroupFlattenEndpointDescriptions(configurations []*globalaccelerator.EndpointDescription) []interface{} {
	out := make([]interface{}, len(configurations))

	for i, configuration := range configurations {
		m := make(map[string]interface{})

		m["endpoint_id"] = aws.StringValue(configuration.EndpointId)
		m["weight"] = aws.Int64Value(configuration.Weight)

		out[i] = m
	}

	log.Printf("[DEBUG] Flatten endpoint_configuration: %s", out)
	return out
}

func resourceAwsGlobalAcceleratorEndpointGroupRetrieve(conn *globalaccelerator.GlobalAccelerator, endpointGroupArn string) (*globalaccelerator.EndpointGroup, error) {
	resp, err := conn.DescribeEndpointGroup(&globalaccelerator.DescribeEndpointGroupInput{
		EndpointGroupArn: aws.String(endpointGroupArn),
	})

	if err != nil {
		if isAWSErr(err, globalaccelerator.ErrCodeEndpointGroupNotFoundException, "") {
			return nil, nil
		}
		return nil, err
	}

	return resp.EndpointGroup, nil
}

func resourceAwsGlobalAcceleratorEndpointGroupUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn

	opts := &globalaccelerator.UpdateEndpointGroupInput{
		EndpointGroupArn: aws.String(d.Id()),
	}

	if v, ok := d.GetOk("health_check_interval_seconds"); ok {
		opts.HealthCheckIntervalSeconds = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_path"); ok {
		opts.HealthCheckPath = aws.String(v.(string))
	}

	if v, ok := d.GetOk("health_check_port"); ok {
		opts.HealthCheckPort = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("health_check_protocol"); ok {
		opts.HealthCheckProtocol = aws.String(v.(string))
	}

	if v, ok := d.GetOk("threshold_count"); ok {
		opts.ThresholdCount = aws.Int64(int64(v.(int)))
	}

	if v, ok := d.GetOk("traffic_dial_percentage"); ok {
		opts.TrafficDialPercentage = aws.Float64(v.(float64))
	}

	if v, ok := d.GetOk("endpoint_configuration"); ok {
		opts.EndpointConfigurations = resourceAwsGlobalAcceleratorEndpointGroupExpandEndpointConfigurations(v.([]interface{}))
	} else {
		opts.EndpointConfigurations = []*globalaccelerator.EndpointConfiguration{}
	}

	log.Printf("[DEBUG] Update Global Accelerator endpoint group: %s", opts)

	_, err := conn.UpdateEndpointGroup(opts)
	if err != nil {
		return fmt.Errorf("Error updating Global Accelerator endpoint group: %s", err)
	}

	acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())

	if err != nil {
		return err
	}

	err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)

	if err != nil {
		return err
	}

	// Creating an endpoint group triggers the accelerator to change status to InPending
	stateConf := &resource.StateChangeConf{
		Pending: []string{globalaccelerator.AcceleratorStatusInProgress},
		Target:  []string{globalaccelerator.AcceleratorStatusDeployed},
		Refresh: resourceAwsGlobalAcceleratorAcceleratorStateRefreshFunc(conn, acceleratorArn),
		Timeout: 5 * time.Minute,
	}

	log.Printf("[DEBUG] Waiting for Global Accelerator endpoint group (%s) availability", d.Id())
	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for Global Accelerator endpoint group (%s) availability: %s", d.Id(), err)
	}

	return resourceAwsGlobalAcceleratorEndpointGroupRead(d, meta)
}

func resourceAwsGlobalAcceleratorEndpointGroupDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).globalacceleratorconn

	opts := &globalaccelerator.DeleteEndpointGroupInput{
		EndpointGroupArn: aws.String(d.Id()),
	}

	_, err := conn.DeleteEndpointGroup(opts)
	if err != nil {
		if isAWSErr(err, globalaccelerator.ErrCodeEndpointGroupNotFoundException, "") {
			return nil
		}
		return fmt.Errorf("Error deleting Global Accelerator endpoint group: %s", err)
	}

	acceleratorArn, err := resourceAwsGlobalAcceleratorListenerParseAcceleratorArn(d.Id())

	if err != nil {
		return err
	}

	err = resourceAwsGlobalAcceleratorAcceleratorWaitForState(conn, acceleratorArn)

	if err != nil {
		return err
	}

	// Deleting an endpoint group triggers the accelerator to change status to InPending
	stateConf := &resource.StateChangeConf{
		Pending: []string{globalaccelerator.AcceleratorStatusInProgress},
		Target:  []string{globalaccelerator.AcceleratorStatusDeployed},
		Refresh: resourceAwsGlobalAcceleratorAcceleratorStateRefreshFunc(conn, acceleratorArn),
		Timeout: 5 * time.Minute,
	}

	log.Printf("[DEBUG] Waiting for Global Accelerator endpoint group (%s) deletion", d.Id())
	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf("Error waiting for Global Accelerator endpoint group (%s) deletion: %s", d.Id(), err)
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"log"
	"path/filepath"
	"strings"
)

// Run a migration specified in raw SQL.
//
// Sections of the script can be annotated with a special comment,
// starting with "-- +goose" to specify whether the section should
// be applied during an Up or Down migration
//
// All statements following an Up or Down directive are grouped together
// until another direction directive is found.
func runSQLMigration(db *sql.DB, script string, v int64, direction bool) error {

	txn, err := db.Begin()
	if err != nil {
		log.Fatal("db.Begin:", err)
	}

	f, err := ioutil.ReadFile(script)
	if err != nil {
		log.Fatal(err)
	}

	// track the count of each section
	// so we can diagnose scripts with no annotations
	upSections := 0
	downSections := 0

	// ensure we don't apply a query until we're sure it's going
	// in the direction we're interested in
	directionIsActive := false

	// find each statement, checking annotations for up/down direction
	// and execute each of them in the current transaction
	stmts := strings.Split(string(f), ";")

	for _, query := range stmts {

		query = strings.TrimSpace(query)

		if strings.HasPrefix(query, "-- +goose Up") {
			directionIsActive = direction == true
			upSections++
		} else if strings.HasPrefix(query, "-- +goose Down") {
			directionIsActive = direction == false
			downSections++
		}

		if !directionIsActive || query == "" {
			continue
		}

		if _, err = txn.Exec(query); err != nil {
			txn.Rollback()
			log.Fatalf("FAIL %s (%v), quitting migration.", filepath.Base(script), err)
			return err
		}
	}

	if err = finalizeMigration(txn, direction, v); err != nil {
		log.Fatalf("error finalizing migration %s, quitting. (%v)", filepath.Base(script), err)
	}

	if upSections == 0 && downSections == 0 {
		log.Printf(`WARNING: no Up/Down annotations found in %s, so no statements were executed.
			See https://bitbucket.org/liamstask/goose/overview for details.`,
			filepath.Base(script))
	}

	return nil
}

// Update the version table for the given migration,
// and finalize the transaction.
func finalizeMigration(txn *sql.Tx, direction bool, v int64) error {

	// XXX: drop goose_db_version table on some minimum version number?
	versionStmt := fmt.Sprintf("INSERT INTO goose_db_version (version_id, is_applied) VALUES (%d, %t);", v, direction)
	if _, err := txn.Exec(versionStmt); err != nil {
		txn.Rollback()
		return err
	}

	return txn.Commit()
}
<commit_msg>migration sql: error out if no annotations are found, rather than marking the migration as having run successfully.<commit_after>package main

import (
	"database/sql"
	"fmt"
	"io/ioutil"
	"log"
	"path/filepath"
	"strings"
)

// Run a migration specified in raw SQL.
//
// Sections of the script can be annotated with a special comment,
// starting with "-- +goose" to specify whether the section should
// be applied during an Up or Down migration
//
// All statements following an Up or Down directive are grouped together
// until another direction directive is found.
func runSQLMigration(db *sql.DB, script string, v int64, direction bool) error {

	txn, err := db.Begin()
	if err != nil {
		log.Fatal("db.Begin:", err)
	}

	f, err := ioutil.ReadFile(script)
	if err != nil {
		log.Fatal(err)
	}

	// track the count of each section
	// so we can diagnose scripts with no annotations
	upSections := 0
	downSections := 0

	// ensure we don't apply a query until we're sure it's going
	// in the direction we're interested in
	directionIsActive := false

	// find each statement, checking annotations for up/down direction
	// and execute each of them in the current transaction
	stmts := strings.Split(string(f), ";")

	for _, query := range stmts {

		query = strings.TrimSpace(query)

		if strings.HasPrefix(query, "-- +goose Up") {
			directionIsActive = direction == true
			upSections++
		} else if strings.HasPrefix(query, "-- +goose Down") {
			directionIsActive = direction == false
			downSections++
		}

		if !directionIsActive || query == "" {
			continue
		}

		if _, err = txn.Exec(query); err != nil {
			txn.Rollback()
			log.Fatalf("FAIL %s (%v), quitting migration.", filepath.Base(script), err)
			return err
		}
	}

	if upSections == 0 && downSections == 0 {
		txn.Rollback()
		log.Fatalf(`ERROR: no Up/Down annotations found in %s, so no statements were executed.
			See https://bitbucket.org/liamstask/goose/overview for details.`,
			filepath.Base(script))
	}

	if err = finalizeMigration(txn, direction, v); err != nil {
		log.Fatalf("error finalizing migration %s, quitting. (%v)", filepath.Base(script), err)
	}

	return nil
}

// Update the version table for the given migration,
// and finalize the transaction.
func finalizeMigration(txn *sql.Tx, direction bool, v int64) error {

	// XXX: drop goose_db_version table on some minimum version number?
	versionStmt := fmt.Sprintf("INSERT INTO goose_db_version (version_id, is_applied) VALUES (%d, %t);", v, direction)
	if _, err := txn.Exec(versionStmt); err != nil {
		txn.Rollback()
		return err
	}

	return txn.Commit()
}
<|endoftext|>