<commit_before>package glock

import (
	"runtime"
	"sort"
	"sync"
	"time"
)

type (
	// MockClock is an implementation of Clock that can be moved forward in time
	// in increments for testing code that relies on timeouts or other time-sensitive
	// constructs.
	MockClock struct {
		fakeTime   time.Time
		triggers   mockTriggers
		tickers    mockTickers
		afterArgs  []time.Duration
		tickerArgs []time.Duration
		afterLock  sync.RWMutex
		tickerLock sync.Mutex
	}

	mockTrigger struct {
		trigger time.Time
		ch      chan time.Time
	}

	mockTriggers []*mockTrigger
	mockTickers  []*mockTicker
)

// NewMockClock creates a new MockClock with the internal time set
// to time.Now()
func NewMockClock() *MockClock {
	return NewMockClockAt(time.Now())
}

// NewMockClockAt creates a new MockClick with the internal time set
// to the provided time.
func NewMockClockAt(now time.Time) *MockClock {
	return &MockClock{
		fakeTime:   now,
		tickers:    make([]*mockTicker, 0),
		afterArgs:  make([]time.Duration, 0),
		tickerArgs: make([]time.Duration, 0),
	}
}

func (mc *MockClock) processTriggers() {
	mc.afterLock.Lock()
	defer mc.afterLock.Unlock()

	now := mc.Now()
	triggered := 0
	for _, trigger := range mc.triggers {
		if trigger.trigger.Before(now) || trigger.trigger.Equal(now) {
			trigger.ch <- trigger.trigger
			triggered++
		}
	}

	mc.triggers = mc.triggers[triggered:]
}

func (mc *MockClock) processTickers() {
	mc.tickerLock.Lock()
	defer mc.tickerLock.Unlock()

	now := mc.Now()
	for _, ticker := range mc.tickers {
		ticker.process(now)
	}
}

// SetCurrent sets the internal MockClock time to the supplied time.
func (mc *MockClock) SetCurrent(current time.Time) {
	mc.fakeTime = current
}

// Advance will advance the internal MockClock time by the supplied time.
func (mc *MockClock) Advance(duration time.Duration) {
	mc.fakeTime = mc.fakeTime.Add(duration)
	mc.processTriggers()
	mc.processTickers()
}

// BlockingAdvance will call Advance but only after there is another routine
// which is blocking on the channel result of a call to After.
func (mc *MockClock) BlockingAdvance(duration time.Duration) {
	for mc.BlockedOnAfter() == 0 {
		runtime.Gosched()
	}

	mc.Advance(duration)
}

// Now returns the current time internal to the MockClock
func (mc *MockClock) Now() time.Time {
	return mc.fakeTime
}

// After returns a channel that will be sent the current internal MockClock
// time once the MockClock's internal time is at or past the provided duration
func (mc *MockClock) After(duration time.Duration) <-chan time.Time {
	mc.afterLock.Lock()
	defer mc.afterLock.Unlock()

	trigger := &mockTrigger{
		trigger: mc.fakeTime.Add(duration),
		ch:      make(chan time.Time, 1),
	}

	mc.triggers = append(mc.triggers, trigger)
	sort.Sort(mc.triggers)
	mc.afterArgs = append(mc.afterArgs, duration)

	return trigger.ch
}

// BlockedOnAfter returns the number of calls to After that are blocked
// waiting for a call to Advance to trigger them.
func (mc *MockClock) BlockedOnAfter() int {
	mc.afterLock.RLock()
	defer mc.afterLock.RUnlock()

	return len(mc.triggers)
}

// Sleep will block until the internal MockClock time is at or past the
// provided duration
func (mc *MockClock) Sleep(duration time.Duration) {
	<-mc.After(duration)
}

// GetAfterArgs returns the duration of each call to After in the
// same order as they were called. The list is cleared each time
// GetAfterArgs is called.
func (mc *MockClock) GetAfterArgs() []time.Duration {
	mc.afterLock.Lock()
	defer mc.afterLock.Unlock()

	args := mc.afterArgs
	mc.afterArgs = mc.afterArgs[:0]
	return args
}

// GetTickerArgs returns the duration of each call to create a new
// ticker in the same order as they were called. The list is cleared
// each time GetTickerArgs is called.
func (mc *MockClock) GetTickerArgs() []time.Duration {
	mc.tickerLock.Lock()
	defer mc.tickerLock.Unlock()

	args := mc.tickerArgs
	mc.tickerArgs = mc.tickerArgs[:0]
	return args
}

type mockTicker struct {
	clock        *MockClock
	duration     time.Duration
	started      time.Time
	nextTick     time.Time
	processLock  sync.Mutex
	processQueue []time.Time
	writeLock    sync.Mutex
	writing      bool
	ch           chan time.Time
	stopped      bool
}

// NewTicker creates a new Ticker tied to the internal MockClock time that ticks
// at intervals similar to time.NewTicker().  It will also skip or drop ticks
// for slow readers similar to time.NewTicker() as well.
func (mc *MockClock) NewTicker(duration time.Duration) Ticker {
	if duration == 0 {
		panic("duration cannot be 0")
	}

	now := mc.Now()

	ft := &mockTicker{
		clock:        mc,
		duration:     duration,
		started:      now,
		nextTick:     now.Add(duration),
		processQueue: make([]time.Time, 0),
		ch:           make(chan time.Time),
	}

	mc.tickerLock.Lock()
	mc.tickers = append(mc.tickers, ft)
	mc.tickerArgs = append(mc.tickerArgs, duration)
	mc.tickerLock.Unlock()

	return ft
}

func (mt *mockTicker) process(now time.Time) {
	if mt.stopped {
		return
	}

	mt.processLock.Lock()
	mt.processQueue = append(mt.processQueue, now)
	mt.processLock.Unlock()

	if !mt.writing && (mt.nextTick.Before(now) || mt.nextTick.Equal(now)) {
		mt.writeLock.Lock()

		mt.writing = true
		go func() {
			defer mt.writeLock.Unlock()

			for {
				mt.processLock.Lock()
				if len(mt.processQueue) == 0 {
					mt.processLock.Unlock()
					break
				}

				procTime := mt.processQueue[0]
				mt.processQueue = mt.processQueue[1:]

				mt.processLock.Unlock()

				if mt.nextTick.After(procTime) {
					continue
				}

				mt.ch <- mt.nextTick

				durationMod := procTime.Sub(mt.started) % mt.duration

				if durationMod == 0 {
					mt.nextTick = procTime.Add(mt.duration)
				} else if procTime.Sub(mt.nextTick) > mt.duration {
					mt.nextTick = procTime.Add(mt.duration - durationMod)
				} else {
					mt.nextTick = mt.nextTick.Add(mt.duration)
				}
			}

			mt.writing = false
		}()
	}
}

// Chan returns a channel which will receive the MockClock's internal time
// at the interval given when creating the ticker.
func (mt *mockTicker) Chan() <-chan time.Time {
	return mt.ch
}

// Stop will stop the ticker from ticking
func (mt *mockTicker) Stop() {
	mt.stopped = true
}

//
// Trigger Sort

func (mt mockTriggers) Len() int {
	return len(mt)
}

func (mt mockTriggers) Less(i, j int) bool {
	return mt[i].trigger.Before(mt[j].trigger)
}

func (mt mockTriggers) Swap(i, j int) {
	mt[i], mt[j] = mt[j], mt[i]
}
<commit_msg>Add a lock around fakeTime.<commit_after>package glock

import (
	"runtime"
	"sort"
	"sync"
	"time"
)

type (
	// MockClock is an implementation of Clock that can be moved forward in time
	// in increments for testing code that relies on timeouts or other time-sensitive
	// constructs.
	MockClock struct {
		fakeTime   time.Time
		triggers   mockTriggers
		tickers    mockTickers
		afterArgs  []time.Duration
		tickerArgs []time.Duration
		nowLock    sync.RWMutex
		afterLock  sync.RWMutex
		tickerLock sync.Mutex
	}

	mockTrigger struct {
		trigger time.Time
		ch      chan time.Time
	}

	mockTriggers []*mockTrigger
	mockTickers  []*mockTicker
)

// NewMockClock creates a new MockClock with the internal time set
// to time.Now()
func NewMockClock() *MockClock {
	return NewMockClockAt(time.Now())
}

// NewMockClockAt creates a new MockClick with the internal time set
// to the provided time.
func NewMockClockAt(now time.Time) *MockClock {
	return &MockClock{
		fakeTime:   now,
		tickers:    make([]*mockTicker, 0),
		afterArgs:  make([]time.Duration, 0),
		tickerArgs: make([]time.Duration, 0),
	}
}

func (mc *MockClock) processTriggers() {
	mc.afterLock.Lock()
	defer mc.afterLock.Unlock()

	now := mc.Now()

	triggered := 0
	for _, trigger := range mc.triggers {
		if trigger.trigger.Before(now) || trigger.trigger.Equal(now) {
			trigger.ch <- trigger.trigger
			triggered++
		}
	}

	mc.triggers = mc.triggers[triggered:]
}

func (mc *MockClock) processTickers() {
	mc.tickerLock.Lock()
	defer mc.tickerLock.Unlock()

	now := mc.Now()
	for _, ticker := range mc.tickers {
		ticker.process(now)
	}
}

// SetCurrent sets the internal MockClock time to the supplied time.
func (mc *MockClock) SetCurrent(current time.Time) {
	mc.nowLock.Lock()
	defer mc.nowLock.Unlock()

	mc.fakeTime = current
}

// Advance will advance the internal MockClock time by the supplied time.
func (mc *MockClock) Advance(duration time.Duration) {
	mc.nowLock.Lock()
	mc.fakeTime = mc.fakeTime.Add(duration)
	mc.nowLock.Unlock()

	mc.processTriggers()
	mc.processTickers()
}

// BlockingAdvance will call Advance but only after there is another routine
// which is blocking on the channel result of a call to After.
func (mc *MockClock) BlockingAdvance(duration time.Duration) {
	for mc.BlockedOnAfter() == 0 {
		runtime.Gosched()
	}

	mc.Advance(duration)
}

// Now returns the current time internal to the MockClock
func (mc *MockClock) Now() time.Time {
	return mc.fakeTime
}

// After returns a channel that will be sent the current internal MockClock
// time once the MockClock's internal time is at or past the provided duration
func (mc *MockClock) After(duration time.Duration) <-chan time.Time {
	mc.nowLock.RLock()
	triggerTime := mc.fakeTime.Add(duration)
	mc.nowLock.RUnlock()

	mc.afterLock.Lock()
	defer mc.afterLock.Unlock()

	trigger := &mockTrigger{
		trigger: triggerTime,
		ch:      make(chan time.Time, 1),
	}

	mc.triggers = append(mc.triggers, trigger)
	sort.Sort(mc.triggers)
	mc.afterArgs = append(mc.afterArgs, duration)
	return trigger.ch
}

// BlockedOnAfter returns the number of calls to After that are blocked
// waiting for a call to Advance to trigger them.
func (mc *MockClock) BlockedOnAfter() int {
	mc.afterLock.RLock()
	defer mc.afterLock.RUnlock()

	return len(mc.triggers)
}

// Sleep will block until the internal MockClock time is at or past the
// provided duration
func (mc *MockClock) Sleep(duration time.Duration) {
	<-mc.After(duration)
}

// GetAfterArgs returns the duration of each call to After in the
// same order as they were called. The list is cleared each time
// GetAfterArgs is called.
func (mc *MockClock) GetAfterArgs() []time.Duration {
	mc.afterLock.Lock()
	defer mc.afterLock.Unlock()

	args := mc.afterArgs
	mc.afterArgs = mc.afterArgs[:0]
	return args
}

// GetTickerArgs returns the duration of each call to create a new
// ticker in the same order as they were called. The list is cleared
// each time GetTickerArgs is called.
func (mc *MockClock) GetTickerArgs() []time.Duration {
	mc.tickerLock.Lock()
	defer mc.tickerLock.Unlock()

	args := mc.tickerArgs
	mc.tickerArgs = mc.tickerArgs[:0]
	return args
}

type mockTicker struct {
	clock        *MockClock
	duration     time.Duration
	started      time.Time
	nextTick     time.Time
	processLock  sync.Mutex
	processQueue []time.Time
	writeLock    sync.Mutex
	writing      bool
	ch           chan time.Time
	stopped      bool
}

// NewTicker creates a new Ticker tied to the internal MockClock time that ticks
// at intervals similar to time.NewTicker().  It will also skip or drop ticks
// for slow readers similar to time.NewTicker() as well.
func (mc *MockClock) NewTicker(duration time.Duration) Ticker {
	if duration == 0 {
		panic("duration cannot be 0")
	}

	now := mc.Now()

	ft := &mockTicker{
		clock:        mc,
		duration:     duration,
		started:      now,
		nextTick:     now.Add(duration),
		processQueue: make([]time.Time, 0),
		ch:           make(chan time.Time),
	}

	mc.tickerLock.Lock()
	mc.tickers = append(mc.tickers, ft)
	mc.tickerArgs = append(mc.tickerArgs, duration)
	mc.tickerLock.Unlock()

	return ft
}

func (mt *mockTicker) process(now time.Time) {
	if mt.stopped {
		return
	}

	mt.processLock.Lock()
	mt.processQueue = append(mt.processQueue, now)
	mt.processLock.Unlock()

	if !mt.writing && (mt.nextTick.Before(now) || mt.nextTick.Equal(now)) {
		mt.writeLock.Lock()

		mt.writing = true
		go func() {
			defer mt.writeLock.Unlock()

			for {
				mt.processLock.Lock()
				if len(mt.processQueue) == 0 {
					mt.processLock.Unlock()
					break
				}

				procTime := mt.processQueue[0]
				mt.processQueue = mt.processQueue[1:]

				mt.processLock.Unlock()

				if mt.nextTick.After(procTime) {
					continue
				}

				mt.ch <- mt.nextTick

				durationMod := procTime.Sub(mt.started) % mt.duration

				if durationMod == 0 {
					mt.nextTick = procTime.Add(mt.duration)
				} else if procTime.Sub(mt.nextTick) > mt.duration {
					mt.nextTick = procTime.Add(mt.duration - durationMod)
				} else {
					mt.nextTick = mt.nextTick.Add(mt.duration)
				}
			}

			mt.writing = false
		}()
	}
}

// Chan returns a channel which will receive the MockClock's internal time
// at the interval given when creating the ticker.
func (mt *mockTicker) Chan() <-chan time.Time {
	return mt.ch
}

// Stop will stop the ticker from ticking
func (mt *mockTicker) Stop() {
	mt.stopped = true
}

//
// Trigger Sort

func (mt mockTriggers) Len() int {
	return len(mt)
}

func (mt mockTriggers) Less(i, j int) bool {
	return mt[i].trigger.Before(mt[j].trigger)
}

func (mt mockTriggers) Swap(i, j int) {
	mt[i], mt[j] = mt[j], mt[i]
}
<|endoftext|>


<commit_before>package processors

import (
	"net/http"
	"net/url"
	"time"
)

var (
	// DefaultTimeout is the default timeout in seconds and is applied to all the requests contained in the batch
	// (unless the batch request specifies a different value through the `x-rrp-timeout` header)
	DefaultTimeout time.Duration
	// DefaultClient is an instance of the custom http.Client created with with the DefaultTimeout
	// (The returned client has a more leniant redirect policy always URL encoding/escaping the location prior to redirect)
	DefaultClient *http.Client
)

func init() {
	// http.Client is safe for concurrent use by multiple goroutines and for efficiency should only be created once and re-used
	DefaultTimeout = time.Duration(20) * time.Second // Default timeout is 20 seconds, TODO should be configurable e.j flag
	DefaultClient = CreateClient(DefaultTimeout)
}

// CreateClient is used to instantiate a custom http.Client with the specified timeout
// The returned client has a more leniant redirect policy always URL encoding/escaping the location prior to redirect
// TODO keep a cache of most commonly used clients so we can reuse them in the same way as we do for `DefaultClient`
func CreateClient(timeout time.Duration) *http.Client {
	return &http.Client{Timeout: timeout,
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			queryString := ""
			if len(req.URL.Query()) > 0 {
				queryString = "?" + req.URL.Query().Encode()
			}
			escapedURL, err := url.Parse(req.URL.Scheme + "://" + req.URL.Host + req.URL.EscapedPath() + queryString)
			if err != nil {
				req.URL = escapedURL
			}
			return err
		},
	}
}
<commit_msg>refactor - custom redirect policy<commit_after>package processors

import (
	"net/http"
	"net/url"
	"time"
)

var (
	// DefaultTimeout is the default timeout duration specified in seconds
	DefaultTimeout time.Duration
	// DefaultClient is an instance of the custom http.Client created with with the DefaultTimeout
	// (The returned client has a more leniant redirect policy always URL encoding/escaping the location prior to redirect)
	DefaultClient *http.Client
)

func init() {
	// http.Client is safe for concurrent use by multiple goroutines and for efficiency should only be created once and re-used
	DefaultTimeout = time.Duration(20) * time.Second // Default timeout is 20 seconds, TODO should be configurable e.g. flag
	DefaultClient = CreateClient(DefaultTimeout)
}

// CreateClient is used to instantiate a custom http.Client with the specified timeout
// The returned client has a more leniant redirect policy always URL encoding/escaping the location prior to redirect
// TODO keep a cache of most commonly used clients so we can reuse them in the same way as we do for `DefaultClient`
func CreateClient(timeout time.Duration) *http.Client {
	return &http.Client{Timeout: timeout,
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			queryString := ""
			if len(req.URL.Query()) > 0 {
				queryString = "?" + req.URL.Query().Encode()
			}
			escapedURL, err := url.Parse(req.URL.Scheme + "://" + req.URL.Host + req.URL.EscapedPath() + queryString)
			if err != nil {
				req.URL = escapedURL
			}
			return err
		},
	}
}
<|endoftext|>


<commit_before>package factorlib

import (
	"github.com/randall77/factorlib/big"
	"github.com/randall77/factorlib/linear"
	"math/rand"
	"log"
)

func init() {
	factorizers["mpqs"] = mpqs
}

// mpqs = Multiple Polynomial Quadratic Sieve
//
// define f(x) = (ax+b)^2 - n
//
// f(x) = a^2x^2 + 2abx+b^2-n
//      = a(ax^2+2bx+c)        where c=(b^2-n)/a
//
// We choose a to be a product of primes in the factor base.
// We choose b such that b^2==n mod a so the division for computing c works.
//
// Then we sieve ax^2+2bx+c to find x such that ax^2+2bx+c factors over
// the factor base.
//
// We sieve around x0 = (sqrt(n)-b)/a, because that is where f(x) is small.
//
// How do we choose a?  For larger a we can extract a larger known
// factor from f(x).  But a larger a also mean f(x) grows faster as x
// diverges from x0.  Pick a so that f(x0+m)/a is minimal when sieving
// [-m,m].

// f(x0+m)/a = (a^2(x0+m)^2 + 2ab(x0+m) + b^2-n)/a
//           = a(x0+m)^2 + 2b(x0+m) + c
//           = ax0^2+2ax0m+am^2+2bx0+2bm+c
//           = ax0^2+2bx0+c + am^2+2ax0m+2bm
//           = 0 + (am+2ax0+2b)m
//           = (am + 2sqrt(n) - 2b + 2b) m
//           = (am + 2sqrt(n)) m
// choose a <= 2sqrt(n)/m, after that f(x0+m)/a starts growing linearly with a.

func mpqs(n big.Int, rnd *rand.Rand) []big.Int {
	// mpqs does not work for powers of a single prime.  Check that first.
	if f := primepower(n, rnd); f != nil {
		return f
	}

	// Pick a factor base
	fb, a := makeFactorBase(n)
	if a != 0 {
		return []big.Int{big.Int64(a), n.Div64(a)}
	}

	maxp := fb[len(fb)-1]

	// Figure out maximum possible a we want.
	amax := n.SqrtCeil().Lsh(1).Div64(sieverange)
	// Point to stop adding more factors to a.
	// It is ok if a is a bit small.
	amin := amax.Div64(maxp)

	// matrix is used to do gaussian elimination on mod 2 exponents.
	m := linear.NewMatrix(uint(len(fb)))

	// pair up large primes that we find using this table
	type largerecord struct {
		x big.Int
		f []uint
	}
	largeprimes := map[int64]largerecord{}

	for {
		// Pick an a.  Use a random product of factor base primes
		// that multiply to at least amax.
		af := map[int64]uint{}
		a := big.One
		for a.Cmp(amin) < 0 {
			f := int64(1+rand.Intn(len(fb)-1))
			af[f] += 1
			a = a.Mul64(fb[f])
		}
		log.Printf("a=%d af=%v amin=%d amax=%d\n", a, af, amin, amax)

		// Pick b = sqrt(n) mod a
		var pp []primePower
		for i, k := range af {
			pp = append(pp, primePower{fb[i],k})
		}
		b := bigSqrtModN(n.Mod(a), pp, rnd)

		// Set c = (b^2-n)/a
		c := b.Square().Sub(n).Div(a)

		// function to process sieve results
		fn := func(x big.Int, factors []uint, remainder int64) []big.Int {
			_ = m
			_ = largeprimes
			return nil
		}

		x0 := n.SqrtCeil().Sub(b).Div(a)
		r := sievesmooth2(a, b.Lsh(1), c, fb, rnd, x0, fn)
		if r != nil {
			return r
		}
	}
	return nil
}

type byInt64Value []int64

func (a byInt64Value) Len() int           { return len(a) }
func (a byInt64Value) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byInt64Value) Less(i, j int) bool { return a[i] < a[j] }
<commit_msg>MPQS now working.<commit_after>package factorlib

import (
	"github.com/randall77/factorlib/big"
	"github.com/randall77/factorlib/linear"
	"math/rand"
	"log"
)

func init() {
	factorizers["mpqs"] = mpqs
}

// mpqs = Multiple Polynomial Quadratic Sieve
//
// define f(x) = (ax+b)^2 - n
//
// f(x) = a^2x^2 + 2abx+b^2-n
//      = a(ax^2+2bx+c)        where c=(b^2-n)/a
//
// We choose a to be a product of primes in the factor base.
// We choose b such that b^2==n mod a so the division for computing c works.
//
// Then we sieve ax^2+2bx+c to find x such that ax^2+2bx+c factors over
// the factor base.
//
// We sieve around x0 = (sqrt(n)-b)/a, because that is where f(x) is small.
//
// How do we choose a?  For larger a we can extract a larger known
// factor from f(x).  But a larger a also mean f(x) grows faster as x
// diverges from x0.  Pick a so that f(x0+m)/a is minimal when sieving
// [-m,m].

// f(x0+m)/a = (a^2(x0+m)^2 + 2ab(x0+m) + b^2-n)/a
//           = a(x0+m)^2 + 2b(x0+m) + c
//           = ax0^2+2ax0m+am^2+2bx0+2bm+c
//           = ax0^2+2bx0+c + am^2+2ax0m+2bm
//           = 0 + (am+2ax0+2b)m
//           = (am + 2sqrt(n) - 2b + 2b) m
//           = (am + 2sqrt(n)) m
// choose a <= 2sqrt(n)/m, after that f(x0+m)/a starts growing linearly with a.

func mpqs(n big.Int, rnd *rand.Rand) []big.Int {
	// mpqs does not work for powers of a single prime.  Check that first.
	if f := primepower(n, rnd); f != nil {
		return f
	}

	// Pick a factor base
	fb, a := makeFactorBase(n)
	if a != 0 {
		return []big.Int{big.Int64(a), n.Div64(a)}
	}

	maxp := fb[len(fb)-1]

	// Figure out maximum possible a we want.
	amax := n.SqrtCeil().Lsh(1).Div64(sieverange)
	// Point to stop adding more factors to a.
	// It is ok if a is a bit small.
	amin := amax.Div64(maxp)

	// matrix is used to do gaussian elimination on mod 2 exponents.
	m := linear.NewMatrix(uint(len(fb)))

	// pair up large primes that we find using this table
	type largerecord struct {
		x big.Int
		f []uint
	}
	largeprimes := map[int64]largerecord{}

	for {
		// Pick an a.  Use a random product of factor base primes
		// that multiply to at least amin.
		af := map[uint]uint{}
		a := big.One
		for a.Cmp(amin) < 0 {
			f := uint(1+rand.Intn(len(fb)-1))
			af[f] += 1
			a = a.Mul64(fb[f])
		}

		// Pick b = sqrt(n) mod a
		var pp []primePower
		for i, k := range af {
			pp = append(pp, primePower{fb[i],k})
		}
		b := bigSqrtModN(n.Mod(a), pp, rnd)

		// Set c = (b^2-n)/a
		c := b.Square().Sub(n).Div(a)

		// function to process sieve results
		fn := func(x big.Int, factors []uint, remainder int64) []big.Int {
			/*
			fmt.Printf("%d*%d^2+%d*%d+%d=%d=", a, x, b, x, c, a.Mul(x).Add(b).Mul(x).Add(c))
			for i, f := range factors {
				if i != 0 {
					fmt.Printf("·")
				}
				fmt.Printf("%d", fb[f])
			}
			if remainder != 1 {
				fmt.Printf("·%d", remainder)
			}
			fmt.Println()
			*/
			for f, k := range af {
				for i := uint(0); i < k; i++ {
					factors = append(factors, f)
				}
			}
			x = a.Mul(x).Add(b)
			if remainder != 1 {
				// try to find another record with the same largeprime
				lr, ok := largeprimes[remainder]
				if !ok {
					// haven't seen this large prime yet.  Save record for later
					largeprimes[remainder] = largerecord{x, factors}
					return nil
				}
				// combine current equation with other largeprime equation
				// x1^2 === prod(f1) * largeprime
				// x2^2 === prod(f2) * largeprime
				//fmt.Printf("  largeprime %d match\n", remainder)
				x = x.Mul(lr.x).Mod(n).Mul(big.Int64(remainder).ModInv(n)).Mod(n) // TODO: could remainder divide n?
				factors = append(factors, lr.f...)
			}

			// Add equation to the matrix
			idlist := m.AddRow(factors, eqn{x, factors})
			if idlist == nil {
				if m.Rows()%100 == 0 {
					log.Printf("%d/%d falsepos=%d largeprimes=%d\n", m.Rows(), len(fb), falsepos, len(largeprimes))
					falsepos = 0
				}
				return nil
			}

			// We found a set of equations with all even powers.
			// Compute a and b where a^2 === b^2 mod n
			a := big.One
			b := big.One
			odd := make([]bool, len(fb))
			for _, id := range idlist {
				e := id.(eqn)
				a = a.Mul(e.x).Mod(n)
				for _, i := range e.f {
					if !odd[i] {
						// first occurrence of this factor
						odd[i] = true
						continue
					}
					// second occurrence of this factor
					b = b.Mul64(fb[i]).Mod(n)
					odd[i] = false
				}
			}
			for _, o := range odd {
				if o {
					panic("gauss elim failed")
				}
			}

			if a.Cmp(b) == 0 {
				// trivial equation, ignore it
				log.Println("triv A")
				return nil
			}
			if a.Add(b).Cmp(n) == 0 {
				// trivial equation, ignore it
				log.Println("triv B")
				return nil
			}

			r := a.Add(b).GCD(n)
			return []big.Int{r, n.Div(r)}
		}
		x0 := n.SqrtCeil().Sub(b).Div(a)
		r := sievesmooth2(a, b.Lsh(1), c, fb, rnd, x0.Sub64(sieverange/2), fn)
		if r != nil {
			return r
		}
	}
	return nil
}

type byInt64Value []int64

func (a byInt64Value) Len() int           { return len(a) }
func (a byInt64Value) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byInt64Value) Less(i, j int) bool { return a[i] < a[j] }
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
)

// NodeVersion is the current node version
var NodeVersion = "?"

// RunScript runs some node code
func (p *Plugins) RunScript(script string) (cmd *exec.Cmd, done func()) {
	useTmpFile := true
	cacheTmp := filepath.Join(CacheHome, "tmp")
	os.MkdirAll(cacheTmp, 0755)
	f, err := ioutil.TempFile(cacheTmp, "heroku-script-")
	if err != nil {
		useTmpFile = false
		LogIfError(err)
	}
	defer f.Close()
	if _, err := f.WriteString(script); err != nil {
		useTmpFile = false
		LogIfError(err)
	}
	if useTmpFile {
		cmd = exec.Command(nodeBinPath(), f.Name())
	} else {
		cmd = exec.Command(nodeBinPath(), "-e", script)
	}
	cmd.Env = append([]string{"NODE_PATH=" + p.modulesPath()}, os.Environ()...)
	return cmd, func() {
		if f != nil {
			os.Remove(f.Name())
		}
	}
}

func nodeBinPath() string {
	b := os.Getenv("HEROKU_NODE_PATH")
	ext := ""
	if runtime.GOOS == WINDOWS {
		ext = ".exe"
	}
	if b == "" {
		b = filepath.Join(AppDir, "lib", "node"+ext)
	}
	if exists, _ := FileExists(b); !exists {
		var err error
		Debugf("node not found in %s. Using node from PATH\n", b)
		b, err = exec.LookPath("node" + ext)
		must(err)
	}
	return b
}

func (p *Plugins) modulesPath() string {
	return filepath.Join(p.Path, "node_modules")
}
<commit_msg>fix node running when script file does not work<commit_after>package main

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
)

// NodeVersion is the current node version
var NodeVersion = "?"

// RunScript runs some node code
func (p *Plugins) RunScript(script string) (cmd *exec.Cmd, done func()) {
	cacheTmp := filepath.Join(CacheHome, "tmp")
	os.MkdirAll(cacheTmp, 0755)
	f, err := ioutil.TempFile(cacheTmp, "heroku-script-")
	if err != nil {
		LogIfError(err)
	}
	if f != nil {
		defer f.Close()
		if _, err := f.WriteString(script); err != nil {
			LogIfError(err)
		}
		cmd = exec.Command(nodeBinPath(), f.Name())
	} else {
		cmd = exec.Command(nodeBinPath(), "-e", script)
	}
	cmd.Env = append([]string{"NODE_PATH=" + p.modulesPath()}, os.Environ()...)
	return cmd, func() {
		if f != nil {
			os.Remove(f.Name())
		}
	}
}

func nodeBinPath() string {
	b := os.Getenv("HEROKU_NODE_PATH")
	ext := ""
	if runtime.GOOS == WINDOWS {
		ext = ".exe"
	}
	if b == "" {
		b = filepath.Join(AppDir, "lib", "node"+ext)
	}
	if exists, _ := FileExists(b); !exists {
		var err error
		Debugf("node not found in %s. Using node from PATH\n", b)
		b, err = exec.LookPath("node" + ext)
		must(err)
	}
	return b
}

func (p *Plugins) modulesPath() string {
	return filepath.Join(p.Path, "node_modules")
}
<|endoftext|>


<commit_before>package riak

import (
	"fmt"
	"net"
	"time"
)

// Constants identifying Node state
const (
	nodeCreated state = iota
	nodeRunning
	nodeHealthChecking
	nodeShuttingDown
	nodeShutdown
	nodeError
)

// NodeOptions defines the RemoteAddress and operational configuration for connections to a Riak KV
// instance
type NodeOptions struct {
	RemoteAddress       string
	MinConnections      uint16
	MaxConnections      uint16
	IdleTimeout         time.Duration
	ConnectTimeout      time.Duration
	RequestTimeout      time.Duration
	HealthCheckInterval time.Duration
	HealthCheckBuilder  CommandBuilder
	AuthOptions         *AuthOptions
}

// Node is a struct that contains all of the information needed to connect and maintain connections
// with a Riak KV instance
type Node struct {
	addr                *net.TCPAddr
	healthCheckInterval time.Duration
	healthCheckBuilder  CommandBuilder
	authOptions         *AuthOptions
	stopChan            chan struct{}
	cm                  *connectionManager
	stateData
}

var defaultNodeOptions = &NodeOptions{
	RemoteAddress:  defaultRemoteAddress,
	MinConnections: defaultMinConnections,
	MaxConnections: defaultMaxConnections,
	IdleTimeout:    defaultIdleTimeout,
	ConnectTimeout: defaultConnectTimeout,
	RequestTimeout: defaultRequestTimeout,
}

// NewNode is a factory function that takes a NodeOptions struct and returns a Node struct
func NewNode(options *NodeOptions) (*Node, error) {
	if options == nil {
		options = defaultNodeOptions
	}
	if options.RemoteAddress == "" {
		options.RemoteAddress = defaultRemoteAddress
	}
	if options.HealthCheckInterval == 0 {
		options.HealthCheckInterval = defaultHealthCheckInterval
	}

	var err error
	var resolvedAddress *net.TCPAddr
	resolvedAddress, err = net.ResolveTCPAddr("tcp", options.RemoteAddress)
	if err == nil {
		n := &Node{
			stopChan:            make(chan struct{}),
			addr:                resolvedAddress,
			healthCheckInterval: options.HealthCheckInterval,
			healthCheckBuilder:  options.HealthCheckBuilder,
			authOptions:         options.AuthOptions,
		}

		connMgrOpts := &connectionManagerOptions{
			addr:           resolvedAddress,
			minConnections: options.MinConnections,
			maxConnections: options.MaxConnections,
			idleTimeout:    options.IdleTimeout,
			connectTimeout: options.ConnectTimeout,
			requestTimeout: options.RequestTimeout,
		}

		var cm *connectionManager
		if cm, err = newConnectionManager(connMgrOpts); err == nil {
			n.cm = cm
			n.initStateData("nodeCreated", "nodeRunning", "nodeHealthChecking", "nodeShuttingDown", "nodeShutdown", "nodeError")
			n.setState(nodeCreated)
			return n, nil
		}
	}

	return nil, err
}

// String returns a formatted string including the remoteAddress for the Node and its current
// connection count
func (n *Node) String() string {
	return fmt.Sprintf("%v|%d|%d", n.addr, n.cm.count(), n.cm.q.count())
}

// Start opens a connection with Riak at the configured remoteAddress and adds the connections to the
// active pool
func (n *Node) start() error {
	if err := n.stateCheck(nodeCreated); err != nil {
		return err
	}

	logDebug("[Node]", "(%v) starting", n)
	n.cm.start()
	n.setState(nodeRunning)
	logDebug("[Node]", "(%v) started", n)

	return nil
}

// Stop closes the connections with Riak at the configured remoteAddress and removes the connections
// from the active pool
func (n *Node) stop() error {
	if err := n.stateCheck(nodeRunning, nodeHealthChecking); err != nil {
		return err
	}

	logDebug("[Node]", "(%v) shutting down.", n)

	n.setState(nodeShuttingDown)
	close(n.stopChan)

	err := n.cm.stop()

	if err == nil {
		n.setState(nodeShutdown)
		logDebug("[Node]", "(%v) shut down.", n)
	} else {
		n.setState(nodeError)
		logErr("[Node]", err)
	}

	return err
}

// Execute retrieves an available connection from the pool and executes the Command operation against
// Riak
func (n *Node) execute(cmd Command) (bool, error) {
	if err := n.stateCheck(nodeRunning, nodeHealthChecking); err != nil {
		return false, err
	}

	cmd.setLastNode(n)

	if n.isCurrentState(nodeRunning) {
		conn, err := n.cm.get()
		if err != nil {
			logErr("[Node]", err)
			n.doHealthCheck()
			return false, err
		}

		if conn == nil {
			panic(fmt.Sprintf("[Node] (%v) expected non-nil connection", n))
		}

		logDebug("[Node]", "(%v) - executing command '%v'", n, cmd.Name())
		err = conn.execute(cmd)
		if err == nil {
			// NB: basically the success path of _responseReceived in Node.js client
			if cmErr := n.cm.put(conn); cmErr != nil {
				logErr("[Node]", cmErr)
			}
			return true, nil
		} else {
			// NB: basically, this is _connectionClosed / _responseReceived in Node.js client
			// must differentiate between Riak and non-Riak errors here and within execute() in connection
			switch err.(type) {
			case RiakError, ClientError:
				// Riak and Client errors will not close connection
				if cmErr := n.cm.put(conn); cmErr != nil {
					logErr("[Node]", cmErr)
				}
				return true, err
			default:
				// NB: must be a non-Riak, non-Client error
				if isTemporaryNetError(err) {
					// Don't nuke the connection on a Temporary error
					if cmErr := n.cm.put(conn); cmErr != nil {
						logErr("[Node]", cmErr)
					}
				} else {
					if cmErr := n.cm.remove(conn); cmErr != nil {
						logErr("[Node]", cmErr)
					}
				}
				n.doHealthCheck()
				return true, err
			}
		}
	} else {
		return false, nil
	}
}

func (n *Node) doHealthCheck() {
	// NB: ensure we're not already healthchecking or shutting down
	if n.isStateLessThan(nodeHealthChecking) {
		n.setState(nodeHealthChecking)
		go n.healthCheck()
	} else {
		logDebug("[Node]", "(%v) is already healthchecking or shutting down.", n)
	}
}

func (n *Node) getHealthCheckCommand() (hc Command) {
	// This is necessary to have a unique Command struct as part of each
	// connection so that concurrent calls to check health can all have
	// unique results
	var err error
	if n.healthCheckBuilder != nil {
		hc, err = n.healthCheckBuilder.Build()
	} else {
		hc = &PingCommand{}
	}

	if err != nil {
		logErr("[Node]", err)
		hc = &PingCommand{}
	}

	return
}

func (n *Node) ensureHealthCheckCanContinue() bool {
	// ensure we ARE healthchecking
	if !n.isCurrentState(nodeHealthChecking) {
		logDebug("[Node]", "(%v) expected healthchecking state, got %s", n, n.stateData.String())
		return false
	}
	return true
}

// private goroutine funcs

func (n *Node) healthCheck() {
	logDebug("[Node]", "(%v) starting healthcheck routine", n)

	healthCheckTicker := time.NewTicker(n.healthCheckInterval)
	defer healthCheckTicker.Stop()

	for {
		if !n.ensureHealthCheckCanContinue() {
			return
		}
		select {
		case <-n.stopChan:
			logDebug("[Node]", "(%v) healthcheck quitting", n)
			return
		case t := <-healthCheckTicker.C:
			if !n.ensureHealthCheckCanContinue() {
				return
			}
			logDebug("[Node]", "(%v) running healthcheck at %v", n, t)
			conn, cerr := n.cm.createConnection()
			if cerr != nil {
				conn.close()
				logError("[Node]", "(%v) failed healthcheck in createConnection, err: %v", n, cerr)
			} else {
				if !n.ensureHealthCheckCanContinue() {
					conn.close()
					return
				}
				hcmd := n.getHealthCheckCommand()
				logDebug("[Node]", "(%v) healthcheck executing %v", n, hcmd.Name())
				if hcerr := conn.execute(hcmd); hcerr != nil || !hcmd.Success() {
					conn.close()
					logError("[Node]", "(%v) failed healthcheck, err: %v", n, hcerr)
				} else {
					conn.close()
					logDebug("[Node]", "(%v) healthcheck success, err: %v, success: %v", n, hcerr, hcmd.Success())
					if n.ensureHealthCheckCanContinue() {
						n.setState(nodeRunning)
					}
					return
				}
			}
		}
	}
}
<commit_msg>Pass authoptions to the node in order to be able to create TLS connections, this fixes the cause of not creating a tls connection on connection/startTls method because authOptions always is nil<commit_after>package riak

import (
	"fmt"
	"net"
	"time"
)

// Constants identifying Node state
const (
	nodeCreated state = iota
	nodeRunning
	nodeHealthChecking
	nodeShuttingDown
	nodeShutdown
	nodeError
)

// NodeOptions defines the RemoteAddress and operational configuration for connections to a Riak KV
// instance
type NodeOptions struct {
	RemoteAddress       string
	MinConnections      uint16
	MaxConnections      uint16
	IdleTimeout         time.Duration
	ConnectTimeout      time.Duration
	RequestTimeout      time.Duration
	HealthCheckInterval time.Duration
	HealthCheckBuilder  CommandBuilder
	AuthOptions         *AuthOptions
}

// Node is a struct that contains all of the information needed to connect and maintain connections
// with a Riak KV instance
type Node struct {
	addr                *net.TCPAddr
	healthCheckInterval time.Duration
	healthCheckBuilder  CommandBuilder
	authOptions         *AuthOptions
	stopChan            chan struct{}
	cm                  *connectionManager
	stateData
}

var defaultNodeOptions = &NodeOptions{
	RemoteAddress:  defaultRemoteAddress,
	MinConnections: defaultMinConnections,
	MaxConnections: defaultMaxConnections,
	IdleTimeout:    defaultIdleTimeout,
	ConnectTimeout: defaultConnectTimeout,
	RequestTimeout: defaultRequestTimeout,
}

// NewNode is a factory function that takes a NodeOptions struct and returns a Node struct
func NewNode(options *NodeOptions) (*Node, error) {
	if options == nil {
		options = defaultNodeOptions
	}
	if options.RemoteAddress == "" {
		options.RemoteAddress = defaultRemoteAddress
	}
	if options.HealthCheckInterval == 0 {
		options.HealthCheckInterval = defaultHealthCheckInterval
	}

	var err error
	var resolvedAddress *net.TCPAddr
	resolvedAddress, err = net.ResolveTCPAddr("tcp", options.RemoteAddress)
	if err == nil {
		n := &Node{
			stopChan:            make(chan struct{}),
			addr:                resolvedAddress,
			healthCheckInterval: options.HealthCheckInterval,
			healthCheckBuilder:  options.HealthCheckBuilder,
			authOptions:         options.AuthOptions,
		}

		connMgrOpts := &connectionManagerOptions{
			addr:           resolvedAddress,
			minConnections: options.MinConnections,
			maxConnections: options.MaxConnections,
			idleTimeout:    options.IdleTimeout,
			connectTimeout: options.ConnectTimeout,
			requestTimeout: options.RequestTimeout,
			authOptions:    options.AuthOptions,
		}

		var cm *connectionManager
		if cm, err = newConnectionManager(connMgrOpts); err == nil {
			n.cm = cm
			n.initStateData("nodeCreated", "nodeRunning", "nodeHealthChecking", "nodeShuttingDown", "nodeShutdown", "nodeError")
			n.setState(nodeCreated)
			return n, nil
		}
	}

	return nil, err
}

// String returns a formatted string including the remoteAddress for the Node and its current
// connection count
func (n *Node) String() string {
	return fmt.Sprintf("%v|%d|%d", n.addr, n.cm.count(), n.cm.q.count())
}

// Start opens a connection with Riak at the configured remoteAddress and adds the connections to the
// active pool
func (n *Node) start() error {
	if err := n.stateCheck(nodeCreated); err != nil {
		return err
	}

	logDebug("[Node]", "(%v) starting", n)
	n.cm.start()
	n.setState(nodeRunning)
	logDebug("[Node]", "(%v) started", n)

	return nil
}

// Stop closes the connections with Riak at the configured remoteAddress and removes the connections
// from the active pool
func (n *Node) stop() error {
	if err := n.stateCheck(nodeRunning, nodeHealthChecking); err != nil {
		return err
	}

	logDebug("[Node]", "(%v) shutting down.", n)

	n.setState(nodeShuttingDown)
	close(n.stopChan)

	err := n.cm.stop()

	if err == nil {
		n.setState(nodeShutdown)
		logDebug("[Node]", "(%v) shut down.", n)
	} else {
		n.setState(nodeError)
		logErr("[Node]", err)
	}

	return err
}

// Execute retrieves an available connection from the pool and executes the Command operation against
// Riak
func (n *Node) execute(cmd Command) (bool, error) {
	if err := n.stateCheck(nodeRunning, nodeHealthChecking); err != nil {
		return false, err
	}

	cmd.setLastNode(n)

	if n.isCurrentState(nodeRunning) {
		conn, err := n.cm.get()
		if err != nil {
			logErr("[Node]", err)
			n.doHealthCheck()
			return false, err
		}

		if conn == nil {
			panic(fmt.Sprintf("[Node] (%v) expected non-nil connection", n))
		}

		logDebug("[Node]", "(%v) - executing command '%v'", n, cmd.Name())
		err = conn.execute(cmd)
		if err == nil {
			// NB: basically the success path of _responseReceived in Node.js client
			if cmErr := n.cm.put(conn); cmErr != nil {
				logErr("[Node]", cmErr)
			}
			return true, nil
		} else {
			// NB: basically, this is _connectionClosed / _responseReceived in Node.js client
			// must differentiate between Riak and non-Riak errors here and within execute() in connection
			switch err.(type) {
			case RiakError, ClientError:
				// Riak and Client errors will not close connection
				if cmErr := n.cm.put(conn); cmErr != nil {
					logErr("[Node]", cmErr)
				}
				return true, err
			default:
				// NB: must be a non-Riak, non-Client error
				if isTemporaryNetError(err) {
					// Don't nuke the connection on a Temporary error
					if cmErr := n.cm.put(conn); cmErr != nil {
						logErr("[Node]", cmErr)
					}
				} else {
					if cmErr := n.cm.remove(conn); cmErr != nil {
						logErr("[Node]", cmErr)
					}
				}
				n.doHealthCheck()
				return true, err
			}
		}
	} else {
		return false, nil
	}
}

func (n *Node) doHealthCheck() {
	// NB: ensure we're not already healthchecking or shutting down
	if n.isStateLessThan(nodeHealthChecking) {
		n.setState(nodeHealthChecking)
		go n.healthCheck()
	} else {
		logDebug("[Node]", "(%v) is already healthchecking or shutting down.", n)
	}
}

func (n *Node) getHealthCheckCommand() (hc Command) {
	// This is necessary to have a unique Command struct as part of each
	// connection so that concurrent calls to check health can all have
	// unique results
	var err error
	if n.healthCheckBuilder != nil {
		hc, err = n.healthCheckBuilder.Build()
	} else {
		hc = &PingCommand{}
	}

	if err != nil {
		logErr("[Node]", err)
		hc = &PingCommand{}
	}

	return
}

func (n *Node) ensureHealthCheckCanContinue() bool {
	// ensure we ARE healthchecking
	if !n.isCurrentState(nodeHealthChecking) {
		logDebug("[Node]", "(%v) expected healthchecking state, got %s", n, n.stateData.String())
		return false
	}
	return true
}

// private goroutine funcs

func (n *Node) healthCheck() {
	logDebug("[Node]", "(%v) starting healthcheck routine", n)

	healthCheckTicker := time.NewTicker(n.healthCheckInterval)
	defer healthCheckTicker.Stop()

	for {
		if !n.ensureHealthCheckCanContinue() {
			return
		}
		select {
		case <-n.stopChan:
			logDebug("[Node]", "(%v) healthcheck quitting", n)
			return
		case t := <-healthCheckTicker.C:
			if !n.ensureHealthCheckCanContinue() {
				return
			}
			logDebug("[Node]", "(%v) running healthcheck at %v", n, t)
			conn, cerr := n.cm.createConnection()
			if cerr != nil {
				conn.close()
				logError("[Node]", "(%v) failed healthcheck in createConnection, err: %v", n, cerr)
			} else {
				if !n.ensureHealthCheckCanContinue() {
					conn.close()
					return
				}
				hcmd := n.getHealthCheckCommand()
				logDebug("[Node]", "(%v) healthcheck executing %v", n, hcmd.Name())
				if hcerr := conn.execute(hcmd); hcerr != nil || !hcmd.Success() {
					conn.close()
					logError("[Node]", "(%v) failed healthcheck, err: %v", n, hcerr)
				} else {
					conn.close()
					logDebug("[Node]", "(%v) healthcheck success, err: %v, success: %v", n, hcerr, hcmd.Success())
					if n.ensureHealthCheckCanContinue() {
						n.setState(nodeRunning)
					}
					return
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>package kongo

import (
	"context"
	"net/http"
)

type (
	// Node retrieves the info about the server nodes.
	Node interface {
		// Info retrieves the information about the server node
		Info() (*NodeInfo, *http.Response, error)

		// InfoWithContext retrieves the information about the server node
		InfoWithContext(ctx context.Context) (*NodeInfo, *http.Response, error)

		// Status retrieves the status of the server node.
		Status() (*NodeStatus, *http.Response, error)

		// StatusWithContext retrieves the status of the server node.
		StatusWithContext(ctx context.Context) (*NodeStatus, *http.Response, error)
	}

	// NodeService it's a concrete instance of node
	NodeService struct {

		// Kongo client manages communication by API.
		client *Kongo
	}

	// NodeInfo it's a structure of API result
	NodeInfo struct {
		Configuration *NodeInfoConfiguration `json:"configuration"`
		Hostname      string                 `json:"hostname"`
		LuaVersion    string                 `json:"lua_version"`
		Plugins       *NodeInfoPlugins       `json:"plugins"`
		PrngSeeds     map[string]int         `json:"prng_seeds"`
		Tagline       string                 `json:"tagline"`
		Timers        *NodeInfoTimers        `json:"timers"`
		Version       string                 `json:"version"`
	}

	// NodeInfoConfiguration it's a structure of API result
	NodeInfoConfiguration struct {
		AdminAcessLog                 string              `json:"admin_access_log"`
		AdminErrorLog                 string              `json:"admin_error_log"`
		AdminListen                   []string            `json:"admin_listen"`
		AdminListeners                []*NodeInfoListener `json:"admin_listeners"`
		AdminSSLCertificateDefault    string              `json:"admin_ssl_cert_default"`
		AdminSSLCertificateCsrDefault string              `json:"admin_ssl_cert_csr_default"`
		AdminSSLCertificateKeyDefault string              `json:"admin_ssl_cert_key_default"`
		AdminSSLEnabled               bool                `json:"admin_ssl_enabled"`
		AnonymousReports              bool                `json:"anonymous_reports"`

		CassandraConsistency            string   `json:"cassandra_consistency"`
		CassandraContactPoints          []string `json:"cassandra_contact_points"`
		CassandraDataCenters            []string `json:"cassandra_data_centers"`
		CassandraKeyspace               string   `json:"cassandra_keyspace"`
		CassandraLBPolicy               string   `json:"cassandra_lb_policy"`
		CassandraPort                   int      `json:"cassandra_port"`
		CassandraReplicationFactor      int      `json:"cassandra_repl_factor"`
		CassandraReplicationStrategy    string   `json:"cassandra_repl_strategy"`
		CassandraSchemaConsensusTimeout int      `json:"cassandra_schema_consensus_timeout"`
		CassandraSSL                    bool     `json:"cassandra_ssl"`
		CassandraSSLVerify              bool     `json:"cassandra_ssl_verify"`
		CassandraTimeout                int      `json:"cassandra_timeout"`
		CassandraUsername               string   `json:"cassandra_username"`

		ClientBodyBufferSize           string `json:"client_body_buffer_size"`
		ClientMaxBodySize              string `json:"client_max_body_size"`
		ClientSSL                      bool   `json:"client_ssl"`
		ClientSSLCertificateCsrDefault string `json:"client_ssl_cert_csr_default"`
		ClientSSLCertificateDefault    string `json:"client_ssl_cert_default"`
		ClientSSLCertificateKeyDefault string `json:"client_ssl_cert_key_default"`

		CustomPlugins interface{} `json:"custom_plugins"`

		Database                  string `json:"database"`
		DatabaseCacheTTL          int    `json:"db_cache_ttl"`
		DatabaseUpdateFrequency   int    `json:"db_update_frequency"`
		DatabaseUpdatePropagation int    `json:"db_update_propagation"`

		DNSErrorTTL    int         `json:"dns_error_ttl"`
		DNSHostsFile   string      `json:"dns_hostsfile"`
		DNSNotFoundTTL int         `json:"dns_not_found_ttl"`
		DNSNoSync      bool        `json:"dns_no_sync"`
		DNSOrder       []string    `json:"dns_order"`
		DNSResolver    interface{} `json:"dns_resolver"`
		DNSStaleTTL    int         `json:"dns_stale_ttl"`

		ErrorDefaultType string `json:"error_default_type"`

		KongEnv string `json:"kong_env"`

		LatencyTokens bool `json:"latency_tokens"`

		LuaPackageCPath   string `json:"lua_package_cpath"`
		LuaPackagePath    string `json:"lua_package_path"`
		LuaSocketPoolSize int    `json:"lua_socket_pool_size"`
		LuaSSLVerifyDepth int    `json:"lua_ssl_verify_depth"`

		LogLevel string `json:"log_level"`

		MemoryCacheSize string `json:"mem_cache_size"`

		NginxAccessLogs      string `json:"nginx_acc_logs"`
		NginxAdminAccessLog  string `json:"nginx_admin_acc_logs"`
		NginxConf            string `json:"nginx_conf"`
		NginxDaemon          string `json:"nginx_daemon"`
		NginxErrorLogs       string `json:"nginx_err_logs"`
		NginxKongConf        string `json:"nginx_kong_conf"`
		NginxOptimizations   bool   `json:"nginx_optimizations"`
		NginxPID             string `json:"nginx_pid"`
		NginxWorkerProcesses string `json:"nginx_worker_processes"`

		Plugins map[string]bool `json:"plugins"`

		PostgresDatabase  string `json:"pg_database"`
		PostgresHost      string `json:"pg_host"`
		PostgresPort      int    `json:"pg_port"`
		PostgresSSL       bool   `json:"pg_ssl"`
		PostgresUsername  string `json:"pg_user"`
		PostgresSSLVerify bool   `json:"pg_ssl_verify"`

		Prefix string `json:"prefix"`

		ProxyAccessLog  string              `json:"proxy_access_log"`
		ProxyErrorLog   string              `json:"proxy_error_log"`
		ProxyListen     []string            `json:"proxy_listen"`
		ProxyListeners  []*NodeInfoListener `json:"proxy_listeners"`
		ProxySSLEnabled bool                `json:"proxy_ssl_enabled"`

		RealIpHeader    string `json:"real_ip_header"`
		RealIpRecursive string `json:"real_ip_recursive"`

		ServerTokens bool `json:"server_tokens"`

		SSLCertificate           string `json:"ssl_cert"`
		SSLCertificateDefault    string `json:"ssl_cert_default"`
		SSLCertificateKey        string `json:"ssl_cert_key"`
		SSLCertificateDefaultKey string `json:"ssl_cert_key_default"`
		SSLCertificateCsrDefault string `json:"ssl_cert_csr_default"`
		SSLCiphers               string `json:"ssl_ciphers"`
		SSLCipherSuite           string `json:"ssl_cipher_suite"`

		TrustedIps interface{} `json:"trusted_ips"`

		UpstreamKeepAlive int `json:"upstream_keepalive"`
	}

	// NodeInfoListener it's a structure of API result
	NodeInfoListener struct {
		SSL      bool   `json:"ssl"`
		Ip       string `json:"ip"`
		Protocol bool   `json:"protocol"`
		Port     int    `json:"port"`
		Http2    bool   `json:"http2"`
		Listener string `json:"listener"`
	}

	// NodeInfoPlugins it's a structure of API result
	NodeInfoPlugins struct {
		AvailableOnServer map[string]bool `json:"available_on_server"`
		EnabledInCluster  []string        `json:"enabled_in_cluster"`
	}

	// NodeInfoTimers it's a structure of API result
	NodeInfoTimers struct {
		Pending int `json:"pending"`
		Running int `json:"running"`
	}

	// NodeStatus it's a structure of API result
	NodeStatus struct {
		Database *NodeStatusDatabase `json:"database"`
		Server   *NodeStatusServer   `json:"server"`
	}

	// NodeStatusDatabase it's a structure of API result
	NodeStatusDatabase struct {
		Reachable bool `json:"reachable, omitempty`
	}

	// NodeStatusServer it's a structure of API result
	NodeStatusServer struct {
		ConnectionsAccepted int `json:"connections_accepted, omitempty"`
		ConnectionsActive   int `json:"connections_active, omitempty"`
		ConnectionsHandled  int `json:"connections_handled, omitempty"`
		ConnectionsReading  int `json:"connections_reading, omitempty"`
		ConnectionsWaiting  int `json:"connections_waiting, omitempty"`
		ConnectionsWriting  int `json:"connections_writing, omitempty"`
		TotalRequests       int `json:"total_requests, omitempty"`
	}
)

// InfoWithContext retrieves the server node information
func (n *NodeService) InfoWithContext(ctx context.Context) (*NodeInfo, *http.Response, error) {
	req, err := n.client.NewRequest(ctx, http.MethodGet, "/")

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

	nodeInfo := new(NodeInfo)

	res, err := n.client.Do(req, nodeInfo)

	if err != nil {
		return nil, res, err
	}

	return nodeInfo, res, nil
}

// Info retrieves the server node information
func (n *NodeService) Info() (*NodeInfo, *http.Response, error) {
	return n.InfoWithContext(context.TODO())
}

// StatusWithContext retrieves the server node status.
func (n *NodeService) StatusWithContext(ctx context.Context) (*NodeStatus, *http.Response, error) {
	req, err := n.client.NewRequest(ctx, http.MethodGet, "/status")

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

	nodeStatus := new(NodeStatus)

	res, err := n.client.Do(req, nodeStatus)

	if err != nil {
		return nil, res, err
	}

	return nodeStatus, res, nil
}

// Status retrieves the server node status.
func (n *NodeService) Status() (*NodeStatus, *http.Response, error) {
	return n.StatusWithContext(context.TODO())
}
<commit_msg>Fix not compatible syntax<commit_after>package kongo

import (
	"context"
	"net/http"
)

type (
	// Node retrieves the info about the server nodes.
	Node interface {
		// Info retrieves the information about the server node
		Info() (*NodeInfo, *http.Response, error)

		// InfoWithContext retrieves the information about the server node
		InfoWithContext(ctx context.Context) (*NodeInfo, *http.Response, error)

		// Status retrieves the status of the server node.
		Status() (*NodeStatus, *http.Response, error)

		// StatusWithContext retrieves the status of the server node.
		StatusWithContext(ctx context.Context) (*NodeStatus, *http.Response, error)
	}

	// NodeService it's a concrete instance of node
	NodeService struct {

		// Kongo client manages communication by API.
		client *Kongo
	}

	// NodeInfo it's a structure of API result
	NodeInfo struct {
		Configuration *NodeInfoConfiguration `json:"configuration"`
		Hostname      string                 `json:"hostname"`
		LuaVersion    string                 `json:"lua_version"`
		Plugins       *NodeInfoPlugins       `json:"plugins"`
		PrngSeeds     map[string]int         `json:"prng_seeds"`
		Tagline       string                 `json:"tagline"`
		Timers        *NodeInfoTimers        `json:"timers"`
		Version       string                 `json:"version"`
	}

	// NodeInfoConfiguration it's a structure of API result
	NodeInfoConfiguration struct {
		AdminAcessLog                 string              `json:"admin_access_log"`
		AdminErrorLog                 string              `json:"admin_error_log"`
		AdminListen                   []string            `json:"admin_listen"`
		AdminListeners                []*NodeInfoListener `json:"admin_listeners"`
		AdminSSLCertificateDefault    string              `json:"admin_ssl_cert_default"`
		AdminSSLCertificateCsrDefault string              `json:"admin_ssl_cert_csr_default"`
		AdminSSLCertificateKeyDefault string              `json:"admin_ssl_cert_key_default"`
		AdminSSLEnabled               bool                `json:"admin_ssl_enabled"`
		AnonymousReports              bool                `json:"anonymous_reports"`

		CassandraConsistency            string   `json:"cassandra_consistency"`
		CassandraContactPoints          []string `json:"cassandra_contact_points"`
		CassandraDataCenters            []string `json:"cassandra_data_centers"`
		CassandraKeyspace               string   `json:"cassandra_keyspace"`
		CassandraLBPolicy               string   `json:"cassandra_lb_policy"`
		CassandraPort                   int      `json:"cassandra_port"`
		CassandraReplicationFactor      int      `json:"cassandra_repl_factor"`
		CassandraReplicationStrategy    string   `json:"cassandra_repl_strategy"`
		CassandraSchemaConsensusTimeout int      `json:"cassandra_schema_consensus_timeout"`
		CassandraSSL                    bool     `json:"cassandra_ssl"`
		CassandraSSLVerify              bool     `json:"cassandra_ssl_verify"`
		CassandraTimeout                int      `json:"cassandra_timeout"`
		CassandraUsername               string   `json:"cassandra_username"`

		ClientBodyBufferSize           string `json:"client_body_buffer_size"`
		ClientMaxBodySize              string `json:"client_max_body_size"`
		ClientSSL                      bool   `json:"client_ssl"`
		ClientSSLCertificateCsrDefault string `json:"client_ssl_cert_csr_default"`
		ClientSSLCertificateDefault    string `json:"client_ssl_cert_default"`
		ClientSSLCertificateKeyDefault string `json:"client_ssl_cert_key_default"`

		CustomPlugins interface{} `json:"custom_plugins"`

		Database                  string `json:"database"`
		DatabaseCacheTTL          int    `json:"db_cache_ttl"`
		DatabaseUpdateFrequency   int    `json:"db_update_frequency"`
		DatabaseUpdatePropagation int    `json:"db_update_propagation"`

		DNSErrorTTL    int         `json:"dns_error_ttl"`
		DNSHostsFile   string      `json:"dns_hostsfile"`
		DNSNotFoundTTL int         `json:"dns_not_found_ttl"`
		DNSNoSync      bool        `json:"dns_no_sync"`
		DNSOrder       []string    `json:"dns_order"`
		DNSResolver    interface{} `json:"dns_resolver"`
		DNSStaleTTL    int         `json:"dns_stale_ttl"`

		ErrorDefaultType string `json:"error_default_type"`

		KongEnv string `json:"kong_env"`

		LatencyTokens bool `json:"latency_tokens"`

		LuaPackageCPath   string `json:"lua_package_cpath"`
		LuaPackagePath    string `json:"lua_package_path"`
		LuaSocketPoolSize int    `json:"lua_socket_pool_size"`
		LuaSSLVerifyDepth int    `json:"lua_ssl_verify_depth"`

		LogLevel string `json:"log_level"`

		MemoryCacheSize string `json:"mem_cache_size"`

		NginxAccessLogs      string `json:"nginx_acc_logs"`
		NginxAdminAccessLog  string `json:"nginx_admin_acc_logs"`
		NginxConf            string `json:"nginx_conf"`
		NginxDaemon          string `json:"nginx_daemon"`
		NginxErrorLogs       string `json:"nginx_err_logs"`
		NginxKongConf        string `json:"nginx_kong_conf"`
		NginxOptimizations   bool   `json:"nginx_optimizations"`
		NginxPID             string `json:"nginx_pid"`
		NginxWorkerProcesses string `json:"nginx_worker_processes"`

		Plugins map[string]bool `json:"plugins"`

		PostgresDatabase  string `json:"pg_database"`
		PostgresHost      string `json:"pg_host"`
		PostgresPort      int    `json:"pg_port"`
		PostgresSSL       bool   `json:"pg_ssl"`
		PostgresUsername  string `json:"pg_user"`
		PostgresSSLVerify bool   `json:"pg_ssl_verify"`

		Prefix string `json:"prefix"`

		ProxyAccessLog  string              `json:"proxy_access_log"`
		ProxyErrorLog   string              `json:"proxy_error_log"`
		ProxyListen     []string            `json:"proxy_listen"`
		ProxyListeners  []*NodeInfoListener `json:"proxy_listeners"`
		ProxySSLEnabled bool                `json:"proxy_ssl_enabled"`

		RealIpHeader    string `json:"real_ip_header"`
		RealIpRecursive string `json:"real_ip_recursive"`

		ServerTokens bool `json:"server_tokens"`

		SSLCertificate           string `json:"ssl_cert"`
		SSLCertificateDefault    string `json:"ssl_cert_default"`
		SSLCertificateKey        string `json:"ssl_cert_key"`
		SSLCertificateDefaultKey string `json:"ssl_cert_key_default"`
		SSLCertificateCsrDefault string `json:"ssl_cert_csr_default"`
		SSLCiphers               string `json:"ssl_ciphers"`
		SSLCipherSuite           string `json:"ssl_cipher_suite"`

		TrustedIps interface{} `json:"trusted_ips"`

		UpstreamKeepAlive int `json:"upstream_keepalive"`
	}

	// NodeInfoListener it's a structure of API result
	NodeInfoListener struct {
		SSL      bool   `json:"ssl"`
		Ip       string `json:"ip"`
		Protocol bool   `json:"protocol"`
		Port     int    `json:"port"`
		Http2    bool   `json:"http2"`
		Listener string `json:"listener"`
	}

	// NodeInfoPlugins it's a structure of API result
	NodeInfoPlugins struct {
		AvailableOnServer map[string]bool `json:"available_on_server"`
		EnabledInCluster  []string        `json:"enabled_in_cluster"`
	}

	// NodeInfoTimers it's a structure of API result
	NodeInfoTimers struct {
		Pending int `json:"pending"`
		Running int `json:"running"`
	}

	// NodeStatus it's a structure of API result
	NodeStatus struct {
		Database *NodeStatusDatabase `json:"database"`
		Server   *NodeStatusServer   `json:"server"`
	}

	// NodeStatusDatabase it's a structure of API result
	NodeStatusDatabase struct {
		Reachable bool `json:"reachable, omitempty"`
	}

	// NodeStatusServer it's a structure of API result
	NodeStatusServer struct {
		ConnectionsAccepted int `json:"connections_accepted, omitempty"`
		ConnectionsActive   int `json:"connections_active, omitempty"`
		ConnectionsHandled  int `json:"connections_handled, omitempty"`
		ConnectionsReading  int `json:"connections_reading, omitempty"`
		ConnectionsWaiting  int `json:"connections_waiting, omitempty"`
		ConnectionsWriting  int `json:"connections_writing, omitempty"`
		TotalRequests       int `json:"total_requests, omitempty"`
	}
)

// InfoWithContext retrieves the server node information
func (n *NodeService) InfoWithContext(ctx context.Context) (*NodeInfo, *http.Response, error) {
	req, err := n.client.NewRequest(ctx, http.MethodGet, "/")

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

	nodeInfo := new(NodeInfo)

	res, err := n.client.Do(req, nodeInfo)

	if err != nil {
		return nil, res, err
	}

	return nodeInfo, res, nil
}

// Info retrieves the server node information
func (n *NodeService) Info() (*NodeInfo, *http.Response, error) {
	return n.InfoWithContext(context.TODO())
}

// StatusWithContext retrieves the server node status.
func (n *NodeService) StatusWithContext(ctx context.Context) (*NodeStatus, *http.Response, error) {
	req, err := n.client.NewRequest(ctx, http.MethodGet, "/status")

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

	nodeStatus := new(NodeStatus)

	res, err := n.client.Do(req, nodeStatus)

	if err != nil {
		return nil, res, err
	}

	return nodeStatus, res, nil
}

// Status retrieves the server node status.
func (n *NodeService) Status() (*NodeStatus, *http.Response, error) {
	return n.StatusWithContext(context.TODO())
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/workspaces"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func dataSourceAwsWorkspacesWorkspace() *schema.Resource {
	return &schema.Resource{
		Read: dataSourceAwsWorkspacesWorkspaceRead,

		Schema: map[string]*schema.Schema{
			"bundle_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"directory_id": {
				Type:          schema.TypeString,
				Computed:      true,
				Optional:      true,
				RequiredWith:  []string{"user_name"},
				ConflictsWith: []string{"workspace_id"},
			},
			"ip_address": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"computer_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"state": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"root_volume_encryption_enabled": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"user_name": {
				Type:          schema.TypeString,
				Computed:      true,
				Optional:      true,
				RequiredWith:  []string{"directory_id"},
				ConflictsWith: []string{"workspace_id"},
			},
			"user_volume_encryption_enabled": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"volume_encryption_key": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"workspace_id": {
				Type:          schema.TypeString,
				Computed:      true,
				Optional:      true,
				ConflictsWith: []string{"directory_id", "user_name"},
			},
			"workspace_properties": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"compute_type_name": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"root_volume_size_gib": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"running_mode": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"running_mode_auto_stop_timeout_in_minutes": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"user_volume_size_gib": {
							Type:     schema.TypeInt,
							Computed: true,
						},
					},
				},
			},
			"tags": tagsSchemaComputed(),
		},
	}
}

func dataSourceAwsWorkspacesWorkspaceRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).workspacesconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	var workspace *workspaces.Workspace

	if workspaceID, ok := d.GetOk("workspace_id"); ok {
		resp, err := conn.DescribeWorkspaces(&workspaces.DescribeWorkspacesInput{
			WorkspaceIds: aws.StringSlice([]string{workspaceID.(string)}),
		})
		if err != nil {
			return err
		}

		if len(resp.Workspaces) != 1 {
			return fmt.Errorf("expected 1 result for WorkSpace  %q, found %d", workspaceID, len(resp.Workspaces))
		}

		workspace = resp.Workspaces[0]

		if workspace == nil {
			return fmt.Errorf("no WorkSpace with ID %q found", workspaceID)
		}
	}

	if directoryID, ok := d.GetOk("directory_id"); ok {
		userName := d.Get("user_name").(string)
		resp, err := conn.DescribeWorkspaces(&workspaces.DescribeWorkspacesInput{
			DirectoryId: aws.String(directoryID.(string)),
			UserName:    aws.String(userName),
		})
		if err != nil {
			return err
		}

		if len(resp.Workspaces) != 1 {
			return fmt.Errorf("expected 1 result for %q WorkSpace in %q directory, found %d", userName, directoryID, len(resp.Workspaces))
		}

		workspace = resp.Workspaces[0]

		if workspace == nil {
			return fmt.Errorf("no %q WorkSpace in %q directory found", userName, directoryID)
		}
	}

	d.SetId(aws.StringValue(workspace.WorkspaceId))
	d.Set("bundle_id", aws.StringValue(workspace.BundleId))
	d.Set("directory_id", aws.StringValue(workspace.DirectoryId))
	d.Set("ip_address", aws.StringValue(workspace.IpAddress))
	d.Set("computer_name", aws.StringValue(workspace.ComputerName))
	d.Set("state", aws.StringValue(workspace.State))
	d.Set("root_volume_encryption_enabled", aws.BoolValue(workspace.RootVolumeEncryptionEnabled))
	d.Set("user_name", aws.StringValue(workspace.UserName))
	d.Set("user_volume_encryption_enabled", aws.BoolValue(workspace.UserVolumeEncryptionEnabled))
	d.Set("volume_encryption_key", aws.StringValue(workspace.VolumeEncryptionKey))
	if err := d.Set("workspace_properties", flattenWorkspaceProperties(workspace.WorkspaceProperties)); err != nil {
		return fmt.Errorf("error setting workspace properties: %s", err)
	}

	tags, err := keyvaluetags.WorkspacesListTags(conn, d.Id())
	if err != nil {
		return fmt.Errorf("error listing tags: %s", err)
	}

	if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	return nil
}
<commit_msg>fix import issue<commit_after>package aws

import (
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/workspaces"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

func dataSourceAwsWorkspacesWorkspace() *schema.Resource {
	return &schema.Resource{
		Read: dataSourceAwsWorkspacesWorkspaceRead,

		Schema: map[string]*schema.Schema{
			"bundle_id": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"directory_id": {
				Type:          schema.TypeString,
				Computed:      true,
				Optional:      true,
				RequiredWith:  []string{"user_name"},
				ConflictsWith: []string{"workspace_id"},
			},
			"ip_address": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"computer_name": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"state": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"root_volume_encryption_enabled": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"user_name": {
				Type:          schema.TypeString,
				Computed:      true,
				Optional:      true,
				RequiredWith:  []string{"directory_id"},
				ConflictsWith: []string{"workspace_id"},
			},
			"user_volume_encryption_enabled": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"volume_encryption_key": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"workspace_id": {
				Type:          schema.TypeString,
				Computed:      true,
				Optional:      true,
				ConflictsWith: []string{"directory_id", "user_name"},
			},
			"workspace_properties": {
				Type:     schema.TypeList,
				Computed: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"compute_type_name": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"root_volume_size_gib": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"running_mode": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"running_mode_auto_stop_timeout_in_minutes": {
							Type:     schema.TypeInt,
							Computed: true,
						},
						"user_volume_size_gib": {
							Type:     schema.TypeInt,
							Computed: true,
						},
					},
				},
			},
			"tags": tagsSchemaComputed(),
		},
	}
}

func dataSourceAwsWorkspacesWorkspaceRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).workspacesconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	var workspace *workspaces.Workspace

	if workspaceID, ok := d.GetOk("workspace_id"); ok {
		resp, err := conn.DescribeWorkspaces(&workspaces.DescribeWorkspacesInput{
			WorkspaceIds: aws.StringSlice([]string{workspaceID.(string)}),
		})
		if err != nil {
			return err
		}

		if len(resp.Workspaces) != 1 {
			return fmt.Errorf("expected 1 result for WorkSpace  %q, found %d", workspaceID, len(resp.Workspaces))
		}

		workspace = resp.Workspaces[0]

		if workspace == nil {
			return fmt.Errorf("no WorkSpace with ID %q found", workspaceID)
		}
	}

	if directoryID, ok := d.GetOk("directory_id"); ok {
		userName := d.Get("user_name").(string)
		resp, err := conn.DescribeWorkspaces(&workspaces.DescribeWorkspacesInput{
			DirectoryId: aws.String(directoryID.(string)),
			UserName:    aws.String(userName),
		})
		if err != nil {
			return err
		}

		if len(resp.Workspaces) != 1 {
			return fmt.Errorf("expected 1 result for %q WorkSpace in %q directory, found %d", userName, directoryID, len(resp.Workspaces))
		}

		workspace = resp.Workspaces[0]

		if workspace == nil {
			return fmt.Errorf("no %q WorkSpace in %q directory found", userName, directoryID)
		}
	}

	d.SetId(aws.StringValue(workspace.WorkspaceId))
	d.Set("bundle_id", aws.StringValue(workspace.BundleId))
	d.Set("directory_id", aws.StringValue(workspace.DirectoryId))
	d.Set("ip_address", aws.StringValue(workspace.IpAddress))
	d.Set("computer_name", aws.StringValue(workspace.ComputerName))
	d.Set("state", aws.StringValue(workspace.State))
	d.Set("root_volume_encryption_enabled", aws.BoolValue(workspace.RootVolumeEncryptionEnabled))
	d.Set("user_name", aws.StringValue(workspace.UserName))
	d.Set("user_volume_encryption_enabled", aws.BoolValue(workspace.UserVolumeEncryptionEnabled))
	d.Set("volume_encryption_key", aws.StringValue(workspace.VolumeEncryptionKey))
	if err := d.Set("workspace_properties", flattenWorkspaceProperties(workspace.WorkspaceProperties)); err != nil {
		return fmt.Errorf("error setting workspace properties: %s", err)
	}

	tags, err := keyvaluetags.WorkspacesListTags(conn, d.Id())
	if err != nil {
		return fmt.Errorf("error listing tags: %s", err)
	}

	if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
)

var (
	title = flag.String("t", "Utility Name", "Title of notification.")
	mesg  = flag.String("m", "Done!", "Message notification will display.")
	sound = flag.String("s", "Ping", "Sound to play when notified.")
)

func init() {
	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, `Usage: noti [-tms] [utility [args...]]

    -t    Title of notification. Default is the utility name.

    -m    Message notification will display. Default is "Done!"

    -s    Sound to play when notified. Default is Ping. Possible options
          are Basso, Blow, Bottle, Frog, Funk, Glass, Hero, Morse, Ping,
          Pop, Purr, Sosumi, Submarine, Tink. Check /System/Library/Sounds
          for more info.

    -h    Display usage information and exit.`)
	}
}

func main() {
	flag.Parse()

	if len(flag.Args()) == 0 {
		if *title == "Utility Name" {
			*title = "noti"
		}
		if err := notify(*title, *mesg, *sound); err != nil {
			log.Println(err)
			os.Exit(1)
		}
		return
	}

	if *title == "Utility Name" {
		*title = flag.Args()[0]
	}

	if err := run(flag.Args()[0], flag.Args()[1:]); err != nil {
		notify(*title, "Failed. See terminal.", "Basso")
		os.Exit(1)
	}

	if err := notify(*title, *mesg, *sound); err != nil {
		log.Println(err)
		os.Exit(1)
	}
}

// run executes a program and waits for it to finish. The stdin, stdout, and
// stderr of noti are passed to the program.
func run(bin string, args []string) error {
	cmd := exec.Command(bin, args...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	return cmd.Run()
}

// notify displays a notification in OS X's notification center with a given
// title, message, and sound.
func notify(title, mesg, sound string) error {
	script := fmt.Sprintf("display notification %q with title %q sound name %q",
		mesg, title, sound)

	cmd := exec.Command("osascript", "-e", script)
	return cmd.Run()
}
<commit_msg>Reword usage.<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
)

var (
	title = flag.String("t", "Utility Name", "Title of notification.")
	mesg  = flag.String("m", "Done!", "Message notification will display.")
	sound = flag.String("s", "Ping", "Sound to play when notified.")
)

func init() {
	flag.Usage = func() {
		fmt.Fprintln(os.Stderr, `Usage: noti [-tms] [utility [args...]]

    -t    Title of notification. Default is the utility name.

    -m    Message notification will display. Default is "Done!"

    -s    Sound to play when notified. Default is Ping. Possible options
          are Basso, Blow, Bottle, Frog, Funk, Glass, Hero, Morse, Ping,
          Pop, Purr, Sosumi, Submarine, Tink. Check /System/Library/Sounds
          for available sounds.

    -h    Display usage information and exit.`)
	}
}

func main() {
	flag.Parse()

	if len(flag.Args()) == 0 {
		if *title == "Utility Name" {
			*title = "noti"
		}
		if err := notify(*title, *mesg, *sound); err != nil {
			log.Println(err)
			os.Exit(1)
		}
		return
	}

	if *title == "Utility Name" {
		*title = flag.Args()[0]
	}

	if err := run(flag.Args()[0], flag.Args()[1:]); err != nil {
		notify(*title, "Failed. See terminal.", "Basso")
		os.Exit(1)
	}

	if err := notify(*title, *mesg, *sound); err != nil {
		log.Println(err)
		os.Exit(1)
	}
}

// run executes a program and waits for it to finish. The stdin, stdout, and
// stderr of noti are passed to the program.
func run(bin string, args []string) error {
	cmd := exec.Command(bin, args...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	return cmd.Run()
}

// notify displays a notification in OS X's notification center with a given
// title, message, and sound.
func notify(title, mesg, sound string) error {
	script := fmt.Sprintf("display notification %q with title %q sound name %q",
		mesg, title, sound)

	cmd := exec.Command("osascript", "-e", script)
	return cmd.Run()
}
<|endoftext|>


<commit_before>// +build !windows

package mssql

import (
	"encoding/binary"
	"errors"
	"strings"
	"unicode/utf16"
)

const (
	NEGOTIATE_MESSAGE    = 1
	CHALLENGE_MESSAGE    = 2
	AUTHENTICATE_MESSAGE = 3
)

const (
	NEGOTIATE_UNICODE              = 0x00000001
	NEGOTIATE_OEM                  = 0x00000002
	NEGOTIATE_TARGET               = 0x00000004
	NEGOTIATE_SIGN                 = 0x00000010
	NEGOTIATE_SEAL                 = 0x00000020
	NEGOTIATE_DATAGRAM             = 0x00000040
	NEGOTIATE_LMKEY                = 0x00000080
	NEGOTIATE_NTLM                 = 0x00000200
	NEGOTIATE_ANONYMOUS            = 0x00000800
	NEGOTIATE_DOMAIN_SUPPLIED      = 0x00001000
	NEGOTIATE_WORKSTATION_SUPPLIED = 0x00002000
	NEGOTIATE_ALWAYS_SIGN          = 0x00008000
	NEGOTIATE_TARGET_TYPE_DOMAIN   = 0x00010000
	NEGOTIATE_TARGET_TYPE_SERVER   = 0x00020000
	NEGOTIATE_EXTENDED_SECURITY    = 0x00080000
	NEGOTIATE_IDENTIFY             = 0x00100000
	REQUEST_NON_NT_SESSION_KEY     = 0x00400000
	NEGOTIATE_TARGET_INFO          = 0x00800000
	NEGOTIATE_VERSION              = 0x02000000
	NEGOTIATE_128                  = 0x20000000
	NEGOTIATE_KEY_EXCH             = 0x400000000
	NEGOTIATE_56                   = 0x80000000
)

const NEGOTIATE_FLAGS = NEGOTIATE_UNICODE |
	NEGOTIATE_NTLM |
	NEGOTIATE_DOMAIN_SUPPLIED |
	NEGOTIATE_WORKSTATION_SUPPLIED |
	NEGOTIATE_ALWAYS_SIGN |
	NEGOTIATE_EXTENDED_SECURITY

type NTLMAuth struct {
	Domain      string
	UserName    string
	Password    string
	Workstation string
}

func getAuth(user, password, service, workstation string) (Auth, bool) {
	if !strings.ContainsRune(user, '\\') {
		return nil, false
	}
	domain_user := strings.SplitN(user, "\\", 2)
	return &NTLMAuth{
		Domain:      domain_user[0],
		UserName:    domain_user[1],
		Password:    password,
		Workstation: workstation,
	}, true
}

func utf16le(val string) []byte {
	var v []byte
	for _, r := range val {
		if utf16.IsSurrogate(r) {
			r1, r2 := utf16.EncodeRune(r)
			v = append(v, byte(r1), byte(r1>>8))
			v = append(v, byte(r2), byte(r2>>8))
		} else {
			v = append(v, byte(r), byte(r>>8))
		}
	}
	return v
}

func (auth *NTLMAuth) InitialBytes() ([]byte, error) {
	domain_len := len(auth.Domain)
	workstation_len := len(auth.Workstation)
	msg := make([]byte, 40+domain_len+workstation_len)
	copy(msg, []byte("NTLMSSP\x00"))
	binary.LittleEndian.PutUint32(msg[8:], NEGOTIATE_MESSAGE)
	binary.LittleEndian.PutUint32(msg[12:], NEGOTIATE_FLAGS)
	binary.LittleEndian.PutUint16(msg[16:], uint16(domain_len))
	binary.LittleEndian.PutUint16(msg[18:], uint16(domain_len))
	binary.LittleEndian.PutUint32(msg[20:], 40) // domain offset
	binary.LittleEndian.PutUint16(msg[24:], uint16(workstation_len))
	binary.LittleEndian.PutUint16(msg[26:], uint16(workstation_len))
	binary.LittleEndian.PutUint32(msg[28:], uint32(40+domain_len)) // workstation offset
	binary.LittleEndian.PutUint32(msg[32:], 0)                     // version
	binary.LittleEndian.PutUint32(msg[36:], 0)
	copy(msg[40:], auth.Domain)
	copy(msg[40+domain_len:], auth.Workstation)
	return msg, nil
}

func (auth *NTLMAuth) NextBytes(bytes []byte) ([]byte, error) {
	return nil, errors.New("NTLM is not implemented")
}

func (auth *NTLMAuth) Free() {
}
<commit_msg>ntlm v1 implementation<commit_after>// +build !windows

package mssql

import (
	"crypto/des"
	"encoding/binary"
	"errors"
	"strings"
	"unicode/utf16"

	"code.google.com/p/go.crypto/md4"
)

const (
	NEGOTIATE_MESSAGE    = 1
	CHALLENGE_MESSAGE    = 2
	AUTHENTICATE_MESSAGE = 3
)

const (
	NEGOTIATE_UNICODE                  = 0x00000001
	NEGOTIATE_OEM                      = 0x00000002
	NEGOTIATE_TARGET                   = 0x00000004
	NEGOTIATE_SIGN                     = 0x00000010
	NEGOTIATE_SEAL                     = 0x00000020
	NEGOTIATE_DATAGRAM                 = 0x00000040
	NEGOTIATE_LMKEY                    = 0x00000080
	NEGOTIATE_NTLM                     = 0x00000200
	NEGOTIATE_ANONYMOUS                = 0x00000800
	NEGOTIATE_OEM_DOMAIN_SUPPLIED      = 0x00001000
	NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000
	NEGOTIATE_ALWAYS_SIGN              = 0x00008000
	NEGOTIATE_TARGET_TYPE_DOMAIN       = 0x00010000
	NEGOTIATE_TARGET_TYPE_SERVER       = 0x00020000
	NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000
	NEGOTIATE_IDENTIFY                 = 0x00100000
	REQUEST_NON_NT_SESSION_KEY         = 0x00400000
	NEGOTIATE_TARGET_INFO              = 0x00800000
	NEGOTIATE_VERSION                  = 0x02000000
	NEGOTIATE_128                      = 0x20000000
	NEGOTIATE_KEY_EXCH                 = 0x400000000
	NEGOTIATE_56                       = 0x80000000
)

const NEGOTIATE_FLAGS = NEGOTIATE_UNICODE |
	NEGOTIATE_NTLM |
	NEGOTIATE_OEM_DOMAIN_SUPPLIED |
	NEGOTIATE_OEM_WORKSTATION_SUPPLIED |
	NEGOTIATE_ALWAYS_SIGN /*|
	NEGOTIATE_EXTENDED_SESSIONSECURITY*/

type NTLMAuth struct {
	Domain      string
	UserName    string
	Password    string
	Workstation string
}

func getAuth(user, password, service, workstation string) (Auth, bool) {
	if !strings.ContainsRune(user, '\\') {
		return nil, false
	}
	domain_user := strings.SplitN(user, "\\", 2)
	return &NTLMAuth{
		Domain:      domain_user[0],
		UserName:    domain_user[1],
		Password:    password,
		Workstation: workstation,
	}, true
}

func utf16le(val string) []byte {
	var v []byte
	for _, r := range val {
		if utf16.IsSurrogate(r) {
			r1, r2 := utf16.EncodeRune(r)
			v = append(v, byte(r1), byte(r1>>8))
			v = append(v, byte(r2), byte(r2>>8))
		} else {
			v = append(v, byte(r), byte(r>>8))
		}
	}
	return v
}

func (auth *NTLMAuth) InitialBytes() ([]byte, error) {
	domain_len := len(auth.Domain)
	workstation_len := len(auth.Workstation)
	msg := make([]byte, 40+domain_len+workstation_len)
	copy(msg, []byte("NTLMSSP\x00"))
	binary.LittleEndian.PutUint32(msg[8:], NEGOTIATE_MESSAGE)
	binary.LittleEndian.PutUint32(msg[12:], NEGOTIATE_FLAGS)
	// Domain Name Fields
	binary.LittleEndian.PutUint16(msg[16:], uint16(domain_len))
	binary.LittleEndian.PutUint16(msg[18:], uint16(domain_len))
	binary.LittleEndian.PutUint32(msg[20:], 40)
	// Workstation Fields
	binary.LittleEndian.PutUint16(msg[24:], uint16(workstation_len))
	binary.LittleEndian.PutUint16(msg[26:], uint16(workstation_len))
	binary.LittleEndian.PutUint32(msg[28:], uint32(40+domain_len))
	// Version
	binary.LittleEndian.PutUint32(msg[32:], 0)
	binary.LittleEndian.PutUint32(msg[36:], 0)
	// Payload
	copy(msg[40:], auth.Domain)
	copy(msg[40+domain_len:], auth.Workstation)
	return msg, nil
}

var errorNTLM = errors.New("NTLM protocol error")

func createDesKey(dst, src []byte) {
	dst[0] = src[0]
	dst[1] = (src[1] >> 1) | (src[0] << 7)
	dst[2] = (src[2] >> 2) | (src[1] << 6)
	dst[3] = (src[3] >> 3) | (src[2] << 5)
	dst[4] = (src[4] >> 4) | (src[3] << 4)
	dst[5] = (src[5] >> 5) | (src[4] << 3)
	dst[6] = (src[6] >> 6) | (src[5] << 2)
	dst[7] = src[6] << 1
	oddParity(dst)
}

func oddParity(bytes []byte) {
	for i := 0; i < len(bytes); i++ {
		b := bytes[i]
		needsParity := (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1)) & 0x01) == 0
		if needsParity {
			bytes[i] = bytes[i] | byte(0x01)
		} else {
			bytes[i] = bytes[i] & byte(0xfe)
		}
	}
}

func encryptDes(key []byte, cleartext []byte, ciphertext []byte) error {
	var desKey [8]byte
	createDesKey(desKey[:], key)
	cipher, err := des.NewCipher(desKey[:])
	if err != nil {
		return err
	}
	cipher.Encrypt(ciphertext, cleartext)
	return nil
}

func response(challenge [8]byte, hash [21]byte) (ret [24]byte) {
	_ = encryptDes(hash[:7], challenge[:], ret[:8])
	_ = encryptDes(hash[7:14], challenge[:], ret[8:16])
	_ = encryptDes(hash[14:], challenge[:], ret[16:])
	return
}

func lmHash(password string) (hash [21]byte) {
	var lmpass [14]byte
	copy(lmpass[:14], []byte(strings.ToUpper(password)))
	magic := []byte("KGS!@#$%")
	_ = encryptDes(lmpass[:7], magic, hash[:8])
	_ = encryptDes(lmpass[7:], magic, hash[8:])
	return
}

func lmResponse(challenge [8]byte, password string) [24]byte {
	hash := lmHash(password)
	return response(challenge, hash)
}

func ntlmHash(password string) (hash [21]byte) {
	h := md4.New()
	h.Write(utf16le(password))
	h.Sum(hash[:0])
	return
}

func ntResponse(challenge [8]byte, password string) [24]byte {
	hash := ntlmHash(password)
	return response(challenge, hash)
}

func (auth *NTLMAuth) NextBytes(bytes []byte) ([]byte, error) {
	if string(bytes[0:8]) != "NTLMSSP\x00" {
		return nil, errorNTLM
	}
	if binary.LittleEndian.Uint32(bytes[8:12]) != CHALLENGE_MESSAGE {
		return nil, errorNTLM
	}
	flags := binary.LittleEndian.Uint32(bytes[12:16])
	var challenge [8]byte
	copy(challenge[:], bytes[24:32])

	lm := lmResponse(challenge, auth.Password)
	lm_len := len(lm)
	nt := ntResponse(challenge, auth.Password)
	nt_len := len(nt)

	domain16 := utf16le(auth.Domain)
	domain_len := len(domain16)
	user16 := utf16le(auth.UserName)
	user_len := len(user16)
	workstation16 := utf16le(auth.Workstation)
	workstation_len := len(workstation16)

	msg := make([]byte, 90+lm_len+nt_len+domain_len+user_len+workstation_len)
	copy(msg, []byte("NTLMSSP\x00"))
	binary.LittleEndian.PutUint32(msg[8:], AUTHENTICATE_MESSAGE)
	// Lm Challenge Response Fields
	binary.LittleEndian.PutUint16(msg[12:], uint16(lm_len))
	binary.LittleEndian.PutUint16(msg[14:], uint16(lm_len))
	binary.LittleEndian.PutUint32(msg[16:], 90)
	// Nt Challenge Response Fields
	binary.LittleEndian.PutUint16(msg[20:], uint16(nt_len))
	binary.LittleEndian.PutUint16(msg[22:], uint16(nt_len))
	binary.LittleEndian.PutUint32(msg[24:], uint32(90+lm_len))
	// Domain Name Fields
	binary.LittleEndian.PutUint16(msg[28:], uint16(domain_len))
	binary.LittleEndian.PutUint16(msg[30:], uint16(domain_len))
	binary.LittleEndian.PutUint32(msg[32:], uint32(90+lm_len+nt_len))
	// User Name Fields
	binary.LittleEndian.PutUint16(msg[36:], uint16(user_len))
	binary.LittleEndian.PutUint16(msg[38:], uint16(user_len))
	binary.LittleEndian.PutUint32(msg[40:], uint32(90+lm_len+nt_len+domain_len))
	// Workstation Fields
	binary.LittleEndian.PutUint16(msg[44:], uint16(workstation_len))
	binary.LittleEndian.PutUint16(msg[46:], uint16(workstation_len))
	binary.LittleEndian.PutUint32(msg[48:], uint32(90+lm_len+nt_len+domain_len+user_len))
	// Encrypted Random Session Key Fields
	binary.LittleEndian.PutUint16(msg[52:], 0)
	binary.LittleEndian.PutUint16(msg[54:], 0)
	binary.LittleEndian.PutUint32(msg[58:], uint32(90+lm_len+nt_len+domain_len+user_len+workstation_len))
	// Negotiate Flags
	binary.LittleEndian.PutUint32(msg[62:], flags)
	// Version
	binary.LittleEndian.PutUint32(msg[66:], 0)
	binary.LittleEndian.PutUint32(msg[70:], 0)
	// MIC
	binary.LittleEndian.PutUint32(msg[74:], 0)
	binary.LittleEndian.PutUint32(msg[78:], 0)
	binary.LittleEndian.PutUint32(msg[82:], 0)
	binary.LittleEndian.PutUint32(msg[86:], 0)
	// Payload
	copy(msg[90:], lm[:])
	copy(msg[90+lm_len:], nt[:])
	copy(msg[90+lm_len+nt_len:], domain16)
	copy(msg[90+lm_len+nt_len+domain_len:], user16)
	copy(msg[90+lm_len+nt_len+domain_len+user_len:], workstation16)
	return msg, nil
}

func (auth *NTLMAuth) Free() {
}
<|endoftext|>