<commit_before>package api

import (
	"encoding/json"
	"net"
	"net/http"

	"github.com/VividCortex/siesta"

	"github.com/PreetamJinka/cistern/device"
	"github.com/PreetamJinka/cistern/state/flows"
	"github.com/PreetamJinka/cistern/state/series"
)

type APIServer struct {
	addr           string
	deviceRegistry *device.Registry
	seriesEngine   *series.Engine
}

func NewAPIServer(address string, deviceRegistry *device.Registry, seriesEngine *series.Engine) *APIServer {
	return &APIServer{
		addr:           address,
		deviceRegistry: deviceRegistry,
		seriesEngine:   seriesEngine,
	}
}

func (s *APIServer) Run() {
	service := siesta.NewService("/")

	service.AddPre(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
	})

	service.AddPost(func(c siesta.Context, w http.ResponseWriter, r *http.Request, q func()) {
		resp := c.Get(responseKey)
		err, _ := c.Get(errorKey).(string)

		if resp == nil && err == "" {
			return
		}

		enc := json.NewEncoder(w)
		enc.Encode(APIResponse{
			Data:  resp,
			Error: err,
		})
	})

	service.Route("GET", "/", "Default page", func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set(responseKey, "Welcome to the Cistern API!")
	})

	service.Route("GET", "/devices", "Lists sources", func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		type ipHostname struct {
			IP       string `json:"ip"`
			Hostname string `json:"hostname,omitempty"`
		}

		devices := []ipHostname{}

		for _, dev := range s.deviceRegistry.Devices() {
			devices = append(devices, ipHostname{
				IP:       dev.IP().String(),
				Hostname: dev.Hostname(),
			})
		}

		c.Set(responseKey, devices)
	})

	service.Route("GET", "/devices/:device/metrics",
		"Lists metrics for a device",
		func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			device := params.String("device", "", "Device name")
			err := params.Parse(r.Form)
			if err != nil {
				c.Set(errorKey, err.Error())
				return
			}

			address := net.ParseIP(*device)
			dev, present := s.deviceRegistry.Lookup(address)
			if !present {
				c.Set(errorKey, "device not found")
				return
			}

			c.Set(responseKey, dev.Metrics())
		})

	service.Route("GET", "/devices/:device/flows",
		"Lists top flows for a device",
		func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			device := params.String("device", "", "Device name")
			err := params.Parse(r.Form)
			if err != nil {
				c.Set(errorKey, err.Error())
				return
			}

			address := net.ParseIP(*device)
			dev, present := s.deviceRegistry.Lookup(address)
			if !present {
				c.Set(errorKey, "device not found")
				return
			}

			type flowsResponse struct {
				ByBytes   []flows.Flow `json:"byBytes"`
				ByPackets []flows.Flow `json:"byPackets"`
			}

			topTalkers := dev.TopTalkers()
			if topTalkers == nil {
				c.Set(errorKey, "No active flows")
				return
			}

			resp := flowsResponse{
				ByBytes:   topTalkers.ByBytes(),
				ByPackets: topTalkers.ByPackets(),
			}

			c.Set(responseKey, resp)
		})

	service.Route("GET", "/series/query",
		"Lists metrics for a device",
		s.querySeriesRoute())

	http.Handle("/", service)

	go http.ListenAndServe(s.addr, nil)
}
<commit_msg>add POST queries<commit_after>package api

import (
	"encoding/json"
	"net"
	"net/http"

	"github.com/VividCortex/siesta"

	"github.com/PreetamJinka/cistern/device"
	"github.com/PreetamJinka/cistern/state/flows"
	"github.com/PreetamJinka/cistern/state/series"
)

type APIServer struct {
	addr           string
	deviceRegistry *device.Registry
	seriesEngine   *series.Engine
}

func NewAPIServer(address string, deviceRegistry *device.Registry, seriesEngine *series.Engine) *APIServer {
	return &APIServer{
		addr:           address,
		deviceRegistry: deviceRegistry,
		seriesEngine:   seriesEngine,
	}
}

func (s *APIServer) Run() {
	service := siesta.NewService("/")

	service.AddPre(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
	})

	service.AddPost(func(c siesta.Context, w http.ResponseWriter, r *http.Request, q func()) {
		resp := c.Get(responseKey)
		err, _ := c.Get(errorKey).(string)

		if resp == nil && err == "" {
			return
		}

		enc := json.NewEncoder(w)
		enc.Encode(APIResponse{
			Data:  resp,
			Error: err,
		})
	})

	service.Route("GET", "/", "Default page", func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		c.Set(responseKey, "Welcome to the Cistern API!")
	})

	service.Route("GET", "/devices", "Lists sources", func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
		type ipHostname struct {
			IP       string `json:"ip"`
			Hostname string `json:"hostname,omitempty"`
		}

		devices := []ipHostname{}

		for _, dev := range s.deviceRegistry.Devices() {
			devices = append(devices, ipHostname{
				IP:       dev.IP().String(),
				Hostname: dev.Hostname(),
			})
		}

		c.Set(responseKey, devices)
	})

	service.Route("GET", "/devices/:device/metrics",
		"Lists metrics for a device",
		func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			device := params.String("device", "", "Device name")
			err := params.Parse(r.Form)
			if err != nil {
				c.Set(errorKey, err.Error())
				return
			}

			address := net.ParseIP(*device)
			dev, present := s.deviceRegistry.Lookup(address)
			if !present {
				c.Set(errorKey, "device not found")
				return
			}

			c.Set(responseKey, dev.Metrics())
		})

	service.Route("GET", "/devices/:device/flows",
		"Lists top flows for a device",
		func(c siesta.Context, w http.ResponseWriter, r *http.Request) {
			var params siesta.Params
			device := params.String("device", "", "Device name")
			err := params.Parse(r.Form)
			if err != nil {
				c.Set(errorKey, err.Error())
				return
			}

			address := net.ParseIP(*device)
			dev, present := s.deviceRegistry.Lookup(address)
			if !present {
				c.Set(errorKey, "device not found")
				return
			}

			type flowsResponse struct {
				ByBytes   []flows.Flow `json:"byBytes"`
				ByPackets []flows.Flow `json:"byPackets"`
			}

			topTalkers := dev.TopTalkers()
			if topTalkers == nil {
				c.Set(errorKey, "No active flows")
				return
			}

			resp := flowsResponse{
				ByBytes:   topTalkers.ByBytes(),
				ByPackets: topTalkers.ByPackets(),
			}

			c.Set(responseKey, resp)
		})

	service.Route("GET", "/series/query",
		"Lists metrics for a device",
		s.querySeriesRoute())

	service.Route("POST", "/series/query",
		"Lists metrics for a device",
		s.querySeriesRoute())

	http.Handle("/", service)

	go http.ListenAndServe(s.addr, nil)
}
<|endoftext|>


<commit_before>//
// Copyright © 2011-2012 Guy M. Allard
//
// 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.
//

// Show a number of queue writers and readers operating concurrently.
// Try to be realistic about workloads.
// Receiver checks messages for proper queue and message number.

/*
Send and receive many STOMP messages using multiple queues and goroutines
to service each send or receive instance.  All senders share a single
STOMP connection, as do all receivers.
*/
package main

import (
	"crypto/rand"
	"flag"
	"fmt"
	"github.com/gmallard/stompngo"
	"github.com/gmallard/stompngo_examples/sngecomm"
	"log"
	"math/big"
	"net"
	"os"
	"runtime"
	"runtime/pprof"
	"strings"
	"sync"
	"time"
)

var exampid = "srmgor_11:"

var wgsend sync.WaitGroup
var wgrecv sync.WaitGroup
var wgall sync.WaitGroup

// We 'stagger' between each message send and message receive for a random
// amount of time.
// Vary these for experimental purposes.  YMMV.
var max int64 = 1e9      // Max stagger time (nanoseconds)
var min int64 = max / 10 // Min stagger time (nanoseconds)
// Vary these for experimental purposes.  YMMV.
var send_factor int64 = 1 // Send factor time
var recv_factor int64 = 1 // Receive factor time

// Wait flags
var send_wait = true
var recv_wait = true

// Possible profile file
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

// Get a duration between min amd max
func timeBetween(min, max int64) int64 {
	br, _ := rand.Int(rand.Reader, big.NewInt(max-min)) // Ignore errors here
	return (br.Add(big.NewInt(min), br).Int64()) / 2
}

// Send messages to a particular queue
func sender(conn *stompngo.Connection, qn, c int) {
	qns := fmt.Sprintf("%d", qn) // queue number
	fmt.Println(exampid, "send starts", qn)
	//
	qp := sngecomm.Dest() // queue name prefix
	q := qp + "." + qns
	fmt.Println(exampid, "send queue name", q, qn)
	h := stompngo.Headers{"destination", q} // send Headers
	if sngecomm.Persistent() {
		h = h.Add("persistent", "true")
	}
	// Send loop
	for i := 1; i <= c; i++ {
		si := fmt.Sprintf("%d", i)
		// Generate a message to send ...............
		m := exampid + "|" + "payload" + "|qnum:" + qns + "|msgnum:" + si
		fmt.Println(exampid, "send message", m, qn)
		e := conn.Send(h, m)
		if e != nil {
			log.Fatalln(exampid, "send error", e, qn)
			break
		}
		if send_wait {
			runtime.Gosched()                                              // yield for this example
			time.Sleep(time.Duration(send_factor * timeBetween(min, max))) // Time to build next message
		}
	}
	// Sending is done
	fmt.Println(exampid, "send ends", qn)
	wgsend.Done()
}

// Receive messages from a particular queue
func receiver(conn *stompngo.Connection, qn, c int) {
	qns := fmt.Sprintf("%d", qn) // queue number
	fmt.Println(exampid, "recv starts", qn)
	//
	qp := sngecomm.Dest() // queue name prefix
	q := qp + "." + qns
	fmt.Println(exampid, "recv queue name", q, qn)
	u := stompngo.Uuid() // A unique subscription ID
	h := stompngo.Headers{"destination", q, "id", u}
	// Subscribe
	r, e := conn.Subscribe(h)
	if e != nil {
		log.Fatalln(exampid, "recv subscribe error", e, qn)
	}
	// Receive loop
	for i := 1; i <= c; i++ {
		d := <-r
		if d.Error != nil {
			log.Fatalln(exampid, "recv read error", d.Error, qn)
		}

		// Process the inbound message .................
		m := d.Message.BodyString()
		fmt.Println(exampid, "recv message", m, qn)

		// Sanity check the queue and message numbers
		mns := fmt.Sprintf("%d", i) // message number
		t := "|qnum:" + qns + "|msgnum:" + mns
		if !strings.Contains(m, t) {
			log.Fatalln(exampid, "recv bad message", m, t, qn)
		}
		if recv_wait {
			runtime.Gosched()                                              // yield for this example
			time.Sleep(time.Duration(recv_factor * timeBetween(min, max))) // Time to process this message
		}
	}
	// Unsubscribe
	e = conn.Unsubscribe(h)
	if e != nil {
		log.Fatalln(exampid, "recv unsubscribe error", e, qn)
	}
	// Receiving is done
	fmt.Println(exampid, "recv ends", qn)
	wgrecv.Done()
}

func startSenders(qn int) {
	fmt.Println(exampid, "startSenders starts", qn)

	// Open
	h, p := sngecomm.HostAndPort11() // a 1.1 connect
	n, e := net.Dial("tcp", net.JoinHostPort(h, p))
	if e != nil {
		log.Fatalln(exampid, "startSenders netconnect error", e, qn) // Handle this ......
	}

	// Stomp connect, 1.1
	ch := stompngo.Headers{"host", sngecomm.Vhost(), "accept-version", "1.1"}
	conn, e := stompngo.Connect(n, ch)
	if e != nil {
		log.Fatalln(exampid, "startSenders stompconnect error", e, qn) // Handle this ......
	}
	log.Println(exampid, "startSenders connection", conn, qn)
	c := sngecomm.Nmsgs() // message count
	fmt.Println(exampid, "startSenders message count", c, qn)
	for i := 1; i <= qn; i++ { // all queues
		wgsend.Add(1)
		go sender(conn, i, c)
	}
	wgsend.Wait()

	// Disconnect from Stomp server
	eh := stompngo.Headers{}
	e = conn.Disconnect(eh)
	if e != nil {
		log.Println(exampid, "startSenders disconnect error", e, qn) // Handle this ......
	}
	// Network close
	e = n.Close()
	if e != nil {
		log.Fatalln(exampid, "startSenders netclose error", e, qn) // Handle this ......
	}

	fmt.Println(exampid, "startSenders ends", qn)
	sngecomm.ShowStats(exampid, "startSenders", conn)
	wgall.Done()
}

func startReceivers(qn int) {
	fmt.Println(exampid, "startReceivers starts", qn)

	// Open
	h, p := sngecomm.HostAndPort11() // a 1.1 connect
	n, e := net.Dial("tcp", net.JoinHostPort(h, p))
	if e != nil {
		log.Fatalln(exampid, "startReceivers nectonnr:", e, qn) // Handle this ......
	}
	ch := stompngo.Headers{"host", sngecomm.Vhost(), "accept-version", "1.1"}
	conn, e := stompngo.Connect(n, ch)
	if e != nil {
		log.Fatalln("startReceivers stompconnectr:", e, qn) // Handle this ......
	}
	log.Println("startReceivers Receive connection is:", conn, qn)
	c := sngecomm.Nmsgs() // get message count
	fmt.Println(exampid, "startReceivers message count", c, qn)
	for i := 1; i <= qn; i++ { // all queues
		wgrecv.Add(1)
		go receiver(conn, i, c)
	}
	wgrecv.Wait()

	// Disconnect from Stomp server
	eh := stompngo.Headers{}
	e = conn.Disconnect(eh)
	if e != nil {
		log.Println(exampid, "startReceivers disconnect error", e, qn) // Handle this ......
	}
	// Network close
	e = n.Close()
	if e != nil {
		log.Println(exampid, "startReceivers netclose error", e, qn) // Handle this ......
	}

	fmt.Println(exampid, "startReceivers ends", qn)
	sngecomm.ShowStats(exampid, "startReceivers", conn)
	wgall.Done()
}

// Show a number of writers and readers operating concurrently from unique
// destinations.
func main() {
	fmt.Println(exampid, "main starts")

	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if sngecomm.SetMAXPROCS() {
		nc := runtime.NumCPU()
		fmt.Println(exampid, "main number of CPUs is:", nc)
		c := runtime.GOMAXPROCS(nc)
		fmt.Println(exampid, "main previous number of GOMAXPROCS is:", c)
		fmt.Println(exampid, "main current number of GOMAXPROCS is:", runtime.GOMAXPROCS(-1))
	}
	//
	send_wait = sngecomm.SendWait()
	recv_wait = sngecomm.RecvWait()
	//
	q := sngecomm.Nqs()
	fmt.Println(exampid, "main Nqs:", q)
	//
	wgall.Add(2)
	go startReceivers(q)
	go startSenders(q)
	wgall.Wait()

	fmt.Println(exampid, "main ends")
}
<commit_msg>Performance enhancement #1: 1 connection with many consumers.<commit_after>//
// Copyright © 2011-2012 Guy M. Allard
//
// 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.
//

// Show a number of queue writers and readers operating concurrently.
// Try to be realistic about workloads.
// Receiver checks messages for proper queue and message number.

/*
Send and receive many STOMP messages using multiple queues and goroutines
to service each send or receive instance.  All senders share a single
STOMP connection, as do all receivers.
*/
package main

import (
	"crypto/rand"
	"flag"
	"fmt"
	"github.com/gmallard/stompngo"
	"github.com/gmallard/stompngo_examples/sngecomm"
	"log"
	"math/big"
	"net"
	"os"
	"runtime"
	"runtime/pprof"
	"strings"
	"sync"
	"time"
)

var exampid = "srmgor_11:"

var wgsend sync.WaitGroup
var wgrecv sync.WaitGroup
var wgall sync.WaitGroup

// We 'stagger' between each message send and message receive for a random
// amount of time.
// Vary these for experimental purposes.  YMMV.
var max int64 = 1e9      // Max stagger time (nanoseconds)
var min int64 = max / 10 // Min stagger time (nanoseconds)
// Vary these for experimental purposes.  YMMV.
var send_factor int64 = 1 // Send factor time
var recv_factor int64 = 1 // Receive factor time

// Wait flags
var send_wait = true
var recv_wait = true

// Possible profile file
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

// Get a duration between min amd max
func timeBetween(min, max int64) int64 {
	br, _ := rand.Int(rand.Reader, big.NewInt(max-min)) // Ignore errors here
	return (br.Add(big.NewInt(min), br).Int64()) / 2
}

// Send messages to a particular queue
func sender(conn *stompngo.Connection, qn, c int) {
	qns := fmt.Sprintf("%d", qn) // queue number
	fmt.Println(exampid, "send starts", qn)
	//
	qp := sngecomm.Dest() // queue name prefix
	q := qp + "." + qns
	fmt.Println(exampid, "send queue name", q, qn)
	h := stompngo.Headers{"destination", q} // send Headers
	if sngecomm.Persistent() {
		h = h.Add("persistent", "true")
	}
	// Send loop
	for i := 1; i <= c; i++ {
		si := fmt.Sprintf("%d", i)
		// Generate a message to send ...............
		m := exampid + "|" + "payload" + "|qnum:" + qns + "|msgnum:" + si
		fmt.Println(exampid, "send message", m, qn)
		e := conn.Send(h, m)
		if e != nil {
			log.Fatalln(exampid, "send error", e, qn)
			break
		}
		if send_wait {
			runtime.Gosched()                                              // yield for this example
			time.Sleep(time.Duration(send_factor * timeBetween(min, max))) // Time to build next message
		}
	}
	// Sending is done
	fmt.Println(exampid, "send ends", qn)
	wgsend.Done()
}

// Asynchronously process all messages for a given subscription.
func receiveWorker(mc chan stompngo.MessageData, qns string, c int, d chan bool) {
	// Receive loop
	for i := 1; i <= c; i++ {
		d := <-mc
		if d.Error != nil {
			log.Fatalln(exampid, "recv read error", d.Error, qns)
		}

		// Process the inbound message .................
		m := d.Message.BodyString()
		fmt.Println(exampid, "recv message", m, qns)

		// Sanity check the queue and message numbers
		mns := fmt.Sprintf("%d", i) // message number
		t := "|qnum:" + qns + "|msgnum:" + mns
		if !strings.Contains(m, t) {
			log.Fatalln(exampid, "recv bad message", m, t, qns)
		}
		if recv_wait {
			runtime.Gosched()                                              // yield for this example
			time.Sleep(time.Duration(recv_factor * timeBetween(min, max))) // Time to process this message
		}
	}
	//
	d <- true
}

// Receive messages from a particular queue
func receiver(conn *stompngo.Connection, qn, c int) {
	qns := fmt.Sprintf("%d", qn) // queue number
	fmt.Println(exampid, "recv starts", qn)
	//
	qp := sngecomm.Dest() // queue name prefix
	q := qp + "." + qns
	fmt.Println(exampid, "recv queue name", q, qn)
	u := stompngo.Uuid() // A unique subscription ID
	h := stompngo.Headers{"destination", q, "id", u}
	// Subscribe
	r, e := conn.Subscribe(h)
	if e != nil {
		log.Fatalln(exampid, "recv subscribe error", e, qn)
	}

	// Many receivers running under the same connection can cause
	// (wire read) performance issues.  This is *very* dependent on the broker
	// being used, specifically the broker's algorithm for putting messages on
	// the wire.
	// To alleviate those issues, this strategy insures that messages are
	// received from the wire as soon as possible.  Those messages are then
	// buffered internally for (possibly later) application processing.

	// Process all inputs async .......
	mc := make(chan stompngo.MessageData, c) // All messages we could possibly get, YMMV
	dc := make(chan bool)                    // Receive processing done channel
	go receiveWorker(mc, qns, c, dc)         // Start async processor
	for i := 1; i <= c; i++ {
		mc <- <-r // Receive message data as soon as possible, and internally queue it
	}
	<-dc // Wait until receive processing is done

	// Unsubscribe
	e = conn.Unsubscribe(h)
	if e != nil {
		log.Fatalln(exampid, "recv unsubscribe error", e, qn)
	}
	// Receiving is done
	fmt.Println(exampid, "recv ends", qn)
	wgrecv.Done()
}

func startSenders(qn int) {
	fmt.Println(exampid, "startSenders starts", qn)

	// Open
	h, p := sngecomm.HostAndPort11() // a 1.1 connect
	n, e := net.Dial("tcp", net.JoinHostPort(h, p))
	if e != nil {
		log.Fatalln(exampid, "startSenders netconnect error", e, qn) // Handle this ......
	}

	// Stomp connect, 1.1
	ch := stompngo.Headers{"host", sngecomm.Vhost(), "accept-version", "1.1"}
	conn, e := stompngo.Connect(n, ch)
	if e != nil {
		log.Fatalln(exampid, "startSenders stompconnect error", e, qn) // Handle this ......
	}
	log.Println(exampid, "startSenders connection", conn, qn)
	c := sngecomm.Nmsgs() // message count
	fmt.Println(exampid, "startSenders message count", c, qn)
	for i := 1; i <= qn; i++ { // all queues
		wgsend.Add(1)
		go sender(conn, i, c)
	}
	wgsend.Wait()

	// Disconnect from Stomp server
	eh := stompngo.Headers{}
	e = conn.Disconnect(eh)
	if e != nil {
		log.Println(exampid, "startSenders disconnect error", e, qn) // Handle this ......
	}
	// Network close
	e = n.Close()
	if e != nil {
		log.Fatalln(exampid, "startSenders netclose error", e, qn) // Handle this ......
	}

	fmt.Println(exampid, "startSenders ends", qn)
	sngecomm.ShowStats(exampid, "startSenders", conn)
	wgall.Done()
}

func startReceivers(qn int) {
	fmt.Println(exampid, "startReceivers starts", qn)

	// Open
	h, p := sngecomm.HostAndPort11() // a 1.1 connect
	n, e := net.Dial("tcp", net.JoinHostPort(h, p))
	if e != nil {
		log.Fatalln(exampid, "startReceivers nectonnr:", e, qn) // Handle this ......
	}
	ch := stompngo.Headers{"host", sngecomm.Vhost(), "accept-version", "1.1"}
	conn, e := stompngo.Connect(n, ch)
	if e != nil {
		log.Fatalln("startReceivers stompconnectr:", e, qn) // Handle this ......
	}
	log.Println("startReceivers Receive connection is:", conn, qn)
	c := sngecomm.Nmsgs() // get message count
	fmt.Println(exampid, "startReceivers message count", c, qn)
	for i := 1; i <= qn; i++ { // all queues
		wgrecv.Add(1)
		go receiver(conn, i, c)
	}
	wgrecv.Wait()

	// Disconnect from Stomp server
	eh := stompngo.Headers{}
	e = conn.Disconnect(eh)
	if e != nil {
		log.Println(exampid, "startReceivers disconnect error", e, qn) // Handle this ......
	}
	// Network close
	e = n.Close()
	if e != nil {
		log.Println(exampid, "startReceivers netclose error", e, qn) // Handle this ......
	}

	fmt.Println(exampid, "startReceivers ends", qn)
	sngecomm.ShowStats(exampid, "startReceivers", conn)
	wgall.Done()
}

// Show a number of writers and readers operating concurrently from unique
// destinations.
func main() {
	fmt.Println(exampid, "main starts")

	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	if sngecomm.SetMAXPROCS() {
		nc := runtime.NumCPU()
		fmt.Println(exampid, "main number of CPUs is:", nc)
		c := runtime.GOMAXPROCS(nc)
		fmt.Println(exampid, "main previous number of GOMAXPROCS is:", c)
		fmt.Println(exampid, "main current number of GOMAXPROCS is:", runtime.GOMAXPROCS(-1))
	}
	//
	send_wait = sngecomm.SendWait()
	recv_wait = sngecomm.RecvWait()
	//
	q := sngecomm.Nqs()
	fmt.Println(exampid, "main Nqs:", q)
	//
	wgall.Add(2)
	go startReceivers(q)
	go startSenders(q)
	wgall.Wait()

	fmt.Println(exampid, "main ends")
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"net"

	"golang.org/x/crypto/ssh"

	"github.com/tg123/sshpiper/sshpiperd/auditor"
	"github.com/tg123/sshpiper/sshpiperd/challenger"
	"github.com/tg123/sshpiper/sshpiperd/upstream"
)

type piperdConfig struct {
	ListenAddr   string `short:"l" long:"listen" description:"Listening Address" default:"0.0.0.0" env:"SSHPIPERD_LISTENADDR" ini-name:"listen-address"`
	Port         uint   `short:"p" long:"port" description:"Listening Port" default:"2222" env:"SSHPIPERD_PORT" ini-name:"listen-port"`
	PiperKeyFile string `short:"i" long:"server-key" description:"Server key file for SSH Piper" default:"/etc/ssh/ssh_host_rsa_key" env:"SSHPIPERD_SERVER_KEY" ini-name:"server-key"`

	UpstreamDriver   string `short:"u" long:"upstream-driver" description:"Upstream provider driver" default:"workingdir" env:"SSHPIPERD_UPSTREAM_DRIVER" ini-name:"upstream-driver"`
	ChallengerDriver string `short:"c" long:"challenger-driver" description:"Additional challenger name, e.g. pam, empty for no additional challenge" env:"SSHPIPERD_CHALLENGER" ini-name:"challenger-driver"`
	AuditorDriver    string `long:"auditor-driver" description:"Auditor for ssh connections piped by SSH Piper " env:"SSHPIPERD_AUDITOR" ini-name:"auditor-driver"`
}

func startPiper(config *piperdConfig) {

	logger.Println("sshpiper is about to start")

	// install upstream driver
	upstream := upstream.Get(config.UpstreamDriver)
	if upstream == nil {
		logger.Fatalf("upstream driver %v not found", config.UpstreamDriver)
	}
	upstream.Init(logger)

	piper := &ssh.SSHPiperConfig{
		FindUpstream: upstream.GetFindUpstreamHandle(),
	}

	// install challenger
	if config.ChallengerDriver != "" {
		ac := challenger.Get(config.ChallengerDriver)
		if ac == nil {
			logger.Fatalf("challenger driver %v not found", config.ChallengerDriver)
		}

		logger.Printf("using additional challenger %s", config.ChallengerDriver)
		ac.Init(logger)

		logger.Printf("%v", ac.GetChallengerHandler())
		piper.AdditionalChallenge = ac.GetChallengerHandler()
	}

	var bigbro auditor.AuditorProvider
	// install auditor
	if config.AuditorDriver != "" {
		bigbro = auditor.Get(config.AuditorDriver)

		if bigbro == nil {
			logger.Fatalf("auditor driver %v not found", config.AuditorDriver)
		}

		logger.Printf("using auditor %s", config.AuditorDriver)
		bigbro.Init(logger)
	}

	privateBytes, err := ioutil.ReadFile(config.PiperKeyFile)
	if err != nil {
		logger.Fatalln(err)
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		logger.Fatalln(err)
	}

	piper.AddHostKey(private)

	listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.ListenAddr, config.Port))
	if err != nil {
		logger.Fatalln("failed to listen for connection: %v", err)
	}
	defer listener.Close()

	logger.Printf("SSHPiperd started")

	for {
		c, err := listener.Accept()
		if err != nil {
			logger.Printf("failed to accept connection: %v", err)
			continue
		}

		logger.Printf("connection accepted: %v", c.RemoteAddr())
		go func() {
			p, err := ssh.NewSSHPiperConn(c, piper)

			if err != nil {
				logger.Printf("connection from %v establishing failed reason: %v", c.RemoteAddr(), err)
				return
			}

			if bigbro != nil {
				a, err := bigbro.CreateAuditor(p.DownstreamConnMeta())
				if err != nil {
					logger.Printf("connection from %v failed to create auditor reason: %v", c.RemoteAddr(), err)
					return
				}
				defer a.Close()

				p.HookUpstreamMsg = a.GetUpstreamHook()
				p.HookDownstreamMsg = a.GetDownstreamHook()

			}

			err = p.Wait()
			logger.Printf("connection from %v closed reason: %v", c.RemoteAddr(), err)
		}()
	}
}
<commit_msg>remove unused log<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net"

	"golang.org/x/crypto/ssh"

	"github.com/tg123/sshpiper/sshpiperd/auditor"
	"github.com/tg123/sshpiper/sshpiperd/challenger"
	"github.com/tg123/sshpiper/sshpiperd/upstream"
)

type piperdConfig struct {
	ListenAddr   string `short:"l" long:"listen" description:"Listening Address" default:"0.0.0.0" env:"SSHPIPERD_LISTENADDR" ini-name:"listen-address"`
	Port         uint   `short:"p" long:"port" description:"Listening Port" default:"2222" env:"SSHPIPERD_PORT" ini-name:"listen-port"`
	PiperKeyFile string `short:"i" long:"server-key" description:"Server key file for SSH Piper" default:"/etc/ssh/ssh_host_rsa_key" env:"SSHPIPERD_SERVER_KEY" ini-name:"server-key"`

	UpstreamDriver   string `short:"u" long:"upstream-driver" description:"Upstream provider driver" default:"workingdir" env:"SSHPIPERD_UPSTREAM_DRIVER" ini-name:"upstream-driver"`
	ChallengerDriver string `short:"c" long:"challenger-driver" description:"Additional challenger name, e.g. pam, empty for no additional challenge" env:"SSHPIPERD_CHALLENGER" ini-name:"challenger-driver"`
	AuditorDriver    string `long:"auditor-driver" description:"Auditor for ssh connections piped by SSH Piper " env:"SSHPIPERD_AUDITOR" ini-name:"auditor-driver"`
}

func startPiper(config *piperdConfig) {

	logger.Println("sshpiper is about to start")

	// install upstream driver
	upstream := upstream.Get(config.UpstreamDriver)
	if upstream == nil {
		logger.Fatalf("upstream driver %v not found", config.UpstreamDriver)
	}
	upstream.Init(logger)

	piper := &ssh.SSHPiperConfig{
		FindUpstream: upstream.GetFindUpstreamHandle(),
	}

	// install challenger
	if config.ChallengerDriver != "" {
		ac := challenger.Get(config.ChallengerDriver)
		if ac == nil {
			logger.Fatalf("challenger driver %v not found", config.ChallengerDriver)
		}

		logger.Printf("using additional challenger %s", config.ChallengerDriver)
		ac.Init(logger)

		piper.AdditionalChallenge = ac.GetChallengerHandler()
	}

	var bigbro auditor.AuditorProvider
	// install auditor
	if config.AuditorDriver != "" {
		bigbro = auditor.Get(config.AuditorDriver)

		if bigbro == nil {
			logger.Fatalf("auditor driver %v not found", config.AuditorDriver)
		}

		logger.Printf("using auditor %s", config.AuditorDriver)
		bigbro.Init(logger)
	}

	privateBytes, err := ioutil.ReadFile(config.PiperKeyFile)
	if err != nil {
		logger.Fatalln(err)
	}

	private, err := ssh.ParsePrivateKey(privateBytes)
	if err != nil {
		logger.Fatalln(err)
	}

	piper.AddHostKey(private)

	listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", config.ListenAddr, config.Port))
	if err != nil {
		logger.Fatalln("failed to listen for connection: %v", err)
	}
	defer listener.Close()

	logger.Printf("SSHPiperd started")

	for {
		c, err := listener.Accept()
		if err != nil {
			logger.Printf("failed to accept connection: %v", err)
			continue
		}

		logger.Printf("connection accepted: %v", c.RemoteAddr())
		go func() {
			p, err := ssh.NewSSHPiperConn(c, piper)

			if err != nil {
				logger.Printf("connection from %v establishing failed reason: %v", c.RemoteAddr(), err)
				return
			}

			if bigbro != nil {
				a, err := bigbro.CreateAuditor(p.DownstreamConnMeta())
				if err != nil {
					logger.Printf("connection from %v failed to create auditor reason: %v", c.RemoteAddr(), err)
					return
				}
				defer a.Close()

				p.HookUpstreamMsg = a.GetUpstreamHook()
				p.HookDownstreamMsg = a.GetDownstreamHook()

			}

			err = p.Wait()
			logger.Printf("connection from %v closed reason: %v", c.RemoteAddr(), err)
		}()
	}
}
<|endoftext|>


<commit_before>package api

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
        "fmt"
        "strings"

	"github.com/gin-gonic/gin"
        "github.com/aptly-dev/aptly/pgp"
)

// POST /api/gpg
func apiGPGAddKey(c *gin.Context) {
	var b struct {
		Keyserver   string
		GpgKeyID    string
		GpgKeyArmor string
		Keyring     string
	}

	if c.Bind(&b) != nil {
		return
	}

	var err error
	args := []string{"--no-default-keyring"}
	keyring := "trustedkeys.gpg"
	if len(b.Keyring) > 0 {
		keyring = b.Keyring
	}
	args = append(args, "--keyring", keyring)
	if len(b.Keyserver) > 0 {
		args = append(args, "--keyserver", b.Keyserver)
	}
	if len(b.GpgKeyArmor) > 0 {
		var tempdir string
		tempdir, err = ioutil.TempDir(os.TempDir(), "aptly")
		if err != nil {
			c.AbortWithError(400, err)
			return
		}
		defer os.RemoveAll(tempdir)

		keypath := filepath.Join(tempdir, "key")
		keyfile, e := os.Create(keypath)
		if e != nil {
			c.AbortWithError(400, e)
			return
		}
		if _, e = keyfile.WriteString(b.GpgKeyArmor); e != nil {
			c.AbortWithError(400, e)
		}
		args = append(args, "--import", keypath)

	}
	if len(b.GpgKeyID) > 0 {
		args = append(args, "--recv-keys", b.GpgKeyID)
	}

        finder := pgp.GPG1Finder()
	gpg, _, err := finder.FindGPG()
	if err != nil {
            c.AbortWithError(400, err)
            return
        }

	// it might happened that we have a situation with an erroneous
	// gpg command (e.g. when GpgKeyID and GpgKeyArmor is set).
	// there is no error handling for such as gpg will do this for us
	cmd := exec.Command(gpg, args...)
        fmt.Printf("running %s %s\n", gpg, strings.Join(args, " "))
	cmd.Stdout = os.Stdout
	if err = cmd.Run(); err != nil {
		c.AbortWithError(400, err)
		return
	}

	c.JSON(200, gin.H{})
}
<commit_msg>gpg: fix downloading multiple keys<commit_after>package api

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
        "fmt"
        "strings"

	"github.com/gin-gonic/gin"
        "github.com/aptly-dev/aptly/pgp"
)

// POST /api/gpg
func apiGPGAddKey(c *gin.Context) {
	var b struct {
		Keyserver   string
		GpgKeyID    string
		GpgKeyArmor string
		Keyring     string
	}

	if c.Bind(&b) != nil {
		return
	}

	var err error
	args := []string{"--no-default-keyring"}
	keyring := "trustedkeys.gpg"
	if len(b.Keyring) > 0 {
		keyring = b.Keyring
	}
	args = append(args, "--keyring", keyring)
	if len(b.Keyserver) > 0 {
		args = append(args, "--keyserver", b.Keyserver)
	}
	if len(b.GpgKeyArmor) > 0 {
		var tempdir string
		tempdir, err = ioutil.TempDir(os.TempDir(), "aptly")
		if err != nil {
			c.AbortWithError(400, err)
			return
		}
		defer os.RemoveAll(tempdir)

		keypath := filepath.Join(tempdir, "key")
		keyfile, e := os.Create(keypath)
		if e != nil {
			c.AbortWithError(400, e)
			return
		}
		if _, e = keyfile.WriteString(b.GpgKeyArmor); e != nil {
			c.AbortWithError(400, e)
		}
		args = append(args, "--import", keypath)

	}
	if len(b.GpgKeyID) > 0 {
                keys := strings.Fields(b.GpgKeyID)
		args = append(args, "--recv-keys")
		args = append(args, keys...)
	}

        finder := pgp.GPG1Finder()
	gpg, _, err := finder.FindGPG()
	if err != nil {
            c.AbortWithError(400, err)
            return
        }

	// it might happened that we have a situation with an erroneous
	// gpg command (e.g. when GpgKeyID and GpgKeyArmor is set).
	// there is no error handling for such as gpg will do this for us
	cmd := exec.Command(gpg, args...)
        fmt.Printf("running %s %s\n", gpg, strings.Join(args, " "))
	cmd.Stdout = os.Stdout
	if err = cmd.Run(); err != nil {
		c.AbortWithError(400, err)
		return
	}

	c.JSON(200, gin.H{})
}
<|endoftext|>


<commit_before>package tagmatcher

import (
	"strings"
)

type MatcherExact struct {
}

func (m *MatcherExact) Filter(tags []TagPather, pattern string) []*Result {
	results := []*Result{}

	//fmt.Printf("================ %s\n", pattern)
	patternItems := strings.Split(pattern, "/")

	fidx := make([]int, len(tags))
	for idx, tag := range tags {
		pitems := tag.PathItems()
		fidx[idx] = len(pitems)
	}

	for patIdx := len(patternItems) - 1; patIdx >= 0; patIdx-- {
		patPart := patternItems[patIdx]
		//fmt.Printf("---------- %s\n", patPart)
		res := NewResult()

	Tags:
		for idx, tag := range tags {
			pitems := tag.PathItems()
			//fmt.Printf("* %d: %v\n", idx, pitems)
			for pathCompIdx := fidx[idx] - 1; pathCompIdx >= 0; pathCompIdx-- {
				for nameIdx, tagName := range pitems[pathCompIdx] {
					//fmt.Printf("* %s (%s)\n", tagName, patPart)
					prio := NoMatch
					if tagName == patPart {
						prio = ExactMatch
					} else if strings.HasPrefix(tagName, patPart) {
						prio = BeginMatch
					} else if strings.HasSuffix(tagName, patPart) {
						prio = EndMatch
					} else if strings.Contains(tagName, patPart) {
						prio = MiddleMatch
					}

					if prio != NoMatch {
						res.Add(idx, prio)
						fidx[idx] = pathCompIdx
						tag.SetMatchDetails(pathCompIdx, nameIdx)
						continue Tags
					}
				}
			}
		}

		if res.Len() == 0 {
			return []*Result{}
		}

		results = append(results, res)
	}

	return results
}
<commit_msg>Fix the case when there's no match<commit_after>package tagmatcher

import (
	"strings"
)

type MatcherExact struct {
}

func (m *MatcherExact) Filter(tags []TagPather, pattern string) []*Result {
	results := []*Result{}

	//fmt.Printf("================ %s\n", pattern)
	patternItems := strings.Split(pattern, "/")

	fidx := make([]int, len(tags))
	for idx, tag := range tags {
		pitems := tag.PathItems()
		fidx[idx] = len(pitems)
	}

	for patIdx := len(patternItems) - 1; patIdx >= 0; patIdx-- {
		patPart := patternItems[patIdx]
		//fmt.Printf("---------- %s\n", patPart)
		res := NewResult()

	Tags:
		for idx, tag := range tags {
			pitems := tag.PathItems()
			//fmt.Printf("* %d: %v\n", idx, pitems)
			for pathCompIdx := fidx[idx] - 1; pathCompIdx >= 0; pathCompIdx-- {
				for nameIdx, tagName := range pitems[pathCompIdx] {
					//fmt.Printf("* %s (%s)\n", tagName, patPart)
					prio := NoMatch
					if tagName == patPart {
						prio = ExactMatch
					} else if strings.HasPrefix(tagName, patPart) {
						prio = BeginMatch
					} else if strings.HasSuffix(tagName, patPart) {
						prio = EndMatch
					} else if strings.Contains(tagName, patPart) {
						prio = MiddleMatch
					}

					if prio != NoMatch {
						res.Add(idx, prio)
						fidx[idx] = pathCompIdx
						tag.SetMatchDetails(pathCompIdx, nameIdx)
						continue Tags
					}
				}
			}
		}

		if res.Len() == 0 {
			return []*Result{res}
		}

		results = append(results, res)
	}

	return results
}
<|endoftext|>


<commit_before>package stats

import (
	"bufio"
	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/mem"
	"github.com/shirou/gopsutil/net"
)

func getRootContainerInfo(count int) (containerInfo, error) {
	rootInfo := containerInfo{}
	rootStats := []containerStats{}
	for i := 0; i < count; i++ {
		stats := containerStats{}
		// cpu
		cpuPerStats, err := cpu.Times(true)
		if err != nil {
			return containerInfo{}, err
		}
		cpuStats, err := cpu.Times(false)
		if err != nil {
			return containerInfo{}, err
		}
		stats.CPU.Usage.PerCPU = []uint64{}
		for _, perStats := range cpuPerStats {
			stats.CPU.Usage.PerCPU = append(stats.CPU.Usage.PerCPU, uint64(perStats.User+perStats.System)*1000000000)
		}
		if len(cpuStats) > 0 {
			stats.CPU.Usage.Total = uint64(cpuStats[0].User+cpuStats[0].System+cpuStats[0].Idle) * 1000000000
			stats.CPU.Usage.User = uint64(cpuStats[0].User) * 1000000000
			stats.CPU.Usage.System = uint64(cpuStats[0].System) * 1000000000
		}
		// memory
		memStats, err := mem.VirtualMemory()
		if err != nil {
			return containerInfo{}, err
		}
		stats.Memory.Usage = memStats.Used
		//disk
		diskIo, err := disk.IOCounters()
		if err != nil {
			return containerInfo{}, err
		}
		readBytes := uint64(0)
		writeBytes := uint64(0)
		for _, io := range diskIo {
			readBytes += io.ReadBytes
			writeBytes += io.WriteBytes
		}
		stats.DiskIo.IoServiceBytes = []PerDiskStats{}
		stats.DiskIo.IoServiceBytes = append(stats.DiskIo.IoServiceBytes, PerDiskStats{})
		stats.DiskIo.IoServiceBytes[0].Stats = map[string]uint64{}
		stats.DiskIo.IoServiceBytes[0].Stats["Read"] = readBytes
		stats.DiskIo.IoServiceBytes[0].Stats["Write"] = writeBytes
		//network
		netStats, err := net.IOCounters(false)
		if err != nil {
			return containerInfo{}, err
		}
		if len(netStats) > 0 {
			stats.Network.Name = netStats[0].Name
			stats.Network.RxBytes = netStats[0].BytesRecv
			stats.Network.TxBytes = netStats[0].BytesSent
		}
		rootStats = append(rootStats, stats)
	}
	rootInfo.Stats = rootStats
	return rootInfo, nil
}

func getAllDockerContainers(readers []*bufio.Reader, count int, IDList []string, pids []int) ([]containerInfo, error) {
	ret := []containerInfo{}
	for i, reader := range readers {
		contInfo, err := getContainerStats(reader, count, IDList[i], pids[i])
		if err != nil {
			return []containerInfo{}, err
		}
		ret = append(ret, contInfo)
	}
	return ret, nil
}
<commit_msg>don't lose decimal for flt<commit_after>package stats

import (
	"bufio"
	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/disk"
	"github.com/shirou/gopsutil/mem"
	"github.com/shirou/gopsutil/net"
)

func getRootContainerInfo(count int) (containerInfo, error) {
	rootInfo := containerInfo{}
	rootStats := []containerStats{}
	for i := 0; i < count; i++ {
		stats := containerStats{}
		// cpu
		cpuPerStats, err := cpu.Times(true)
		if err != nil {
			return containerInfo{}, err
		}
		cpuStats, err := cpu.Times(false)
		if err != nil {
			return containerInfo{}, err
		}
		stats.CPU.Usage.PerCPU = []uint64{}
		for _, perStats := range cpuPerStats {
			stats.CPU.Usage.PerCPU = append(stats.CPU.Usage.PerCPU, uint64((perStats.User+perStats.System)*1000000000))
		}
		if len(cpuStats) > 0 {
			stats.CPU.Usage.Total = uint64((cpuStats[0].User + cpuStats[0].System + cpuStats[0].Idle + cpuStats[0].Guest +
				cpuStats[0].Iowait + cpuStats[0].GuestNice + cpuStats[0].Steal +
				cpuStats[0].Stolen + cpuStats[0].Irq + cpuStats[0].Softirq) * 1000000000)
			stats.CPU.Usage.User = uint64((cpuStats[0].User) * 1000000000)
			stats.CPU.Usage.System = uint64((cpuStats[0].System) * 1000000000)
		}
		// memory
		memStats, err := mem.VirtualMemory()
		if err != nil {
			return containerInfo{}, err
		}
		stats.Memory.Usage = memStats.Used
		//disk
		diskIo, err := disk.IOCounters()
		if err != nil {
			return containerInfo{}, err
		}
		readBytes := uint64(0)
		writeBytes := uint64(0)
		for _, io := range diskIo {
			readBytes += io.ReadBytes
			writeBytes += io.WriteBytes
		}
		stats.DiskIo.IoServiceBytes = []PerDiskStats{}
		stats.DiskIo.IoServiceBytes = append(stats.DiskIo.IoServiceBytes, PerDiskStats{})
		stats.DiskIo.IoServiceBytes[0].Stats = map[string]uint64{}
		stats.DiskIo.IoServiceBytes[0].Stats["Read"] = readBytes
		stats.DiskIo.IoServiceBytes[0].Stats["Write"] = writeBytes
		//network
		netStats, err := net.IOCounters(false)
		if err != nil {
			return containerInfo{}, err
		}
		if len(netStats) > 0 {
			stats.Network.Name = netStats[0].Name
			stats.Network.RxBytes = netStats[0].BytesRecv
			stats.Network.TxBytes = netStats[0].BytesSent
		}
		rootStats = append(rootStats, stats)
	}
	rootInfo.Stats = rootStats
	return rootInfo, nil
}

func getAllDockerContainers(readers []*bufio.Reader, count int, IDList []string, pids []int) ([]containerInfo, error) {
	ret := []containerInfo{}
	for i, reader := range readers {
		contInfo, err := getContainerStats(reader, count, IDList[i], pids[i])
		if err != nil {
			return []containerInfo{}, err
		}
		ret = append(ret, contInfo)
	}
	return ret, nil
}
<|endoftext|>


<commit_before>package terraform

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/hashicorp/terraform/config"
	"github.com/hashicorp/terraform/config/module"
	"github.com/hashicorp/terraform/helper/hilmapstructure"
)

// EvalTypeCheckVariable is an EvalNode which ensures that the variable
// values which are assigned as inputs to a module (including the root)
// match the types which are either declared for the variables explicitly
// or inferred from the default values.
//
// In order to achieve this three things are required:
//     - a map of the proposed variable values
//     - the configuration tree of the module in which the variable is
//       declared
//     - the path to the module (so we know which part of the tree to
//       compare the values against).
//
// Currently since the type system is simple, we currently do not make
// use of the values since it is only valid to pass string values. The
// structure is in place for extension of the type system, however.
type EvalTypeCheckVariable struct {
	Variables  map[string]interface{}
	ModulePath []string
	ModuleTree *module.Tree
}

func (n *EvalTypeCheckVariable) Eval(ctx EvalContext) (interface{}, error) {
	currentTree := n.ModuleTree
	for _, pathComponent := range n.ModulePath[1:] {
		currentTree = currentTree.Children()[pathComponent]
	}
	targetConfig := currentTree.Config()

	prototypes := make(map[string]config.VariableType)
	for _, variable := range targetConfig.Variables {
		prototypes[variable.Name] = variable.Type()
	}

	// Only display a module in an error message if we are not in the root module
	modulePathDescription := fmt.Sprintf(" in module %s", strings.Join(n.ModulePath[1:], "."))
	if len(n.ModulePath) == 1 {
		modulePathDescription = ""
	}

	for name, declaredType := range prototypes {
		// This is only necessary when we _actually_ check. It is left as a reminder
		// that at the current time we are dealing with a type system consisting only
		// of strings and maps - where the only valid inter-module variable type is
		// string.
		proposedValue, ok := n.Variables[name]
		if !ok {
			// This means the default value should be used as no overriding value
			// has been set. Therefore we should continue as no check is necessary.
			continue
		}

		if proposedValue == config.UnknownVariableValue {
			continue
		}

		switch declaredType {
		case config.VariableTypeString:
			// This will need actual verification once we aren't dealing with
			// a map[string]string but this is sufficient for now.
			switch proposedValue.(type) {
			case string:
				continue
			default:
				return nil, fmt.Errorf("variable %s%s should be type %s, got %s",
					name, modulePathDescription, declaredType.Printable(), hclTypeName(proposedValue))
			}
		case config.VariableTypeMap:
			switch proposedValue.(type) {
			case map[string]interface{}:
				continue
			default:
				return nil, fmt.Errorf("variable %s%s should be type %s, got %s",
					name, modulePathDescription, declaredType.Printable(), hclTypeName(proposedValue))
			}
		case config.VariableTypeList:
			switch proposedValue.(type) {
			case []interface{}:
				continue
			default:
				return nil, fmt.Errorf("variable %s%s should be type %s, got %s",
					name, modulePathDescription, declaredType.Printable(), hclTypeName(proposedValue))
			}
		default:
			// This will need the actual type substituting when we have more than
			// just strings and maps.
			return nil, fmt.Errorf("variable %s%s should be type %s, got type string",
				name, modulePathDescription, declaredType.Printable())
		}
	}

	return nil, nil
}

// EvalSetVariables is an EvalNode implementation that sets the variables
// explicitly for interpolation later.
type EvalSetVariables struct {
	Module    *string
	Variables map[string]interface{}
}

// TODO: test
func (n *EvalSetVariables) Eval(ctx EvalContext) (interface{}, error) {
	ctx.SetVariables(*n.Module, n.Variables)
	return nil, nil
}

// EvalVariableBlock is an EvalNode implementation that evaluates the
// given configuration, and uses the final values as a way to set the
// mapping.
type EvalVariableBlock struct {
	Config         **ResourceConfig
	VariableValues map[string]interface{}
}

// TODO: test
func (n *EvalVariableBlock) Eval(ctx EvalContext) (interface{}, error) {
	// Clear out the existing mapping
	for k, _ := range n.VariableValues {
		delete(n.VariableValues, k)
	}

	// Get our configuration
	rc := *n.Config
	for k, v := range rc.Config {
		var vString string
		if err := hilmapstructure.WeakDecode(v, &vString); err == nil {
			n.VariableValues[k] = vString
			continue
		}

		var vMap map[string]interface{}
		if err := hilmapstructure.WeakDecode(v, &vMap); err == nil {
			n.VariableValues[k] = vMap
			continue
		}

		var vSlice []interface{}
		if err := hilmapstructure.WeakDecode(v, &vSlice); err == nil {
			n.VariableValues[k] = vSlice
			continue
		}

		return nil, fmt.Errorf("Variable value for %s is not a string, list or map type", k)
	}
	for k, _ := range rc.Raw {
		if _, ok := n.VariableValues[k]; !ok {
			n.VariableValues[k] = config.UnknownVariableValue
		}
	}

	return nil, nil
}

// hclTypeName returns the name of the type that would represent this value in
// a config file, or falls back to the Go type name if there's no corresponding
// HCL type. This is used for formatted output, not for comparing types.
func hclTypeName(i interface{}) string {
	switch k := reflect.Indirect(reflect.ValueOf(i)).Kind(); k {
	case reflect.Bool:
		return "boolean"
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
		reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
		return "number"
	case reflect.Array, reflect.Slice:
		return "array"
	case reflect.Map:
		return "object"
	case reflect.String:
		return "string"
	default:
		// fall back to the Go type if there's no match
		return k.String()
	}
}
<commit_msg>core: Use Terraform terms over HCL ones<commit_after>package terraform

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/hashicorp/terraform/config"
	"github.com/hashicorp/terraform/config/module"
	"github.com/hashicorp/terraform/helper/hilmapstructure"
)

// EvalTypeCheckVariable is an EvalNode which ensures that the variable
// values which are assigned as inputs to a module (including the root)
// match the types which are either declared for the variables explicitly
// or inferred from the default values.
//
// In order to achieve this three things are required:
//     - a map of the proposed variable values
//     - the configuration tree of the module in which the variable is
//       declared
//     - the path to the module (so we know which part of the tree to
//       compare the values against).
//
// Currently since the type system is simple, we currently do not make
// use of the values since it is only valid to pass string values. The
// structure is in place for extension of the type system, however.
type EvalTypeCheckVariable struct {
	Variables  map[string]interface{}
	ModulePath []string
	ModuleTree *module.Tree
}

func (n *EvalTypeCheckVariable) Eval(ctx EvalContext) (interface{}, error) {
	currentTree := n.ModuleTree
	for _, pathComponent := range n.ModulePath[1:] {
		currentTree = currentTree.Children()[pathComponent]
	}
	targetConfig := currentTree.Config()

	prototypes := make(map[string]config.VariableType)
	for _, variable := range targetConfig.Variables {
		prototypes[variable.Name] = variable.Type()
	}

	// Only display a module in an error message if we are not in the root module
	modulePathDescription := fmt.Sprintf(" in module %s", strings.Join(n.ModulePath[1:], "."))
	if len(n.ModulePath) == 1 {
		modulePathDescription = ""
	}

	for name, declaredType := range prototypes {
		// This is only necessary when we _actually_ check. It is left as a reminder
		// that at the current time we are dealing with a type system consisting only
		// of strings and maps - where the only valid inter-module variable type is
		// string.
		proposedValue, ok := n.Variables[name]
		if !ok {
			// This means the default value should be used as no overriding value
			// has been set. Therefore we should continue as no check is necessary.
			continue
		}

		if proposedValue == config.UnknownVariableValue {
			continue
		}

		switch declaredType {
		case config.VariableTypeString:
			// This will need actual verification once we aren't dealing with
			// a map[string]string but this is sufficient for now.
			switch proposedValue.(type) {
			case string:
				continue
			default:
				return nil, fmt.Errorf("variable %s%s should be type %s, got %s",
					name, modulePathDescription, declaredType.Printable(), hclTypeName(proposedValue))
			}
		case config.VariableTypeMap:
			switch proposedValue.(type) {
			case map[string]interface{}:
				continue
			default:
				return nil, fmt.Errorf("variable %s%s should be type %s, got %s",
					name, modulePathDescription, declaredType.Printable(), hclTypeName(proposedValue))
			}
		case config.VariableTypeList:
			switch proposedValue.(type) {
			case []interface{}:
				continue
			default:
				return nil, fmt.Errorf("variable %s%s should be type %s, got %s",
					name, modulePathDescription, declaredType.Printable(), hclTypeName(proposedValue))
			}
		default:
			// This will need the actual type substituting when we have more than
			// just strings and maps.
			return nil, fmt.Errorf("variable %s%s should be type %s, got type string",
				name, modulePathDescription, declaredType.Printable())
		}
	}

	return nil, nil
}

// EvalSetVariables is an EvalNode implementation that sets the variables
// explicitly for interpolation later.
type EvalSetVariables struct {
	Module    *string
	Variables map[string]interface{}
}

// TODO: test
func (n *EvalSetVariables) Eval(ctx EvalContext) (interface{}, error) {
	ctx.SetVariables(*n.Module, n.Variables)
	return nil, nil
}

// EvalVariableBlock is an EvalNode implementation that evaluates the
// given configuration, and uses the final values as a way to set the
// mapping.
type EvalVariableBlock struct {
	Config         **ResourceConfig
	VariableValues map[string]interface{}
}

// TODO: test
func (n *EvalVariableBlock) Eval(ctx EvalContext) (interface{}, error) {
	// Clear out the existing mapping
	for k, _ := range n.VariableValues {
		delete(n.VariableValues, k)
	}

	// Get our configuration
	rc := *n.Config
	for k, v := range rc.Config {
		var vString string
		if err := hilmapstructure.WeakDecode(v, &vString); err == nil {
			n.VariableValues[k] = vString
			continue
		}

		var vMap map[string]interface{}
		if err := hilmapstructure.WeakDecode(v, &vMap); err == nil {
			n.VariableValues[k] = vMap
			continue
		}

		var vSlice []interface{}
		if err := hilmapstructure.WeakDecode(v, &vSlice); err == nil {
			n.VariableValues[k] = vSlice
			continue
		}

		return nil, fmt.Errorf("Variable value for %s is not a string, list or map type", k)
	}
	for k, _ := range rc.Raw {
		if _, ok := n.VariableValues[k]; !ok {
			n.VariableValues[k] = config.UnknownVariableValue
		}
	}

	return nil, nil
}

// hclTypeName returns the name of the type that would represent this value in
// a config file, or falls back to the Go type name if there's no corresponding
// HCL type. This is used for formatted output, not for comparing types.
func hclTypeName(i interface{}) string {
	switch k := reflect.Indirect(reflect.ValueOf(i)).Kind(); k {
	case reflect.Bool:
		return "boolean"
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
		reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
		reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
		return "number"
	case reflect.Array, reflect.Slice:
		return "list"
	case reflect.Map:
		return "map"
	case reflect.String:
		return "string"
	default:
		// fall back to the Go type if there's no match
		return k.String()
	}
}
<|endoftext|>


<commit_before>package auth551

import "golang.org/x/oauth2"

type Auth struct {
	config *Config
}

var authInstance *Auth

type Config struct {
	Form   ConfigForm  `json:"form"`
	Google ConfigOAuth `json:"google"`
}

type ConfigForm struct {
	LoginId string `json:"loginId"`
}

type ConfigOAuth struct {
	Vendor       string   `json:"vendor"`
	ClientId     string   `json:"client_id"`
	ClientSecret string   `json:"client_secret"`
	RedirectUrl  string   `json:"redirect_url"`
	Scope        []string `json:"scope"`
	AuthUrl      string   `json:"auth_url"`
	TokenUrl     string   `json:"token_url"`
}

type AuthVendor string

const (
	VENDOR_GOOGLE AuthVendor = "google"
)

func Load(config *Config) *Auth {
	if authInstance != nil {
		return authInstance
	}

	authInstance = &Auth{
		config: config,
	}

	return authInstance
}

func (a *Auth) AuthCodeUrl(vendor AuthVendor) string {
	var config ConfigOAuth

	switch vendor {
	case VENDOR_GOOGLE:
		config = a.config.Google
	default:
		return ""
	}

	authConfig := &oauth2.Config{
		ClientID:     config.ClientId,
		ClientSecret: config.ClientSecret,
		RedirectURL:  config.RedirectUrl,
		Scopes:       config.Scope,
		Endpoint: oauth2.Endpoint{
			AuthURL:  config.AuthUrl,
			TokenURL: config.TokenUrl,
		},
	}

	return authConfig.AuthCodeURL("", oauth2.SetAuthURLParam("access_type", "offline"))
}
<commit_msg>refs #13 code を oauth2.token に変換（交換）するメソッドを実装する<commit_after>package auth551

import "golang.org/x/oauth2"

type Auth struct {
	config *Config
}

var authInstance *Auth

type Config struct {
	Form   ConfigForm  `json:"form"`
	Google ConfigOAuth `json:"google"`
}

type ConfigForm struct {
	LoginId string `json:"loginId"`
}

type ConfigOAuth struct {
	Vendor       string   `json:"vendor"`
	ClientId     string   `json:"client_id"`
	ClientSecret string   `json:"client_secret"`
	RedirectUrl  string   `json:"redirect_url"`
	Scope        []string `json:"scope"`
	AuthUrl      string   `json:"auth_url"`
	TokenUrl     string   `json:"token_url"`
}

type AuthVendor string

const (
	VENDOR_GOOGLE AuthVendor = "google"
)

func Load(config *Config) *Auth {
	if authInstance != nil {
		return authInstance
	}

	authInstance = &Auth{
		config: config,
	}

	return authInstance
}

func (a *Auth) authConfig(vendor AuthVendor) *oauth2.Config {
	var config ConfigOAuth

	switch vendor {
	case VENDOR_GOOGLE:
		config = a.config.Google
	default:
		return nil
	}

	authConfig := &oauth2.Config{
		ClientID:     config.ClientId,
		ClientSecret: config.ClientSecret,
		RedirectURL:  config.RedirectUrl,
		Scopes:       config.Scope,
		Endpoint: oauth2.Endpoint{
			AuthURL:  config.AuthUrl,
			TokenURL: config.TokenUrl,
		},
	}

	return authConfig

}

func (a *Auth) AuthCodeUrl(vendor AuthVendor) string {
	authConfig := a.authConfig(vendor)

	return authConfig.AuthCodeURL("", oauth2.SetAuthURLParam("access_type", "offline"))
}

func (a *Auth) TokenExchange(vendor AuthVendor, code string) *oauth2.Token {
	authConfig := a.authConfig(vendor)

	token, err := authConfig.Exchange(nil, code)
	if err != nil {
		return nil
	}

	return token
}
<|endoftext|>


<commit_before>package aws

import (
	ec2 "github.com/scorelab/gocloud-v2/compute/ec2"
)

// type represents AWS struct.
type AWS struct {
	ec2.EC2
}
<commit_msg>aws struct<commit_after>package aws

import (
	ec2 "github.com/scorelab/gocloud-v2/compute/ec2"
)

//AWS struct reperents amazon cloud provider.
type AWS struct {
	ec2.EC2
}
<|endoftext|>


<commit_before>package aws

import (
	"errors"
	"fmt"
	"time"
	"os"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/ec2"
)

type Client struct {
	*ec2.EC2
}

type AttachENIParam struct {
	InterfaceID string
	InstanceID string
	DeviceIndex int
}

type DetachENIParam struct {
	InterfaceID string
}

type GrabENIParam AttachENIParam

type RetryParam struct {
	TimeoutSec int64
	IntervalSec int64
}

func validateRetryParam(param *RetryParam) error {
	if param == nil {
		return errors.New(fmt.Sprintf("RetryParam require"))
	}

	if param.TimeoutSec <= 0 {
		return errors.New(fmt.Sprintf("invalid timeout (%d) seconds", param.TimeoutSec))
	}
	if param.IntervalSec <= 0 {
		return errors.New(fmt.Sprintf("invalid interval (%d) seconds", param.IntervalSec))
	}
	if param.TimeoutSec < param.IntervalSec {
		return errors.New(fmt.Sprintf(
			"interval (%d) should be less than timeout (%d) seconds",
			param.IntervalSec,
			param.TimeoutSec,
		))
	}

	return nil
}

func NewClient(region string, accessKey string, secretKey string) (*Client, error) {
	config := aws.Config{}
	envRegion := os.Getenv("AWS_REGION")

	if region == "" && envRegion == "" {
		var err error

		config.Region, err = GetRegion()
		if err != nil {
			return nil, err
		}
	} else if region == "" && envRegion != "" {
		config.Region = envRegion
	} else {
		config.Region = region
	}

	if accessKey != "" && secretKey != "" {
		config.Credentials = aws.Creds(accessKey, secretKey, "")
	}

	return &Client{ec2.New(&config)}, nil
}

func (cli *Client) DescribeENIByID(InterfaceID string) (*ec2.NetworkInterface, error) {
	params := &ec2.DescribeNetworkInterfacesInput{
		NetworkInterfaceIDs: []*string{
			aws.String(InterfaceID),
		},
	}
	resp, err := cli.EC2.DescribeNetworkInterfaces(params)
	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return nil, errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return nil, err
	}

	if len(resp.NetworkInterfaces) < 1 {
		return nil, nil
	}

	return resp.NetworkInterfaces[0], nil
}

func (cli *Client) DescribeENIs() ([]*ec2.NetworkInterface, error) {
	resp, err := cli.EC2.DescribeNetworkInterfaces(nil)
	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return nil, errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return nil, err
	}

	if len(resp.NetworkInterfaces) < 1 {
		return nil, nil
	}

	return resp.NetworkInterfaces, nil
}

func (cli *Client) AttachENI(param *AttachENIParam) error {
	input := &ec2.AttachNetworkInterfaceInput{
		NetworkInterfaceID: aws.String(param.InterfaceID),
		InstanceID:         aws.String(param.InstanceID),
		DeviceIndex:        aws.Long(int64(param.DeviceIndex)),
	}
	_, err := cli.EC2.AttachNetworkInterface(input)
	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return err
	}

	return nil
}

func (cli *Client) AttachENIWithRetry(param *AttachENIParam, retryParam *RetryParam) error {
	if err := validateRetryParam(retryParam); err != nil {
		return err
	}

	if err := cli.AttachENI(param); err != nil {
		return err
	}

	// Retry until attach event completed or timeout
	for {
		select {
		case <-time.After(time.Duration(retryParam.TimeoutSec) * time.Second):
			return errors.New(fmt.Sprintf("timeout occured. %d seconds elapsed.", retryParam.TimeoutSec))
		case <-time.Tick(time.Duration(retryParam.IntervalSec) * time.Second):
			eni, err := cli.DescribeENIByID(param.InterfaceID)
			if err != nil {
				return err
			}
			if *eni.Status == "in-use" && eni.Attachment != nil && *eni.Attachment.Status == "attached" {
				return nil // detach completed
			}
		}
	}

	return nil
}

func (cli *Client) DetachENIByAttachmentID(attachmentID string) error {
	params := &ec2.DetachNetworkInterfaceInput{
		AttachmentID: aws.String(attachmentID),
		Force:        aws.Boolean(false),
	}
	_, err := cli.EC2.DetachNetworkInterface(params)

	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return err
	}

	return nil
}

func (cli *Client) DetachENI(param *DetachENIParam) error {
	eni, err := cli.DescribeENIByID(param.InterfaceID)
	if err != nil {
		return err
	}

	if eni.Attachment == nil {
		// already detached
		return nil
	}

	if err := cli.DetachENIByAttachmentID(*eni.Attachment.AttachmentID); err != nil {
		return err
	}

	return nil
}

func (cli *Client) DetachENIWithRetry(param *DetachENIParam, retryParam *RetryParam) error {
	if err := validateRetryParam(retryParam); err != nil {
		return err
	}

	if err := cli.DetachENI(param); err != nil {
		return err
	}

	// Retry until detach event completed or timeout
	for {
		select {
		case <-time.After(time.Duration(retryParam.TimeoutSec) * time.Second):
			return errors.New(fmt.Sprintf("timeout occured. %d seconds elapsed.", retryParam.TimeoutSec))
		case <-time.Tick(time.Duration(retryParam.IntervalSec) * time.Second):
			eni, err := cli.DescribeENIByID(param.InterfaceID)
			if err != nil {
				return err
			}
			if *eni.Status == "available" {
				return nil // detach completed
			}
		}
	}

	return nil
}

func (cli *Client) GrabENI(param *GrabENIParam, retryParam *RetryParam) (error, bool) {
	eni, err := cli.DescribeENIByID(param.InterfaceID)
	if err != nil {
		return err, false
	}

	// Skip detaching if the target ENI has still not attached with the other instance
	if eni.Attachment != nil {
		// Do nothing if the target ENI already attached with the target instance
		if *eni.Attachment.InstanceID == param.InstanceID {
			return nil, false
		}

		if err := cli.DetachENIWithRetry(&DetachENIParam{InterfaceID: param.InterfaceID}, retryParam); err != nil {
			return err, false
		}
	}

	p := AttachENIParam(*param)
	if err := cli.AttachENIWithRetry(&p, retryParam); err != nil {
		return err, false
	}

	return nil, true
}
<commit_msg>Replace errors.New() into fmt.Errorf()<commit_after>package aws

import (
	"errors"
	"fmt"
	"time"
	"os"

	"github.com/awslabs/aws-sdk-go/aws"
	"github.com/awslabs/aws-sdk-go/service/ec2"
)

type Client struct {
	*ec2.EC2
}

type AttachENIParam struct {
	InterfaceID string
	InstanceID string
	DeviceIndex int
}

type DetachENIParam struct {
	InterfaceID string
}

type GrabENIParam AttachENIParam

type RetryParam struct {
	TimeoutSec int64
	IntervalSec int64
}

func validateRetryParam(param *RetryParam) error {
	if param == nil {
		return fmt.Errorf("RetryParam require")
	}

	if param.TimeoutSec <= 0 {
		return fmt.Errorf("invalid timeout (%d) seconds", param.TimeoutSec)
	}
	if param.IntervalSec <= 0 {
		return fmt.Errorf("invalid interval (%d) seconds", param.IntervalSec)
	}
	if param.TimeoutSec < param.IntervalSec {
		return fmt.Errorf(
			"interval (%d) should be less than timeout (%d) seconds",
			param.IntervalSec,
			param.TimeoutSec,
		)
	}

	return nil
}

func NewClient(region string, accessKey string, secretKey string) (*Client, error) {
	config := aws.Config{}
	envRegion := os.Getenv("AWS_REGION")

	if region == "" && envRegion == "" {
		var err error

		config.Region, err = GetRegion()
		if err != nil {
			return nil, err
		}
	} else if region == "" && envRegion != "" {
		config.Region = envRegion
	} else {
		config.Region = region
	}

	if accessKey != "" && secretKey != "" {
		config.Credentials = aws.Creds(accessKey, secretKey, "")
	}

	return &Client{ec2.New(&config)}, nil
}

func (cli *Client) DescribeENIByID(InterfaceID string) (*ec2.NetworkInterface, error) {
	params := &ec2.DescribeNetworkInterfacesInput{
		NetworkInterfaceIDs: []*string{
			aws.String(InterfaceID),
		},
	}
	resp, err := cli.EC2.DescribeNetworkInterfaces(params)
	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return nil, errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return nil, err
	}

	if len(resp.NetworkInterfaces) < 1 {
		return nil, nil
	}

	return resp.NetworkInterfaces[0], nil
}

func (cli *Client) DescribeENIs() ([]*ec2.NetworkInterface, error) {
	resp, err := cli.EC2.DescribeNetworkInterfaces(nil)
	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return nil, errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return nil, err
	}

	if len(resp.NetworkInterfaces) < 1 {
		return nil, nil
	}

	return resp.NetworkInterfaces, nil
}

func (cli *Client) AttachENI(param *AttachENIParam) error {
	input := &ec2.AttachNetworkInterfaceInput{
		NetworkInterfaceID: aws.String(param.InterfaceID),
		InstanceID:         aws.String(param.InstanceID),
		DeviceIndex:        aws.Long(int64(param.DeviceIndex)),
	}
	_, err := cli.EC2.AttachNetworkInterface(input)
	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return err
	}

	return nil
}

func (cli *Client) AttachENIWithRetry(param *AttachENIParam, retryParam *RetryParam) error {
	if err := validateRetryParam(retryParam); err != nil {
		return err
	}

	if err := cli.AttachENI(param); err != nil {
		return err
	}

	// Retry until attach event completed or timeout
	for {
		select {
		case <-time.After(time.Duration(retryParam.TimeoutSec) * time.Second):
			return errors.New(fmt.Sprintf("timeout occured. %d seconds elapsed.", retryParam.TimeoutSec))
		case <-time.Tick(time.Duration(retryParam.IntervalSec) * time.Second):
			eni, err := cli.DescribeENIByID(param.InterfaceID)
			if err != nil {
				return err
			}
			if *eni.Status == "in-use" && eni.Attachment != nil && *eni.Attachment.Status == "attached" {
				return nil // detach completed
			}
		}
	}

	return nil
}

func (cli *Client) DetachENIByAttachmentID(attachmentID string) error {
	params := &ec2.DetachNetworkInterfaceInput{
		AttachmentID: aws.String(attachmentID),
		Force:        aws.Boolean(false),
	}
	_, err := cli.EC2.DetachNetworkInterface(params)

	if awserr := aws.Error(err); awserr != nil {
		// A service error occurred.
		return errors.New(awserr.Error())
	} else if err != nil {
		// A non-service error occurred.
		return err
	}

	return nil
}

func (cli *Client) DetachENI(param *DetachENIParam) error {
	eni, err := cli.DescribeENIByID(param.InterfaceID)
	if err != nil {
		return err
	}

	if eni.Attachment == nil {
		// already detached
		return nil
	}

	if err := cli.DetachENIByAttachmentID(*eni.Attachment.AttachmentID); err != nil {
		return err
	}

	return nil
}

func (cli *Client) DetachENIWithRetry(param *DetachENIParam, retryParam *RetryParam) error {
	if err := validateRetryParam(retryParam); err != nil {
		return err
	}

	if err := cli.DetachENI(param); err != nil {
		return err
	}

	// Retry until detach event completed or timeout
	for {
		select {
		case <-time.After(time.Duration(retryParam.TimeoutSec) * time.Second):
			return errors.New(fmt.Sprintf("timeout occured. %d seconds elapsed.", retryParam.TimeoutSec))
		case <-time.Tick(time.Duration(retryParam.IntervalSec) * time.Second):
			eni, err := cli.DescribeENIByID(param.InterfaceID)
			if err != nil {
				return err
			}
			if *eni.Status == "available" {
				return nil // detach completed
			}
		}
	}

	return nil
}

func (cli *Client) GrabENI(param *GrabENIParam, retryParam *RetryParam) (error, bool) {
	eni, err := cli.DescribeENIByID(param.InterfaceID)
	if err != nil {
		return err, false
	}

	// Skip detaching if the target ENI has still not attached with the other instance
	if eni.Attachment != nil {
		// Do nothing if the target ENI already attached with the target instance
		if *eni.Attachment.InstanceID == param.InstanceID {
			return nil, false
		}

		if err := cli.DetachENIWithRetry(&DetachENIParam{InterfaceID: param.InterfaceID}, retryParam); err != nil {
			return err, false
		}
	}

	p := AttachENIParam(*param)
	if err := cli.AttachENIWithRetry(&p, retryParam); err != nil {
		return err, false
	}

	return nil, true
}
<|endoftext|>


<commit_before>package oauth2

import (
	"errors"
	"io"
	"net/http"
)

var (
	ErrNotFound = errors.New("object not found")
)

// PersistenceBackend defines the interface necessary for persistence, which needs to
// be implemented by users of this library.
// If an object can't be found by any of the Get* methods, it should return ErrNotFound.
type PersistenceBackend interface {
	//*
	// Authorization persistence
	//*
	SaveAuthorization(a *Authorization) error
	GetAuthorizationByCode(code string) (*Authorization, error)
	GetAuthorizationByAccessToken(code string) (*Authorization, error)

	//*
	// Client persistence
	//*
	SaveClient(c *Client) error
	GetClientByID(ID string) (*Client, error)

	//*
	// Scope persistence
	//*
	GetScopesByID(scopeIDs ...string) ([]*Scope, error)

	//*
	// User persistence
	//*
	GetUserByCredentials(username, password string) (*User, error)
}

type AuthorizationPageData struct {
	Client *Client
	User   *User
	Scopes []*Scope
}

type HTTPBackend interface {
	// RenderAuthorizationPage should write to the io.Writer the HTML for the
	// authorization page.
	RenderAuthorizationPage(w io.Writer, data *AuthorizationPageData) error

	// AuthenticateRequest should take an http.Request and either return
	// the current logged in user or generate a response that will allow the
	// user to login, such as a redirect. If the later happens, both User and
	// error should be nil.
	AuthenticateRequest(w http.ResponseWriter, req *http.Request) (*User, error)
}
<commit_msg>Tweaks to backend doc<commit_after>package oauth2

import (
	"errors"
	"io"
	"net/http"
)

// ErrNotFound should be returned by any Get* methods defined in PersistenceBackend
// when the object could not be found.
var ErrNotFound = errors.New("object not found")

// PersistenceBackend defines the interface necessary for persistence, which needs to
// be implemented by users of this library.
//
// If an object can't be found by any of the Get* methods, it should return ErrNotFound.
type PersistenceBackend interface {
	//*
	// Authorization persistence
	//*
	GetAuthorizationByCode(code string) (*Authorization, error)
	GetAuthorizationByAccessToken(code string) (*Authorization, error)
	SaveAuthorization(a *Authorization) error

	//*
	// Client persistence
	//*
	GetClientByID(ID string) (*Client, error)
	SaveClient(c *Client) error

	//*
	// Scope persistence
	//*
	GetScopesByID(scopeIDs ...string) ([]*Scope, error)

	//*
	// User persistence
	//*
	GetUserByCredentials(username, password string) (*User, error)
}

type AuthorizationPageData struct {
	Client *Client
	User   *User
	Scopes []*Scope
}

type HTTPBackend interface {
	// RenderAuthorizationPage should write to the io.Writer the HTML for the
	// authorization page.
	RenderAuthorizationPage(w io.Writer, data *AuthorizationPageData) error

	// AuthenticateRequest should take an http.Request and either return
	// the current logged in user or generate a response that will allow the
	// user to login, such as a redirect. If the later happens, both User and
	// error should be nil.
	AuthenticateRequest(w http.ResponseWriter, req *http.Request) (*User, error)
}
<|endoftext|>


<commit_before>package alignment

//package main

import . "./interface"
import "fmt"
import "math"

type Rgotoh struct {
	x     string
	y     string
	h     [][][]int
	vague bool
	Constants
}

func NewRGotoh(y string, x string, settings Constants) *Rgotoh {
	xlen := len(x) + 1
	h := make([][][]int, 3)
	for i := 0; i < 3; i++ {
		h[i] = make([][]int, xlen)
		for y := 0; y < xlen; y++ {
			h[i][y] = make([]int, 2)
		}
	}
	Rgotoh := &Rgotoh{x: x, y: y, h: h}
	Rgotoh.Constants = settings
	return Rgotoh
}

func (l Rgotoh) Strlen() (int, int) {
	return len(l.x), len(l.y)
}

func (l Rgotoh) Substitution(x int, y int) int {
	return l.Constants.Substitution(l.x[x-1], l.y[y-1])
}

func (l Rgotoh) Score() int {
	e, _ := l.ScoreArgs(len(l.x))
	return e
}

func (l *Rgotoh) Length() {
	l.RegionAlign(0, len(l.x), 0, len(l.y), true)
}

func (l *Rgotoh) RegionAlign(i1 int, i2 int, j1 int, j2 int, order bool) (result int, class int) {
	var m = i2 - i1
	var n = j2 - j1
	l.h[0][0][0] = 0
	l.h[1][0][0] = math.MinInt64
	l.h[2][0][0] = math.MinInt64
	for i := 1; i <= m; i++ {
		l.h[0][i][0] = math.MinInt32
		l.h[1][i][0] = l.Cost(i)
		l.h[2][i][0] = math.MinInt32
	}

	for j := 1; j <= n; j++ {
		l.h[0][0][1] = math.MinInt32
		l.h[1][0][1] = math.MinInt32
		l.h[2][0][1] = l.Cost(j)
		for i := 1; i <= m; i++ {
			var nexth int
			//Update H^1 (l.h[0])
			nexth, _ = Max(l.h[0][i-1][0], l.h[1][i-1][0], l.h[2][i-1][0])
			//fmt.Println(i, j)
			if order {
				l.h[0][i][1] = nexth + l.Substitution(i+i1, j+j1)
			} else {
				l.h[0][i][1] = nexth + l.Substitution(i2-i+1, j2-j+1)
			}
			//Update H^2 (l.h[1])
			e, d := l.Geted()
			nexth, _ = Max(l.h[0][i-1][1]-d, l.h[1][i-1][1]-e, l.h[2][i-1][1]-d)
			l.h[1][i][1] = nexth
			//Update H^3 (l.h[2])
			nexth, _ = Max(l.h[0][i][0]-d, math.MinInt64, l.h[2][i][0]-e)
			l.h[2][i][1] = nexth
		}
		for i := 0; i <= m; i++ {
			l.h[0][i][0] = l.h[0][i][1]
			l.h[1][i][0] = l.h[1][i][1]
			l.h[2][i][0] = l.h[2][i][1]
		}
	}
	return l.ScoreArgs(m)
}

func (l Rgotoh) ScoreArgs(x int) (e int, k int) {
	e, k = Max(l.h[0][x][0], l.h[1][x][0], l.h[2][x][0])
	return
}

func (l Rgotoh) Print(i int, j int) (string, string, string) {
	//fmt.Println(l.LinearSpaceAlign(120, 120, 120, 120))
	//fmt.Println(l.RegionAlign(7, len(l.x), 0, len(l.y), false))
	//fmt.Println(l.RegionAlign(7, len(l.x), 0, len(l.y), true))
	//fmt.Println(l.RegionAlign(0, 7, 0, 0, false))
	//fmt.Println(l.RegionAlign(0, 7, 0, 0, true))
	if len(l.x) > 100 {
		l.vague = true
	}
	return l.LinearSpace(0, 0, i-1, j-1, l.Score())
	//return l.LinearBinaryAlign(0, i-1, 0, j-1, l.Score())
	//return l.linearSpaceAlign(0, len(l.x), 0, len(l.y))
}

func (l Rgotoh) LinearSpace(i0 int, j0 int, i int, j int, score int) (p string, q string, r string) {
	if (i < i0 && j == j0) || (j < j0 && i == i0) {
		return
	} else if i < i0 {
		for jt := j0; jt <= j; jt++ {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[jt])
		}
		return
	} else if j < j0 {
		for it := i0; it <= i; it++ {
			p += fmt.Sprintf("%c", l.x[it])
			q += " "
			r += "-"
		}
		return
	}
	maxj := j + 1 //To use determine whethere i have a suitable solution.
	min := 0
	if l.vague {
		min = j - 70
	}
	for jh := j; jh >= min; jh-- {
		tmp1, err1 := l.RegionAlign(0, i, 0, jh, true)
		tmp2, err2 := l.RegionAlign(i, len(l.x), jh, len(l.y), false)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 == err2 && err2 >= 1 {
			tmp += d
		}
		//fmt.Println(tmp1, tmp2, err1, err2, tmp, jh)
		if tmp == score {
			maxj = jh
			break
		}
	}
	//fmt.Println(i, j, maxj, "result")
	p, q, r = l.LinearSpace(i0, j0, i-1, maxj-1, score)
	if maxj == j+1 {
		//When no suitable solution is not found for i.
		p += fmt.Sprintf("%c", l.x[i])
		q += " "
		r += "-"
	} else if maxj < j {
		//When no suitable solution is not found for j.
		p += fmt.Sprintf("%c", l.x[i])
		q += "|"
		r += fmt.Sprintf("%c", l.y[maxj])
		for maxj++; maxj <= j; maxj++ {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[maxj])
		}
	} else {
		//fmt.Println(i)
		p += fmt.Sprintf("%c", l.x[i])
		q += "|"
		r += fmt.Sprintf("%c", l.y[j])
	}
	return
}

func (l Rgotoh) LinearBinaryAlign(i1 int, i2 int, j1 int, j2 int, score int) (p string, q string, r string) {
	if i2-i1 <= 100 || j2-j1 <= 100 {
		//fmt.Println(i1, j1, i2, j2, "delegate")
		return l.LinearSpace(i1, j1, i2, j2, score)
	}
	ih := ((i1 + i2) / 2)
	if ih >= len(l.x) || ih < i1 {
		panic(i1 + i2)
	}
	maxscore, maxj := -1000, j1+1
	for jh := j2; jh >= j1; jh-- {
		tmp1, err1 := l.RegionAlign(i1, ih, j1, jh, true)
		tmp2, err2 := l.RegionAlign(ih, i2, jh, j2, false)
		//fmt.Println(tmp1, tmp2)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 >= 1 && err2 >= 1 {
			tmp += d
		}
		//fmt.Println(i1, i2, j1, j2, ih, jh, tmp)
		if tmp > maxscore {
			maxscore = tmp
			maxj = jh
		}
	}
	fmt.Println(i1, ih, i2, j1, maxj, j2)
	p, q, r = l.LinearBinaryAlign(i1, ih-1, j1, maxj-1, score)
	//p += fmt.Sprintf("%c", l.x[ih])
	//q += "|"
	//r += fmt.Sprintf("%c", l.y[maxj])
	p2, q2, r2 := l.LinearBinaryAlign(ih, i2, maxj, j2, score)
	p += p2
	q += q2
	r += r2
	return
}

//linearSpaceAlign is not used.
func (l Rgotoh) linearSpaceAlign(i1 int, i2 int, j1 int, j2 int) (p string, q string, r string) {
	i := i2 - i1
	j := j2 - j1
	fmt.Println(i1, i2, j1, j2, i, j, "hantei")
	if i <= 0 && j <= 0 {
		return "", "", ""
	} else if i <= 0 {
		//p,q,r = l.Print(i,j-1)
		for ; j2 > j1; j2-- {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[j2])
		}
		return p, q, r
	} else if j <= 0 {
		//p,q,r = l.Print(i-1,j)
		for ; i2 > i1; i2-- {
			p += fmt.Sprintf("%c", l.x[i2])
			q += " "
			r += "-"
		}
		return p, q, r
	} else if i == 1 && j == 1 {
		//	p += fmt.Sprintf("%c", l.x[i1])
		//	q += "|"
		//	r += fmt.Sprintf("%c", l.y[i1])
		return p, q, r
	}
	ih := ((i1 + i2) / 2)
	if ih >= len(l.x) || ih < i1 {
		panic(i1 + i2)
	}
	maxscore, maxj := math.MinInt64, j1+1
	for jh := j1 + 1; jh < j2; jh++ {
		tmp1, err1 := l.RegionAlign(i1, ih, j1, jh, true)
		tmp2, err2 := l.RegionAlign(ih, i2, jh, j2, false)
		fmt.Println(tmp1, tmp2)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 >= 1 && err2 >= 1 {
			tmp += d
		}
		fmt.Println(i1, i2, j1, j2, ih, jh, tmp)
		if tmp > maxscore {
			maxscore = tmp
			maxj = jh
		}
	}
	fmt.Println(i1, ih, i2, j1, maxj, j2)
	p, q, r = l.linearSpaceAlign(i1, ih, j1, maxj)
	p += fmt.Sprintf("%c", l.x[ih])
	q += "!"
	r += fmt.Sprintf("%c", l.y[maxj])
	p2, q2, r2 := l.linearSpaceAlign(ih, i2, maxj, j2)
	p += p2
	q += q2
	r += r2
	return
}
<commit_msg>Fix vague option<commit_after>package alignment

//package main

import . "./interface"
import "fmt"
import "math"

type Rgotoh struct {
	x     string
	y     string
	h     [][][]int
	vague bool
	Constants
}

func NewRGotoh(y string, x string, settings Constants) *Rgotoh {
	xlen := len(x) + 1
	h := make([][][]int, 3)
	for i := 0; i < 3; i++ {
		h[i] = make([][]int, xlen)
		for y := 0; y < xlen; y++ {
			h[i][y] = make([]int, 2)
		}
	}
	Rgotoh := &Rgotoh{x: x, y: y, h: h}
	Rgotoh.Constants = settings
	return Rgotoh
}

func (l Rgotoh) Strlen() (int, int) {
	return len(l.x), len(l.y)
}

func (l Rgotoh) Substitution(x int, y int) int {
	return l.Constants.Substitution(l.x[x-1], l.y[y-1])
}

func (l Rgotoh) Score() int {
	e, _ := l.ScoreArgs(len(l.x))
	return e
}

func (l *Rgotoh) Length() {
	l.RegionAlign(0, len(l.x), 0, len(l.y), true)
}

func (l *Rgotoh) RegionAlign(i1 int, i2 int, j1 int, j2 int, order bool) (result int, class int) {
	var m = i2 - i1
	var n = j2 - j1
	l.h[0][0][0] = 0
	l.h[1][0][0] = math.MinInt64
	l.h[2][0][0] = math.MinInt64
	for i := 1; i <= m; i++ {
		l.h[0][i][0] = math.MinInt32
		l.h[1][i][0] = l.Cost(i)
		l.h[2][i][0] = math.MinInt32
	}

	for j := 1; j <= n; j++ {
		l.h[0][0][1] = math.MinInt32
		l.h[1][0][1] = math.MinInt32
		l.h[2][0][1] = l.Cost(j)
		for i := 1; i <= m; i++ {
			var nexth int
			//Update H^1 (l.h[0])
			nexth, _ = Max(l.h[0][i-1][0], l.h[1][i-1][0], l.h[2][i-1][0])
			//fmt.Println(i, j)
			if order {
				l.h[0][i][1] = nexth + l.Substitution(i+i1, j+j1)
			} else {
				l.h[0][i][1] = nexth + l.Substitution(i2-i+1, j2-j+1)
			}
			//Update H^2 (l.h[1])
			e, d := l.Geted()
			nexth, _ = Max(l.h[0][i-1][1]-d, l.h[1][i-1][1]-e, l.h[2][i-1][1]-d)
			l.h[1][i][1] = nexth
			//Update H^3 (l.h[2])
			nexth, _ = Max(l.h[0][i][0]-d, math.MinInt64, l.h[2][i][0]-e)
			l.h[2][i][1] = nexth
		}
		for i := 0; i <= m; i++ {
			l.h[0][i][0] = l.h[0][i][1]
			l.h[1][i][0] = l.h[1][i][1]
			l.h[2][i][0] = l.h[2][i][1]
		}
	}
	return l.ScoreArgs(m)
}

func (l Rgotoh) ScoreArgs(x int) (e int, k int) {
	e, k = Max(l.h[0][x][0], l.h[1][x][0], l.h[2][x][0])
	return
}

func (l Rgotoh) Print(i int, j int) (string, string, string) {
	//fmt.Println(l.LinearSpaceAlign(120, 120, 120, 120))
	//fmt.Println(l.RegionAlign(0, 7, 0, 0, true))
	if len(l.x) > 200 {
		l.vague = true
	}
	return l.LinearSpace(0, 0, i-1, j-1, l.Score())
	//return l.LinearBinaryAlign(0, i-1, 0, j-1, l.Score())
	//return l.linearSpaceAlign(0, len(l.x), 0, len(l.y))
}

func (l Rgotoh) LinearSpace(i0 int, j0 int, i int, j int, score int) (p string, q string, r string) {
	if (i < i0 && j == j0) || (j < j0 && i == i0) {
		return
	} else if i < i0 {
		for jt := j0; jt <= j; jt++ {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[jt])
		}
		return
	} else if j < j0 {
		for it := i0; it <= i; it++ {
			p += fmt.Sprintf("%c", l.x[it])
			q += " "
			r += "-"
		}
		return
	}
	maxj := j + 1 //To use determine whethere i have a suitable solution.
	min := 0
	if l.vague {
		min = j - 70
	}
	for jh := j; jh >= min; jh-- {
		tmp1, err1 := l.RegionAlign(0, i, 0, jh, true)
		tmp2, err2 := l.RegionAlign(i, len(l.x), jh, len(l.y), false)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 == err2 && err2 >= 1 {
			tmp += d
		}
		//fmt.Println(tmp1, tmp2, err1, err2, tmp, jh)
		if tmp == score {
			maxj = jh
			break
		}
	}
	//fmt.Println(i, j, maxj, "result")
	p, q, r = l.LinearSpace(i0, j0, i-1, maxj-1, score)
	if maxj == j+1 {
		//When no suitable solution is not found for i.
		p += fmt.Sprintf("%c", l.x[i])
		q += " "
		r += "-"
	} else if maxj < j {
		//When no suitable solution is not found for j.
		p += fmt.Sprintf("%c", l.x[i])
		q += "|"
		r += fmt.Sprintf("%c", l.y[maxj])
		for maxj++; maxj <= j; maxj++ {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[maxj])
		}
	} else {
		//fmt.Println(i)
		p += fmt.Sprintf("%c", l.x[i])
		q += "|"
		r += fmt.Sprintf("%c", l.y[j])
	}
	return
}

func (l Rgotoh) LinearBinaryAlign(i1 int, i2 int, j1 int, j2 int, score int) (p string, q string, r string) {
	if i2-i1 <= 100 || j2-j1 <= 100 {
		//fmt.Println(i1, j1, i2, j2, "delegate")
		return l.LinearSpace(i1, j1, i2, j2, score)
	}
	ih := ((i1 + i2) / 2)
	if ih >= len(l.x) || ih < i1 {
		panic(i1 + i2)
	}
	maxscore, maxj := -1000, j1+1
	for jh := j2; jh >= j1; jh-- {
		tmp1, err1 := l.RegionAlign(i1, ih, j1, jh, true)
		tmp2, err2 := l.RegionAlign(ih, i2, jh, j2, false)
		//fmt.Println(tmp1, tmp2)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 >= 1 && err2 >= 1 {
			tmp += d
		}
		//fmt.Println(i1, i2, j1, j2, ih, jh, tmp)
		if tmp > maxscore {
			maxscore = tmp
			maxj = jh
		}
	}
	fmt.Println(i1, ih, i2, j1, maxj, j2)
	p, q, r = l.LinearBinaryAlign(i1, ih-1, j1, maxj-1, score)
	//p += fmt.Sprintf("%c", l.x[ih])
	//q += "|"
	//r += fmt.Sprintf("%c", l.y[maxj])
	p2, q2, r2 := l.LinearBinaryAlign(ih, i2, maxj, j2, score)
	p += p2
	q += q2
	r += r2
	return
}

//linearSpaceAlign is not used.
func (l Rgotoh) linearSpaceAlign(i1 int, i2 int, j1 int, j2 int) (p string, q string, r string) {
	i := i2 - i1
	j := j2 - j1
	fmt.Println(i1, i2, j1, j2, i, j, "hantei")
	if i <= 0 && j <= 0 {
		return "", "", ""
	} else if i <= 0 {
		//p,q,r = l.Print(i,j-1)
		for ; j2 > j1; j2-- {
			p += "-"
			q += " "
			r += fmt.Sprintf("%c", l.y[j2])
		}
		return p, q, r
	} else if j <= 0 {
		//p,q,r = l.Print(i-1,j)
		for ; i2 > i1; i2-- {
			p += fmt.Sprintf("%c", l.x[i2])
			q += " "
			r += "-"
		}
		return p, q, r
	} else if i == 1 && j == 1 {
		//	p += fmt.Sprintf("%c", l.x[i1])
		//	q += "|"
		//	r += fmt.Sprintf("%c", l.y[i1])
		return p, q, r
	}
	ih := ((i1 + i2) / 2)
	if ih >= len(l.x) || ih < i1 {
		panic(i1 + i2)
	}
	maxscore, maxj := math.MinInt64, j1+1
	for jh := j1 + 1; jh < j2; jh++ {
		tmp1, err1 := l.RegionAlign(i1, ih, j1, jh, true)
		tmp2, err2 := l.RegionAlign(ih, i2, jh, j2, false)
		fmt.Println(tmp1, tmp2)
		tmp := tmp1 + tmp2
		_, d := l.Geted()
		if err1 >= 1 && err2 >= 1 {
			tmp += d
		}
		fmt.Println(i1, i2, j1, j2, ih, jh, tmp)
		if tmp > maxscore {
			maxscore = tmp
			maxj = jh
		}
	}
	fmt.Println(i1, ih, i2, j1, maxj, j2)
	p, q, r = l.linearSpaceAlign(i1, ih, j1, maxj)
	p += fmt.Sprintf("%c", l.x[ih])
	q += "!"
	r += fmt.Sprintf("%c", l.y[maxj])
	p2, q2, r2 := l.linearSpaceAlign(ih, i2, maxj, j2)
	p += p2
	q += q2
	r += r2
	return
}
<|endoftext|>


<commit_before>package signed

import (
	"github.com/Sirupsen/logrus"
	"github.com/endophage/gotuf/data"
	"github.com/endophage/gotuf/errors"
	"fmt"
)

// Sign takes a data.Signed and a key, calculated and adds the signature
// to the data.Signed
func Sign(service CryptoService, s *data.Signed, keys ...data.PublicKey) error {
	logrus.Debugf("sign called with %d keys", len(keys))
	signatures := make([]data.Signature, 0, len(s.Signatures)+1)
	keyIDMemb := make(map[string]struct{})
	keyIDs := make([]string, 0, len(keys))

	for _, key := range keys {
		keyIDMemb[key.ID()] = struct{}{}
		keyIDs = append(keyIDs, key.ID())
	}
	logrus.Debugf("Generated list of signing IDs: %v", keyIDs)
	for _, sig := range s.Signatures {
		if _, ok := keyIDMemb[sig.KeyID]; ok {
			continue
		}
		signatures = append(signatures, sig)
	}
	newSigs, err := service.Sign(keyIDs, s.Signed)
	if err != nil {
		return err
	}
	if len(newSigs) < 1 {
		return errors.ErrInsufficientSignatures{
			Name: fmt.Sprint("Cryptoservice failed to produce any signatures for keys %v", keyIDs),
			Err:  nil,
		}
	}
	logrus.Debugf("appending %d new signatures", len(newSigs))
	s.Signatures = append(signatures, newSigs...)
	return nil
}
<commit_msg>updating error messages on signing failures<commit_after>package signed

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/endophage/gotuf/data"
	"github.com/endophage/gotuf/errors"
	"strings"
)

// Sign takes a data.Signed and a key, calculated and adds the signature
// to the data.Signed
func Sign(service CryptoService, s *data.Signed, keys ...data.PublicKey) error {
	logrus.Debugf("sign called with %d keys", len(keys))
	signatures := make([]data.Signature, 0, len(s.Signatures)+1)
	keyIDMemb := make(map[string]struct{})
	keyIDs := make([]string, 0, len(keys))

	for _, key := range keys {
		keyIDMemb[key.ID()] = struct{}{}
		keyIDs = append(keyIDs, key.ID())
	}
	logrus.Debugf("Generated list of signing IDs: %s", strings.Join(keyIDs, ", "))
	for _, sig := range s.Signatures {
		if _, ok := keyIDMemb[sig.KeyID]; ok {
			continue
		}
		signatures = append(signatures, sig)
	}
	newSigs, err := service.Sign(keyIDs, s.Signed)
	if err != nil {
		return err
	}
	if len(newSigs) < 1 {
		return errors.ErrInsufficientSignatures{
			Name: fmt.Sprint("Cryptoservice failed to produce any signatures for keys with IDs: %s", strings.Join(keyIDs, ", ")),
			Err:  nil,
		}
	}
	logrus.Debugf("appending %d new signatures", len(newSigs))
	s.Signatures = append(signatures, newSigs...)
	return nil
}
<|endoftext|>