<commit_before>package aws

import (
	"fmt"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/elb"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsAppCookieStickinessPolicy() *schema.Resource {
	return &schema.Resource{
		// There is no concept of "updating" an App Stickiness policy in
		// the AWS API.
		Create: resourceAwsAppCookieStickinessPolicyCreate,
		Update: resourceAwsAppCookieStickinessPolicyCreate,

		Read:   resourceAwsAppCookieStickinessPolicyRead,
		Delete: resourceAwsAppCookieStickinessPolicyDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"load_balancer": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"lb_port": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"cookie_name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
		},
	}
}

func resourceAwsAppCookieStickinessPolicyCreate(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	// Provision the AppStickinessPolicy
	acspOpts := &elb.CreateAppCookieStickinessPolicyInput{
		CookieName:       aws.String(d.Get("cookie_name").(string)),
		LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
		PolicyName:       aws.String(d.Get("name").(string)),
	}

	if _, err := elbconn.CreateAppCookieStickinessPolicy(acspOpts); err != nil {
		return fmt.Errorf("Error creating AppCookieStickinessPolicy: %s", err)
	}

	setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
		LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
		LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
		PolicyNames:      []*string{aws.String(d.Get("name").(string))},
	}

	if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil {
		return fmt.Errorf("Error setting AppCookieStickinessPolicy: %s", err)
	}

	d.SetId(fmt.Sprintf("%s:%d:%s",
		*acspOpts.LoadBalancerName,
		*setLoadBalancerOpts.LoadBalancerPort,
		*acspOpts.PolicyName))
	return nil
}

func resourceAwsAppCookieStickinessPolicyRead(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	lbName, lbPort, policyName := resourceAwsAppCookieStickinessPolicyParseId(d.Id())

	request := &elb.DescribeLoadBalancerPoliciesInput{
		LoadBalancerName: aws.String(lbName),
		PolicyNames:      []*string{aws.String(policyName)},
	}

	getResp, err := elbconn.DescribeLoadBalancerPolicies(request)
	if err != nil {
		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "PolicyNotFound" {
			// The policy is gone.
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error retrieving policy: %s", err)
	}

	if len(getResp.PolicyDescriptions) != 1 {
		return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions)
	}

	// We can get away with this because there's only one attribute, the
	// cookie expiration, in these descriptions.
	policyDesc := getResp.PolicyDescriptions[0]
	cookieAttr := policyDesc.PolicyAttributeDescriptions[0]
	if *cookieAttr.AttributeName != "CookieName" {
		return fmt.Errorf("Unable to find cookie Name.")
	}
	d.Set("cookie_name", cookieAttr.AttributeValue)

	d.Set("name", policyName)
	d.Set("load_balancer", lbName)
	d.Set("lb_port", lbPort)

	return nil
}

func resourceAwsAppCookieStickinessPolicyDelete(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	lbName, _, policyName := resourceAwsAppCookieStickinessPolicyParseId(d.Id())

	// Perversely, if we Set an empty list of PolicyNames, we detach the
	// policies attached to a listener, which is required to delete the
	// policy itself.
	setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
		LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
		LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
		PolicyNames:      []*string{},
	}

	if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil {
		return fmt.Errorf("Error removing AppCookieStickinessPolicy: %s", err)
	}

	request := &elb.DeleteLoadBalancerPolicyInput{
		LoadBalancerName: aws.String(lbName),
		PolicyName:       aws.String(policyName),
	}

	if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil {
		return fmt.Errorf("Error deleting App stickiness policy %s: %s", d.Id(), err)
	}
	return nil
}

// resourceAwsAppCookieStickinessPolicyParseId takes an ID and parses it into
// it's constituent parts. You need three axes (LB name, policy name, and LB
// port) to create or identify a stickiness policy in AWS's API.
func resourceAwsAppCookieStickinessPolicyParseId(id string) (string, string, string) {
	parts := strings.SplitN(id, ":", 3)
	return parts[0], parts[1], parts[2]
}
<commit_msg>Added the validation for the app-cookie-stickiness-policy after the AWS API returned an error<commit_after>package aws

import (
	"fmt"
	"regexp"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/elb"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsAppCookieStickinessPolicy() *schema.Resource {
	return &schema.Resource{
		// There is no concept of "updating" an App Stickiness policy in
		// the AWS API.
		Create: resourceAwsAppCookieStickinessPolicyCreate,
		Update: resourceAwsAppCookieStickinessPolicyCreate,

		Read:   resourceAwsAppCookieStickinessPolicyRead,
		Delete: resourceAwsAppCookieStickinessPolicyDelete,

		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
				ValidateFunc: func(v interface{}, k string) (ws []string, es []error) {
					value := v.(string)
					if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) {
						es = append(es, fmt.Errorf(
							"only alphanumeric characters and hyphens allowed in %q", k))
					}
					return
				},
			},

			"load_balancer": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"lb_port": &schema.Schema{
				Type:     schema.TypeInt,
				Required: true,
				ForceNew: true,
			},

			"cookie_name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
		},
	}
}

func resourceAwsAppCookieStickinessPolicyCreate(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	// Provision the AppStickinessPolicy
	acspOpts := &elb.CreateAppCookieStickinessPolicyInput{
		CookieName:       aws.String(d.Get("cookie_name").(string)),
		LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
		PolicyName:       aws.String(d.Get("name").(string)),
	}

	if _, err := elbconn.CreateAppCookieStickinessPolicy(acspOpts); err != nil {
		return fmt.Errorf("Error creating AppCookieStickinessPolicy: %s", err)
	}

	setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
		LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
		LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
		PolicyNames:      []*string{aws.String(d.Get("name").(string))},
	}

	if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil {
		return fmt.Errorf("Error setting AppCookieStickinessPolicy: %s", err)
	}

	d.SetId(fmt.Sprintf("%s:%d:%s",
		*acspOpts.LoadBalancerName,
		*setLoadBalancerOpts.LoadBalancerPort,
		*acspOpts.PolicyName))
	return nil
}

func resourceAwsAppCookieStickinessPolicyRead(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	lbName, lbPort, policyName := resourceAwsAppCookieStickinessPolicyParseId(d.Id())

	request := &elb.DescribeLoadBalancerPoliciesInput{
		LoadBalancerName: aws.String(lbName),
		PolicyNames:      []*string{aws.String(policyName)},
	}

	getResp, err := elbconn.DescribeLoadBalancerPolicies(request)
	if err != nil {
		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "PolicyNotFound" {
			// The policy is gone.
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error retrieving policy: %s", err)
	}

	if len(getResp.PolicyDescriptions) != 1 {
		return fmt.Errorf("Unable to find policy %#v", getResp.PolicyDescriptions)
	}

	// We can get away with this because there's only one attribute, the
	// cookie expiration, in these descriptions.
	policyDesc := getResp.PolicyDescriptions[0]
	cookieAttr := policyDesc.PolicyAttributeDescriptions[0]
	if *cookieAttr.AttributeName != "CookieName" {
		return fmt.Errorf("Unable to find cookie Name.")
	}
	d.Set("cookie_name", cookieAttr.AttributeValue)

	d.Set("name", policyName)
	d.Set("load_balancer", lbName)
	d.Set("lb_port", lbPort)

	return nil
}

func resourceAwsAppCookieStickinessPolicyDelete(d *schema.ResourceData, meta interface{}) error {
	elbconn := meta.(*AWSClient).elbconn

	lbName, _, policyName := resourceAwsAppCookieStickinessPolicyParseId(d.Id())

	// Perversely, if we Set an empty list of PolicyNames, we detach the
	// policies attached to a listener, which is required to delete the
	// policy itself.
	setLoadBalancerOpts := &elb.SetLoadBalancerPoliciesOfListenerInput{
		LoadBalancerName: aws.String(d.Get("load_balancer").(string)),
		LoadBalancerPort: aws.Int64(int64(d.Get("lb_port").(int))),
		PolicyNames:      []*string{},
	}

	if _, err := elbconn.SetLoadBalancerPoliciesOfListener(setLoadBalancerOpts); err != nil {
		return fmt.Errorf("Error removing AppCookieStickinessPolicy: %s", err)
	}

	request := &elb.DeleteLoadBalancerPolicyInput{
		LoadBalancerName: aws.String(lbName),
		PolicyName:       aws.String(policyName),
	}

	if _, err := elbconn.DeleteLoadBalancerPolicy(request); err != nil {
		return fmt.Errorf("Error deleting App stickiness policy %s: %s", d.Id(), err)
	}
	return nil
}

// resourceAwsAppCookieStickinessPolicyParseId takes an ID and parses it into
// it's constituent parts. You need three axes (LB name, policy name, and LB
// port) to create or identify a stickiness policy in AWS's API.
func resourceAwsAppCookieStickinessPolicyParseId(id string) (string, string, string) {
	parts := strings.SplitN(id, ":", 3)
	return parts[0], parts[1], parts[2]
}
<|endoftext|>


<commit_before>package beaverguide

import (
    "strconv"
    "strings"
    "github.com/PuerkitoBio/goquery"
)

// Build course properties
func (this *Course) GetProperties() *Course {
    course := GetDocument(this.URL)
    key_facts := course.Find("#keyFacts-Content p")

    this.Department = strings.TrimPrefix(key_facts.First().Text(), "Department: ")
    this.Students, _ = strconv.Atoi(strings.Split(key_facts.Eq(1).Text(), ": ")[1])
    this.Class, _ = strconv.Atoi(strings.Split(key_facts.Eq(2).Text(), ": ")[1])

    if strings.Split(key_facts.Eq(3).Text(), " ")[1] == "Half" {
        this.Value = 0.5
    } else {
        this.Value = 1
    }

    teachers := strings.Replace(course.Find("#teacherResponsible-Content p").First().Text(), " and", ",", -1)
    this.Teachers = strings.Split(teachers, ", ")

    this.Availability = FormatProperty(course.Find("#availability-Content p"))
    this.Prerequisites = FormatProperty(course.Find("#preRequisites-Content p"))
    this.Content = FormatProperty(course.Find("#courseContent-Content p"))
    this.Teaching = FormatProperty(course.Find("#teaching-Content p"))
    this.Formative = FormatProperty(course.Find("#formativeCoursework-Content p"))
    this.Readings = FormatProperty(course.Find("#indicativeReading-Content p"))
    this.Assessments = FormatProperty(course.Find("#assessment-Content p"))

    return this
}

func FormatProperty(paragraphs *goquery.Selection) string {
    no_html := strings.Join(paragraphs.Map(func(i int, s *goquery.Selection) string {
        return s.Text()
    }), "\n")
    return strings.TrimSpace(no_html)
}<commit_msg>Added GetProperties() function (return is not necessary; changes through pointer)<commit_after>package beaverguide

import (
    "strconv"
    "strings"
    "sync"
    "github.com/PuerkitoBio/goquery"
)

// Build properties for a course
func (this *Course) GetProperties() *Course {
    course := GetDocument(this.URL)
    key_facts := course.Find("#keyFacts-Content p")

    this.Department = strings.TrimPrefix(key_facts.First().Text(), "Department: ")
    this.Students, _ = strconv.Atoi(strings.Split(key_facts.Eq(1).Text(), ": ")[1])
    this.Class, _ = strconv.Atoi(strings.Split(key_facts.Eq(2).Text(), ": ")[1])

    if strings.Split(key_facts.Eq(3).Text(), " ")[1] == "Half" {
        this.Value = 0.5
    } else {
        this.Value = 1
    }

    teachers := strings.Replace(course.Find("#teacherResponsible-Content p").First().Text(), " and", ",", -1)
    this.Teachers = strings.Split(teachers, ", ")

    this.Availability = FormatProperty(course.Find("#availability-Content p"))
    this.Prerequisites = FormatProperty(course.Find("#preRequisites-Content p"))
    this.Content = FormatProperty(course.Find("#courseContent-Content p"))
    this.Teaching = FormatProperty(course.Find("#teaching-Content p"))
    this.Formative = FormatProperty(course.Find("#formativeCoursework-Content p"))
    this.Readings = FormatProperty(course.Find("#indicativeReading-Content p"))
    this.Assessments = FormatProperty(course.Find("#assessment-Content p"))

    return this
}

// Build properties for all courses
func (this Courses) GetProperties() Courses {
    var wg sync.WaitGroup
    wg.Add(len(this))

    for _, course := range this {
        go func(course *Course) {
            defer wg.Done()
            course.GetProperties()
        }(course)
    }

    wg.Wait()
    return this
}

func FormatProperty(paragraphs *goquery.Selection) string {
    no_html := strings.Join(paragraphs.Map(func(i int, s *goquery.Selection) string {
        return s.Text()
    }), "\n")
    return strings.TrimSpace(no_html)
}<|endoftext|>


<commit_before>/*live-hosts reads an nmap xml file from stdin or as an argument and shows the hosts that are alive*/
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/lair-framework/go-nmap"
)

func checkError(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
func main() {
	var file *os.File
	var err error
	pUp := flag.Bool("p", false, "host must have at least one port to be alive")
	flag.Parse()
	if len(flag.Args()) >= 1 {
		file, err = os.Open(flag.Arg(0))
		checkError(err)
	} else {
		file = os.Stdin
	}
	data, err := ioutil.ReadAll(file)
	checkError(err)
	n, err := nmap.Parse(data)
	checkError(err)

	for _, h := range n.Hosts {
		if h.Status.State == "up" {
			if *pUp {
				for _, p := range h.Ports {
					if p.State.State == "open" {
						fmt.Println(h.Address[0].Addr)
						break
					}
				}
				continue
			}
			fmt.Println(h.Address[0].Addr)
		}
	}
}
<commit_msg>upstream change to nmap lib<commit_after>/*live-hosts reads an nmap xml file from stdin or as an argument and shows the hosts that are alive*/
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"

	"github.com/lair-framework/go-nmap"
)

func checkError(err error) {
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}
func main() {
	var file *os.File
	var err error
	pUp := flag.Bool("p", false, "host must have at least one port to be alive")
	flag.Parse()
	if len(flag.Args()) >= 1 {
		file, err = os.Open(flag.Arg(0))
		checkError(err)
	} else {
		file = os.Stdin
	}
	data, err := ioutil.ReadAll(file)
	checkError(err)
	n, err := nmap.Parse(data)
	checkError(err)

	for _, h := range n.Hosts {
		if h.Status.State == "up" {
			if *pUp {
				for _, p := range h.Ports {
					if p.State.State == "open" {
						fmt.Println(h.Addresses[0].Addr)
						break
					}
				}
				continue
			}
			fmt.Println(h.Addresses[0].Addr)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 xeipuuv ( https://github.com/xeipuuv )
//
// 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.

// author  			xeipuuv
// author-github 	https://github.com/xeipuuv
// author-mail		xeipuuv@gmail.com
//
// repository-name	gojsonpointer
// repository-desc	An implementation of JSON Pointer - Go language
//
// description		Main and unique file.
//
// created      	25-02-2013

package gojsonpointer

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

const (
	const_empty_pointer     = ``
	const_pointer_separator = `/`

	const_invalid_start = `JSON pointer must be empty or start with a "` + const_pointer_separator + `"`
)

type implStruct struct {
	mode string // "SET" or "GET"

	inDocument interface{}

	setInValue interface{}

	getOutNode interface{}
	getOutKind reflect.Kind
	outError   error
}

type JsonPointer struct {
	referenceTokens []string
}

// NewJsonPointer parses the given string JSON pointer and returns an object
func NewJsonPointer(jsonPointerString string) (p JsonPointer, err error) {

	// Pointer to the root of the document
	if len(jsonPointerString) == 0 {
		// Keep referenceTokens nil
		return
	}
	if jsonPointerString[0] != '/' {
		return p, errors.New(const_invalid_start)
	}

	p.referenceTokens = strings.Split(jsonPointerString[1:], const_pointer_separator)
	return
}

// Uses the pointer to retrieve a value from a JSON document
func (p *JsonPointer) Get(document interface{}) (interface{}, reflect.Kind, error) {

	is := &implStruct{mode: "GET", inDocument: document}
	p.implementation(is)
	return is.getOutNode, is.getOutKind, is.outError

}

// Uses the pointer to update a value from a JSON document
func (p *JsonPointer) Set(document interface{}, value interface{}) (interface{}, error) {

	is := &implStruct{mode: "SET", inDocument: document, setInValue: value}
	p.implementation(is)
	return document, is.outError

}

// Both Get and Set functions use the same implementation to avoid code duplication
func (p *JsonPointer) implementation(i *implStruct) {

	kind := reflect.Invalid

	// Full document when empty
	if len(p.referenceTokens) == 0 {
		i.getOutNode = i.inDocument
		i.outError = nil
		i.getOutKind = kind
		i.outError = nil
		return
	}

	node := i.inDocument

	for ti, token := range p.referenceTokens {

		isLastToken := ti == len(p.referenceTokens)-1

		switch v := node.(type) {

		case map[string]interface{}:
			decodedToken := decodeReferenceToken(token)
			if _, ok := v[decodedToken]; ok {
				node = v[decodedToken]
				if isLastToken && i.mode == "SET" {
					v[decodedToken] = i.setInValue
				}
			} else {
				i.outError = fmt.Errorf("Object has no key '%s'", decodedToken)
				i.getOutKind = reflect.Map
				i.getOutNode = nil
				return
			}

		case []interface{}:
			tokenIndex, err := strconv.Atoi(token)
			if err != nil {
				i.outError = fmt.Errorf("Invalid array index '%s'", token)
				i.getOutKind = reflect.Slice
				i.getOutNode = nil
				return
			}
			if tokenIndex < 0 || tokenIndex >= len(v) {
				i.outError = fmt.Errorf("Out of bound array[0,%d] index '%d'", len(v), tokenIndex)
				i.getOutKind = reflect.Slice
				i.getOutNode = nil
				return
			}

			node = v[tokenIndex]
			if isLastToken && i.mode == "SET" {
				v[tokenIndex] = i.setInValue
			}

		default:
			i.outError = fmt.Errorf("Invalid token reference '%s'", token)
			i.getOutKind = reflect.ValueOf(node).Kind()
			i.getOutNode = nil
			return
		}

	}

	i.getOutNode = node
	i.getOutKind = reflect.ValueOf(node).Kind()
	i.outError = nil
}

// Pointer to string representation function
func (p *JsonPointer) String() string {

	if len(p.referenceTokens) == 0 {
		return const_empty_pointer
	}

	pointerString := const_pointer_separator + strings.Join(p.referenceTokens, const_pointer_separator)

	return pointerString
}

// Specific JSON pointer encoding here
// ~0 => ~
// ~1 => /
// ... and vice versa

const (
	const_encoded_reference_token_0 = `~0`
	const_encoded_reference_token_1 = `~1`
	const_decoded_reference_token_0 = `~`
	const_decoded_reference_token_1 = `/`
)

func decodeReferenceToken(token string) string {
	step1 := strings.Replace(token, const_encoded_reference_token_1, const_decoded_reference_token_1, -1)
	step2 := strings.Replace(step1, const_encoded_reference_token_0, const_decoded_reference_token_0, -1)
	return step2
}

func encodeReferenceToken(token string) string {
	step1 := strings.Replace(token, const_decoded_reference_token_1, const_encoded_reference_token_1, -1)
	step2 := strings.Replace(step1, const_decoded_reference_token_0, const_encoded_reference_token_0, -1)
	return step2
}
<commit_msg>Remove useless constant that hide an issue in encodeReferenceToken (1/2)<commit_after>// Copyright 2015 xeipuuv ( https://github.com/xeipuuv )
//
// 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.

// author  			xeipuuv
// author-github 	https://github.com/xeipuuv
// author-mail		xeipuuv@gmail.com
//
// repository-name	gojsonpointer
// repository-desc	An implementation of JSON Pointer - Go language
//
// description		Main and unique file.
//
// created      	25-02-2013

package gojsonpointer

import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"strings"
)

const (
	const_empty_pointer     = ``
	const_pointer_separator = `/`

	const_invalid_start = `JSON pointer must be empty or start with a "` + const_pointer_separator + `"`
)

type implStruct struct {
	mode string // "SET" or "GET"

	inDocument interface{}

	setInValue interface{}

	getOutNode interface{}
	getOutKind reflect.Kind
	outError   error
}

type JsonPointer struct {
	referenceTokens []string
}

// NewJsonPointer parses the given string JSON pointer and returns an object
func NewJsonPointer(jsonPointerString string) (p JsonPointer, err error) {

	// Pointer to the root of the document
	if len(jsonPointerString) == 0 {
		// Keep referenceTokens nil
		return
	}
	if jsonPointerString[0] != '/' {
		return p, errors.New(const_invalid_start)
	}

	p.referenceTokens = strings.Split(jsonPointerString[1:], const_pointer_separator)
	return
}

// Uses the pointer to retrieve a value from a JSON document
func (p *JsonPointer) Get(document interface{}) (interface{}, reflect.Kind, error) {

	is := &implStruct{mode: "GET", inDocument: document}
	p.implementation(is)
	return is.getOutNode, is.getOutKind, is.outError

}

// Uses the pointer to update a value from a JSON document
func (p *JsonPointer) Set(document interface{}, value interface{}) (interface{}, error) {

	is := &implStruct{mode: "SET", inDocument: document, setInValue: value}
	p.implementation(is)
	return document, is.outError

}

// Both Get and Set functions use the same implementation to avoid code duplication
func (p *JsonPointer) implementation(i *implStruct) {

	kind := reflect.Invalid

	// Full document when empty
	if len(p.referenceTokens) == 0 {
		i.getOutNode = i.inDocument
		i.outError = nil
		i.getOutKind = kind
		i.outError = nil
		return
	}

	node := i.inDocument

	for ti, token := range p.referenceTokens {

		isLastToken := ti == len(p.referenceTokens)-1

		switch v := node.(type) {

		case map[string]interface{}:
			decodedToken := decodeReferenceToken(token)
			if _, ok := v[decodedToken]; ok {
				node = v[decodedToken]
				if isLastToken && i.mode == "SET" {
					v[decodedToken] = i.setInValue
				}
			} else {
				i.outError = fmt.Errorf("Object has no key '%s'", decodedToken)
				i.getOutKind = reflect.Map
				i.getOutNode = nil
				return
			}

		case []interface{}:
			tokenIndex, err := strconv.Atoi(token)
			if err != nil {
				i.outError = fmt.Errorf("Invalid array index '%s'", token)
				i.getOutKind = reflect.Slice
				i.getOutNode = nil
				return
			}
			if tokenIndex < 0 || tokenIndex >= len(v) {
				i.outError = fmt.Errorf("Out of bound array[0,%d] index '%d'", len(v), tokenIndex)
				i.getOutKind = reflect.Slice
				i.getOutNode = nil
				return
			}

			node = v[tokenIndex]
			if isLastToken && i.mode == "SET" {
				v[tokenIndex] = i.setInValue
			}

		default:
			i.outError = fmt.Errorf("Invalid token reference '%s'", token)
			i.getOutKind = reflect.ValueOf(node).Kind()
			i.getOutNode = nil
			return
		}

	}

	i.getOutNode = node
	i.getOutKind = reflect.ValueOf(node).Kind()
	i.outError = nil
}

// Pointer to string representation function
func (p *JsonPointer) String() string {

	if len(p.referenceTokens) == 0 {
		return const_empty_pointer
	}

	pointerString := const_pointer_separator + strings.Join(p.referenceTokens, const_pointer_separator)

	return pointerString
}

// Specific JSON pointer encoding here
// ~0 => ~
// ~1 => /
// ... and vice versa

const (
	const_encoded_reference_token_0 = `~0`
	const_decoded_reference_token_0 = `~`
)

func decodeReferenceToken(token string) string {
	step1 := strings.Replace(token, `~1`, `/`, -1)
	step2 := strings.Replace(step1, const_encoded_reference_token_0, const_decoded_reference_token_0, -1)
	return step2
}

func encodeReferenceToken(token string) string {
	step1 := strings.Replace(token, `/`, `~1`, -1)
	step2 := strings.Replace(step1, const_decoded_reference_token_0, const_encoded_reference_token_0, -1)
	return step2
}
<|endoftext|>


<commit_before>package scp

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/viant/toolbox"
	"github.com/viant/toolbox/ssh"
	"github.com/viant/toolbox/storage"
	"io"
	"io/ioutil"
	"net/url"
	"strings"

	"path"
	"github.com/viant/toolbox/cred"
)

const defaultSSHPort = 22

const (
	fileInfoPermission = iota
	_
	fileInfoOwner
	fileInfoGroup
	fileInfoSize
	fileInfoDateMonth
	fileInfoDateDay
	fileInfoDateHour
	fileInfoDateYear
	fileInfoName
)

type service struct {
	config *cred.Config
}

func (s *service) runCommand(URL string, command string) (string, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return "", err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = 22
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return "", err
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		return "", err
	}
	defer session.Close()
	output, err := session.CombinedOutput(command)
	if err != nil {
		return "", err
	}
	return toolbox.AsString(output), err

}

//List returns a list of object for supplied URL
func (s *service) List(URL string) ([]storage.Object, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return nil, err
	}

	var result = make([]storage.Object, 0)
	output, err := s.runCommand(URL, "ls -lTtr "+parsedUrl.Path)
	if strings.Contains(string(output), "No such file or directory") {
		return result, nil
	}

	var fileNameFilter = ""
	if err == nil && output == "" {
		parent, fileName := path.Split(parsedUrl.Path)
		fileNameFilter = fileName
		output, err = s.runCommand(URL, "ls -lTtr "+parent+" | grep "+fileName)
	}
	if err != nil {
		return nil, err
	}

	for _, line := range strings.Split(string(output), "\n") {
		fileInfo := extractFileInfo(line)
		if fileInfo.name == "" {
			continue
		}
		fileInfo.url = URL
		if fileNameFilter == "" || fileNameFilter == fileInfo.name {
			result = append(result, fileInfo)
		}
	}
	return result, nil
}

func extractFileInfo(line string) *object {
	fragmentCount := 0
	fileInfo := &object{}
	for i := range line {

		aChar := string(line[i])
		if aChar == " " || aChar == "\t" {
			if i+1 < len(line) {
				nextChar := string(line[i+1])
				if !(nextChar == " " || nextChar == "\t") {
					fragmentCount++
				}
			}
			continue
		}
		switch fragmentCount {

		case fileInfoPermission:
			fileInfo.permission += aChar
		case fileInfoOwner:
			fileInfo.owner += aChar
		case fileInfoGroup:
			fileInfo.group += aChar
		case fileInfoSize:
			fileInfo.size += aChar
		case fileInfoDateMonth:
			fileInfo.month += aChar
		case fileInfoDateDay:
			fileInfo.day += aChar
		case fileInfoDateHour:
			fileInfo.hour += aChar
		case fileInfoDateYear:
			fileInfo.year += aChar
		case fileInfoName:
			fileInfo.name += aChar
		}

	}
	return fileInfo
}

func (s *service) Exists(URL string) (bool, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return false, err
	}
	output, err := s.runCommand(URL, "ls -lTtr "+parsedUrl.Path)
	if strings.Contains(string(output), "No such file or directory") {
		return false, nil
	}
	return true, nil

}

func (s *service) StorageObject(URL string) (storage.Object, error) {
	objects, err := s.List(URL)
	if err != nil {
		return nil, err
	}
	if len(objects) == 0 {
		return nil, fmt.Errorf("No found %v", URL)
	}
	return objects[0], nil
}

//Download returns reader for downloaded storage object
func (s *service) Download(object storage.Object) (io.Reader, error) {
	if object == nil {
		return nil, fmt.Errorf("Object was nil")
	}
	parsedUrl, err := url.Parse(object.URL())
	if err != nil {
		return nil, err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = defaultSSHPort
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return nil, err
	}
	defer client.Close()

	content, err := client.Download(parsedUrl.Path)
	if err != nil {
		return nil, err
	}
	return bytes.NewReader(content), nil
}

//Upload uploads provided reader content for supplied URL.
func (s *service) Upload(URL string, reader io.Reader) error {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = defaultSSHPort
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return err
	}
	defer client.Close()

	content, err := ioutil.ReadAll(reader)
	if err != nil {
		return fmt.Errorf("Failed to upload - unable read: %v", err)
	}
	return client.Upload(parsedUrl.Path, content)
}

func (s *service) Register(schema string, service storage.Service) error {
	return errors.New("unsupported")
}

//Delete removes passed in storage object
func (s *service) Delete(object storage.Object) error {
	parsedUrl, err := url.Parse(object.URL())
	if err != nil {
		return err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = defaultSSHPort
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return err
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	if parsedUrl.Path == "/" {
		return fmt.Errorf("Invalid removal path: %v", parsedUrl.Path)
	}
	_, err = session.Output("rm -rf " + parsedUrl.Path)
	return err
}

//NewService create a new gc storage service
func NewService(config *cred.Config) *service {
	return &service{
		config: config,
	}
}
<commit_msg>added scp verification<commit_after>package scp

import (
	"bytes"
	"errors"
	"fmt"
	"github.com/viant/toolbox"
	"github.com/viant/toolbox/ssh"
	"github.com/viant/toolbox/storage"
	"io"
	"io/ioutil"
	"net/url"
	"strings"

	"path"
	"github.com/viant/toolbox/cred"
)

const defaultSSHPort = 22

const (
	fileInfoPermission = iota
	_
	fileInfoOwner
	fileInfoGroup
	fileInfoSize
	fileInfoDateMonth
	fileInfoDateDay
	fileInfoDateHour
	fileInfoDateYear
	fileInfoName
)

type service struct {
	config *cred.Config
}

func (s *service) runCommand(URL string, command string) (string, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return "", err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = 22
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return "", err
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		return "", err
	}
	defer session.Close()
	output, err := session.CombinedOutput(command)
	if err != nil {
		return "", err
	}
	return toolbox.AsString(output), err

}

//List returns a list of object for supplied URL
func (s *service) List(URL string) ([]storage.Object, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return nil, err
	}

	var result = make([]storage.Object, 0)
	output, err := s.runCommand(URL, "ls -lTtr "+parsedUrl.Path)
	if strings.Contains(string(output), "No such file or directory") {
		return result, nil
	}

	var fileNameFilter = ""
	if err == nil && output == "" {
		parent, fileName := path.Split(parsedUrl.Path)
		fileNameFilter = fileName
		output, err = s.runCommand(URL, "ls -lTtr "+parent+" | grep "+fileName)
	}
	if err != nil {
		return nil, err
	}

	for _, line := range strings.Split(string(output), "\n") {
		fileInfo := extractFileInfo(line)
		if fileInfo.name == "" {
			continue
		}
		fileInfo.url = URL
		if fileNameFilter == "" || fileNameFilter == fileInfo.name {
			result = append(result, fileInfo)
		}
	}
	return result, nil
}

func extractFileInfo(line string) *object {
	fragmentCount := 0
	fileInfo := &object{}
	for i := range line {

		aChar := string(line[i])
		if aChar == " " || aChar == "\t" {
			if i+1 < len(line) {
				nextChar := string(line[i+1])
				if !(nextChar == " " || nextChar == "\t") {
					fragmentCount++
				}
			}
			continue
		}
		switch fragmentCount {

		case fileInfoPermission:
			fileInfo.permission += aChar
		case fileInfoOwner:
			fileInfo.owner += aChar
		case fileInfoGroup:
			fileInfo.group += aChar
		case fileInfoSize:
			fileInfo.size += aChar
		case fileInfoDateMonth:
			fileInfo.month += aChar
		case fileInfoDateDay:
			fileInfo.day += aChar
		case fileInfoDateHour:
			fileInfo.hour += aChar
		case fileInfoDateYear:
			fileInfo.year += aChar
		case fileInfoName:
			fileInfo.name += aChar
		}

	}
	return fileInfo
}

func (s *service) Exists(URL string) (bool, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return false, err
	}
	output, err := s.runCommand(URL, "ls -lTtr "+parsedUrl.Path)
	if strings.Contains(string(output), "No such file or directory") {
		return false, nil
	}
	return true, nil

}

func (s *service) StorageObject(URL string) (storage.Object, error) {
	objects, err := s.List(URL)
	if err != nil {
		return nil, err
	}
	if len(objects) == 0 {
		return nil, fmt.Errorf("No found %v", URL)
	}
	return objects[0], nil
}

//Download returns reader for downloaded storage object
func (s *service) Download(object storage.Object) (io.Reader, error) {
	if object == nil {
		return nil, fmt.Errorf("Object was nil")
	}
	parsedUrl, err := url.Parse(object.URL())
	if err != nil {
		return nil, err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = defaultSSHPort
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return nil, err
	}
	defer client.Close()

	content, err := client.Download(parsedUrl.Path)
	if err != nil {
		return nil, err
	}

	//download verification (as sometimes scp failed) with one retry
	if int(object.Size()) != len(content) {
		content, err = client.Download(parsedUrl.Path)
		if err != nil {
			return nil, err
		}
		if int(object.Size()) != len(content) {
			return nil, fmt.Errorf("Faled to download from %v,  object size was: %v, but scp download was %v", object.URL(), object.Size(), len(content))
		}
	}
	return bytes.NewReader(content), nil
}

//Upload uploads provided reader content for supplied URL.
func (s *service) Upload(URL string, reader io.Reader) error {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = defaultSSHPort
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return err
	}
	defer client.Close()

	content, err := ioutil.ReadAll(reader)
	if err != nil {
		return fmt.Errorf("Failed to upload - unable read: %v", err)
	}

	err = client.Upload(parsedUrl.Path, content)
	object, err := s.StorageObject(URL)
	if err != nil {
		return  err
	}
	if int(object.Size()) != len(content) {
		err = client.Upload(parsedUrl.Path, content)
		object, err = s.StorageObject(URL)
		if err != nil {
			return  err
		}
		if int(object.Size()) != len(content) {
			return fmt.Errorf("Failed to upload to %v, actual size was:%v,  but uploaded size was  ", URL, len(content), int(object.Size()))
		}
	}
	return err
}

func (s *service) Register(schema string, service storage.Service) error {
	return errors.New("unsupported")
}

//Delete removes passed in storage object
func (s *service) Delete(object storage.Object) error {
	parsedUrl, err := url.Parse(object.URL())
	if err != nil {
		return err
	}

	port := toolbox.AsInt(parsedUrl.Port())
	if port == 0 {
		port = defaultSSHPort
	}
	client, err := ssh.NewClient(parsedUrl.Hostname(), toolbox.AsInt(port), s.config)
	if err != nil {
		return err
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		return err
	}
	defer session.Close()

	if parsedUrl.Path == "/" {
		return fmt.Errorf("Invalid removal path: %v", parsedUrl.Path)
	}
	_, err = session.Output("rm -rf " + parsedUrl.Path)
	return err
}

//NewService create a new gc storage service
func NewService(config *cred.Config) *service {
	return &service{
		config: config,
	}
}
<|endoftext|>


<commit_before>package fly

import (
	"bufio"
	"encoding/binary"
	"io"
	"log"
	"net"
)

const (
	LFlagRPC   byte = 0x80
	LFlagResp  byte = 0x40
	LFlagError byte = 0x20
	// LFLAG_NOTIFY byte = 0x10
	// LFLAG_LEN_16 byte = 0x08
	LFlagBuffer byte = 0x04
	// LFLAG_ZIP         byte = 0x02
	// LFLAG_ENCRYPT     byte = 0x01
)

type TCmd uint8
type TSeq uint8
type TLength uint16

const MaxLength = ^TLength(0)

type Header struct {
	Flag byte
	Cmd  TCmd
	Seq  TSeq
}

type Packet struct {
	// TODO remove this from packet
	Protocol Protocol
	ClientId int
	Length   TLength
	Header   *Header
	MsgBuff  []byte
}

type PacketHandler func(*Packet)

type Protocol interface {
	OnPacket(PacketHandler)
	SendPacket(*Packet) error
}

type protocol struct {
	IsMultiplex bool
	Conn        net.Conn
	Reader      *bufio.Reader
	Writer      *bufio.Writer
	handlers    []PacketHandler
}

func NewProtocol(conn net.Conn, isMultiplex bool) Protocol {
	return newProtocol(conn, conn, isMultiplex)
}

func newProtocol(reader io.Reader, writer io.Writer, isMultiplex bool) Protocol {
	p := &protocol{
		IsMultiplex: isMultiplex,
		Reader:      bufio.NewReader(reader),
		Writer:      bufio.NewWriter(writer),
		handlers:    make([]PacketHandler, 0),
	}
	go p.handleStream()
	return p
}

func (p *protocol) Close() error {
	if p.Conn != nil {
		return p.Conn.Close()
	}
	return nil
}

func (p *protocol) OnPacket(handler PacketHandler) {
	p.handlers = append(p.handlers, handler)
}

func (p *protocol) SendPacket(pk *Packet) error {
	log.Println("Sending:", pk.ClientId, pk.Header, pk.MsgBuff)
	if p.Writer == nil {
		err := p.Close()
		return NewFlyError(ErrWriterClosed, err)
	}
	if p.Writer.Available() == 0 {
		return NewFlyError(ErrWriterClosed, nil)
	}
	if p.IsMultiplex {
		if err := binary.Write(p.Writer, binary.BigEndian, pk.ClientId); err != nil {
			return err
		}
	}
	// if support zip {
	// DO zip
	// buff = zip(buff)
	// }
	pk.Length = TLength(len(pk.MsgBuff))
	if pk.Length > MaxLength {
		return NewFlyError(ErrBuffTooLong, nil)
	}
	if err := binary.Write(p.Writer, binary.BigEndian, pk.Header); err != nil {
		return err
	}
	log.Println("Length:", pk.Length)

	if err := binary.Write(p.Writer, binary.BigEndian, pk.Length); err != nil {
		return err
	}
	log.Println("Buff:", pk.MsgBuff)
	if _, err := p.Writer.Write(pk.MsgBuff); err != nil {
		return err
	}
	return p.Writer.Flush()
}

func (p *protocol) handleStream() {
	// 协议处理函数
	for {
		msg, err := p.ReadPacket()
		log.Println("readPacket:", msg, err)
		if err != nil {
			if err != io.EOF {
				log.Println("error", err)
			}
			_ = p.Close()
			break
		}
		// emitPacket
		for _, handler := range p.handlers {
			go handler(msg)
		}
	}
}

func (p *protocol) ReadPacket() (*Packet, error) {
	var clientId = 0
	if p.IsMultiplex {
		err := binary.Read(p.Reader, binary.BigEndian, &clientId)
		if err != nil {
			return nil, err
		}
	}
	// read header
	header := &Header{}
	err := binary.Read(p.Reader, binary.BigEndian, header)
	if err != nil {
		return nil, err
	}
	// read length
	var length TLength
	err = binary.Read(p.Reader, binary.BigEndian, &length)
	if err != nil {
		return nil, err
	}
	buf := make([]byte, length)
	_, err = io.ReadFull(p.Reader, buf)
	if err != nil {
		return nil, err
	}
	log.Println("return packet", buf)
	packet := &Packet{
		ClientId: clientId,
		Length:   length,
		Header:   header,
		MsgBuff:  buf,
	}
	return packet, nil
}
<commit_msg>update flag<commit_after>package fly

import (
	"bufio"
	"encoding/binary"
	"io"
	"log"
	"net"
)

const (
	LFlagRPC    byte = 0x80
	LFlagResp   byte = 0x40
	LFlagError  byte = 0x20
	LFlagBuffer byte = 0x10
	// LFLAG_NOTIFY byte = 0x10
	// LFLAG_LEN_16 byte = 0x08
	// LFLAG_ZIP         byte = 0x02
	// LFLAG_ENCRYPT     byte = 0x01
)

type TCmd uint8
type TSeq uint8
type TLength uint16

const MaxLength = ^TLength(0)

type Header struct {
	Flag byte
	Cmd  TCmd
	Seq  TSeq
}

type Packet struct {
	// TODO remove this from packet
	Protocol Protocol
	ClientId int
	Length   TLength
	Header   *Header
	MsgBuff  []byte
}

type PacketHandler func(*Packet)

type Protocol interface {
	OnPacket(PacketHandler)
	SendPacket(*Packet) error
}

type protocol struct {
	IsMultiplex bool
	Conn        net.Conn
	Reader      *bufio.Reader
	Writer      *bufio.Writer
	handlers    []PacketHandler
}

func NewProtocol(conn net.Conn, isMultiplex bool) Protocol {
	return newProtocol(conn, conn, isMultiplex)
}

func newProtocol(reader io.Reader, writer io.Writer, isMultiplex bool) Protocol {
	p := &protocol{
		IsMultiplex: isMultiplex,
		Reader:      bufio.NewReader(reader),
		Writer:      bufio.NewWriter(writer),
		handlers:    make([]PacketHandler, 0),
	}
	go p.handleStream()
	return p
}

func (p *protocol) Close() error {
	if p.Conn != nil {
		return p.Conn.Close()
	}
	return nil
}

func (p *protocol) OnPacket(handler PacketHandler) {
	p.handlers = append(p.handlers, handler)
}

func (p *protocol) SendPacket(pk *Packet) error {
	log.Println("Sending:", pk.ClientId, pk.Header, pk.MsgBuff)
	if p.Writer == nil {
		err := p.Close()
		return NewFlyError(ErrWriterClosed, err)
	}
	if p.Writer.Available() == 0 {
		return NewFlyError(ErrWriterClosed, nil)
	}
	if p.IsMultiplex {
		if err := binary.Write(p.Writer, binary.BigEndian, pk.ClientId); err != nil {
			return err
		}
	}
	// if support zip {
	// DO zip
	// buff = zip(buff)
	// }
	pk.Length = TLength(len(pk.MsgBuff))
	if pk.Length > MaxLength {
		return NewFlyError(ErrBuffTooLong, nil)
	}
	if err := binary.Write(p.Writer, binary.BigEndian, pk.Header); err != nil {
		return err
	}
	log.Println("Length:", pk.Length)

	if err := binary.Write(p.Writer, binary.BigEndian, pk.Length); err != nil {
		return err
	}
	log.Println("Buff:", pk.MsgBuff)
	if _, err := p.Writer.Write(pk.MsgBuff); err != nil {
		return err
	}
	return p.Writer.Flush()
}

func (p *protocol) handleStream() {
	// 协议处理函数
	for {
		msg, err := p.ReadPacket()
		log.Println("readPacket:", msg, err)
		if err != nil {
			if err != io.EOF {
				log.Println("error", err)
			}
			_ = p.Close()
			break
		}
		// emitPacket
		for _, handler := range p.handlers {
			go handler(msg)
		}
	}
}

func (p *protocol) ReadPacket() (*Packet, error) {
	var clientId = 0
	// only for server
	if p.IsMultiplex {
		err := binary.Read(p.Reader, binary.BigEndian, &clientId)
		if err != nil {
			return nil, err
		}
	}
	// read header
	header := &Header{}
	err := binary.Read(p.Reader, binary.BigEndian, header)
	if err != nil {
		return nil, err
	}
	// read length
	var length TLength
	err = binary.Read(p.Reader, binary.BigEndian, &length)
	if err != nil {
		return nil, err
	}
	buf := make([]byte, length)
	_, err = io.ReadFull(p.Reader, buf)
	if err != nil {
		return nil, err
	}
	log.Println("return packet", buf)
	packet := &Packet{
		ClientId: clientId,
		Length:   length,
		Header:   header,
		MsgBuff:  buf,
	}
	return packet, nil
}
<|endoftext|>


<commit_before>package tty

import (
	"log"
	"os"
	"syscall"
	"unsafe"
)

type termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

// Ttty covers the unexported real tty info in
// a termios struct.
type Tty struct {
	original *termios
}

func tcSetAttr(fd uintptr, termios *termios) error {
	// TCSETS+1 == TCSETSW, because TCSAFLUSH doesn't exist
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func tcGetAttr(fd uintptr) *termios {
	var termios = &termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		log.Fatalf("Problem getting terminal attributes: %s\n", err)
	}
	return termios
}

// EnableRawMode changes tty settings so that the program can control
// cursor position etc, and so that the program only blocks for a short
// while when reading bytes from stdin.
func (t *Tty) EnableRawMode() {
	t.original = tcGetAttr(os.Stdin.Fd())
	var raw termios
	raw = *t.original
	raw.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON
	raw.Oflag &^= syscall.OPOST
	raw.Cflag |= syscall.CS8
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG
	raw.Cc[syscall.VMIN+1] = 0
	raw.Cc[syscall.VTIME+1] = 1
	if e := tcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		log.Fatalf("Problem enabling raw mode: %s\n", e)
	}
}

// DisableRawMode resets tty termios attributes to what they
// were originally.
func (t *Tty) DisableRawMode() {
	if e := tcSetAttr(os.Stdin.Fd(), t.original); e != nil {
		log.Fatalf("Problem disabling raw mode: %s\n", e)
	}
}
<commit_msg>Fix misspelling in comment.<commit_after>package tty

import (
	"log"
	"os"
	"syscall"
	"unsafe"
)

type termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

// Tty covers the unexported real tty info in
// a termios struct.
type Tty struct {
	original *termios
}

func tcSetAttr(fd uintptr, termios *termios) error {
	// TCSETS+1 == TCSETSW, because TCSAFLUSH doesn't exist
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func tcGetAttr(fd uintptr) *termios {
	var termios = &termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		log.Fatalf("Problem getting terminal attributes: %s\n", err)
	}
	return termios
}

// EnableRawMode changes tty settings so that the program can control
// cursor position etc, and so that the program only blocks for a short
// while when reading bytes from stdin.
func (t *Tty) EnableRawMode() {
	t.original = tcGetAttr(os.Stdin.Fd())
	var raw termios
	raw = *t.original
	raw.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON
	raw.Oflag &^= syscall.OPOST
	raw.Cflag |= syscall.CS8
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG
	raw.Cc[syscall.VMIN+1] = 0
	raw.Cc[syscall.VTIME+1] = 1
	if e := tcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		log.Fatalf("Problem enabling raw mode: %s\n", e)
	}
}

// DisableRawMode resets tty termios attributes to what they
// were originally.
func (t *Tty) DisableRawMode() {
	if e := tcSetAttr(os.Stdin.Fd(), t.original); e != nil {
		log.Fatalf("Problem disabling raw mode: %s\n", e)
	}
}
<|endoftext|>


<commit_before>
package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rotr rot13Reader) Read(b []byte) (int, error) {
	n, e := rotr.r.Read(b)
	for i := 0; i < n; i++ {
		switch {
		case 'a' <= b[i] && b[i] <= 'z':
			b[i] = 'a'+(b[i]-'a'+13)%26
		case 'A' <= b[i] && b[i] <= 'Z':
			b[i] = 'A'+(b[i]-'A'+13)%26
		}
	}
	return n, e
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!\n")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}
<commit_msg>Updated "rot13Reader" exercise description (from the Go Tour)<commit_after>/* Taken from the Go Tour (Exercise: rot13Reader)
 *
 * A common pattern is an io.Reader that wraps another io.Reader, modifying the stream in some way.
 *
 * For example, the gzip.NewReader function takes an io.Reader (a stream of compressed data) and
 * returns a *gzip.Reader that also implements io.Reader (a stream of the decompressed data).
 *
 * Implement a rot13Reader that implements io.Reader and reads from an io.Reader, modifying the
 * stream by applying the rot13 substitution cipher to all alphabetical characters.
 *
 * The rot13Reader type is provided for you. Make it an io.Reader by implementing its Read method.
 *
 */

package main

import (
	"io"
	"os"
	"strings"
)

type rot13Reader struct {
	r io.Reader
}

func (rotr rot13Reader) Read(b []byte) (int, error) {
	n, e := rotr.r.Read(b)
	for i := 0; i < n; i++ {
		switch {
		case 'a' <= b[i] && b[i] <= 'z':
			b[i] = 'a'+(b[i]-'a'+13)%26
		case 'A' <= b[i] && b[i] <= 'Z':
			b[i] = 'A'+(b[i]-'A'+13)%26
		}
	}
	return n, e
}

func main() {
	s := strings.NewReader("Lbh penpxrq gur pbqr!\n")
	r := rot13Reader{s}
	io.Copy(os.Stdout, &r)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/takama/daemon"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
)

// #include <wiringPi.h>
// #cgo LDFLAGS: -lwiringPi
import "C"

const (
	// CPU temperature target, degrees C
	defaultTempTarget = 50.
	hysteresis        = float32(1.)

	pwmClockDivisor = 100

	/* Minimum duty cycle is the point below which the fan does
	/* not spin. This depends on both your fan and the switching
	/* transistor used. */
	defaultPwmDutyMin = 1
	pwmDutyMax        = 10

	// how often to update
	delaySeconds = 30

	// GPIO-1/BCM "18"/Pin 12 on a Raspberry PI 3
	defaultPin = 1

	// name of the service
	name        = "fancontrol"
	description = "cooling fan speed control based on CPU temperature"

	// port which daemon should be listen
	port = ":9977"
)

var stdlog, errlog *log.Logger

func fanControl(pwmDutyMin int, pin int, tempTarget float32) {
	cPin := C.int(pin)

	C.wiringPiSetup()

	// Power on "test". Allows the user to verify that their fan is working.
	C.pinMode(cPin, C.OUTPUT)
	C.digitalWrite(cPin, C.HIGH)
	time.Sleep(5 * time.Second)
	C.digitalWrite(cPin, C.LOW)

	C.pwmSetMode(C.PWM_MODE_BAL)
	C.pinMode(cPin, C.PWM_OUTPUT)
	C.pwmSetRange(pwmDutyMax)
	C.pwmSetClock(pwmClockDivisor)
	C.pwmWrite(cPin, C.int(pwmDutyMin))
	temp := float32(0.)
	go cpuTempMonitor(func(cpuTemp float32) {
		if isCPUTempValid(cpuTemp) {
			temp = cpuTemp
		}
	})
	pwmDuty := 0

	tempWhenRampStarted := float32(0.)
	for {
		if temp > (tempTarget + hysteresis) {
			if tempWhenRampStarted < 1. {
				tempWhenRampStarted = temp
			}
			pwmDuty = iMax(iMin(pwmDutyMax, pwmDuty+1), pwmDutyMin)
			if pwmDuty == pwmDutyMax {
				// At the maximum duty cycle currently.
				// Has the temperature increased "substantially" since the ramp-up started?
				if temp > (tempWhenRampStarted + hysteresis) {
					// Give up. The fan does not like the PWM control.
					break
				}
			}
		} else if temp < (tempTarget - hysteresis) {
			pwmDuty = iMax(pwmDuty-1, 0)
			if pwmDuty < pwmDutyMin {
				pwmDuty = 0
				tempWhenRampStarted = 0.
			}
		}
		//log.Println(temp, " ", pwmDuty)
		C.pwmWrite(cPin, C.int(pwmDuty))
		time.Sleep(delaySeconds * time.Second)
	}

	// Default to "ON".
	C.pinMode(cPin, C.OUTPUT)
	C.digitalWrite(cPin, C.HIGH)
}

// Service has embedded daemon
type Service struct {
	daemon.Daemon
}

// Manage by daemon commands or run the daemon
func (service *Service) Manage() (string, error) {

	tempTarget := flag.Float64("temp", defaultTempTarget, "Target CPU Temperature, degrees C")
	pwmDutyMin := flag.Int("minduty", defaultPwmDutyMin, "Minimum PWM duty cycle")
	pin := flag.Int("pin", defaultPin, "PWM pin (wiringPi numbering)")
	flag.Parse()

	usage := "Usage: " + name + " install | remove | start | stop | status"
	// if received any kind of command, do it
	if flag.NArg() > 0 {
		command := os.Args[flag.NFlag()+1]
		switch command {
		case "install":
			return service.Install()
		case "remove":
			return service.Remove()
		case "start":
			return service.Start()
		case "stop":
			return service.Stop()
		case "status":
			return service.Status()
		default:
			return usage, nil
		}
	}

	go fanControl(*pwmDutyMin, *pin, float32(*tempTarget))

	// Set up channel on which to send signal notifications.
	// We must use a buffered channel or risk missing the signal
	// if we're not ready to receive when the signal is sent.
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM)

	// Set up listener for defined host and port
	listener, err := net.Listen("tcp", port)
	if err != nil {
		return "Possibly was a problem with the port binding", err
	}

	// set up channel on which to send accepted connections
	listen := make(chan net.Conn, 100)
	go acceptConnection(listener, listen)

	// loop work cycle with accept connections or interrupt
	// by system signal
	for {
		select {
		case conn := <-listen:
			go handleClient(conn)
		case killSignal := <-interrupt:
			stdlog.Println("Got signal:", killSignal)
			stdlog.Println("Stoping listening on ", listener.Addr())
			listener.Close()
			if killSignal == os.Interrupt {
				return "Daemon was interrupted by system signal", nil
			}
			return "Daemon was killed", nil
		}
	}
}

// Accept a client connection and collect it in a channel
func acceptConnection(listener net.Listener, listen chan<- net.Conn) {
	for {
		conn, err := listener.Accept()
		if err != nil {
			continue
		}
		listen <- conn
	}
}

func handleClient(client net.Conn) {
	for {
		buf := make([]byte, 4096)
		numbytes, err := client.Read(buf)
		if numbytes == 0 || err != nil {
			return
		}
		client.Write(buf[:numbytes])
	}
}

func init() {
	stdlog = log.New(os.Stdout, "", 0)
	errlog = log.New(os.Stderr, "", 0)
}

func main() {
	srv, err := daemon.New(name, description, []string{}...)
	if err != nil {
		errlog.Println("Error: ", err)
		os.Exit(1)
	}
	service := &Service{srv}
	status, err := service.Manage()
	if err != nil {
		errlog.Println(status, "\nError: ", err)
		os.Exit(1)
	}
	fmt.Println(status)
}
<commit_msg>Switch from "BAL" mode to "MS" PWM modes. #599, #595, #593.<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/takama/daemon"
	"log"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
)

// #include <wiringPi.h>
// #cgo LDFLAGS: -lwiringPi
import "C"

const (
	// CPU temperature target, degrees C
	defaultTempTarget = 50.
	hysteresis        = float32(1.)

	pwmClockDivisor = 100

	/* Minimum duty cycle is the point below which the fan does
	/* not spin. This depends on both your fan and the switching
	/* transistor used. */
	defaultPwmDutyMin = 1
	pwmDutyMax        = 10

	// how often to update
	delaySeconds = 30

	// GPIO-1/BCM "18"/Pin 12 on a Raspberry PI 3
	defaultPin = 1

	// name of the service
	name        = "fancontrol"
	description = "cooling fan speed control based on CPU temperature"

	// port which daemon should be listen
	port = ":9977"
)

var stdlog, errlog *log.Logger

func fanControl(pwmDutyMin int, pin int, tempTarget float32) {
	cPin := C.int(pin)

	C.wiringPiSetup()

	// Power on "test". Allows the user to verify that their fan is working.
	C.pinMode(cPin, C.OUTPUT)
	C.digitalWrite(cPin, C.HIGH)
	time.Sleep(5 * time.Second)
	C.digitalWrite(cPin, C.LOW)

	C.pwmSetMode(C.PWM_MODE_MS)
	C.pinMode(cPin, C.PWM_OUTPUT)
	C.pwmSetRange(pwmDutyMax)
	C.pwmSetClock(pwmClockDivisor)
	C.pwmWrite(cPin, C.int(pwmDutyMin))
	temp := float32(0.)
	go cpuTempMonitor(func(cpuTemp float32) {
		if isCPUTempValid(cpuTemp) {
			temp = cpuTemp
		}
	})
	pwmDuty := 0

	tempWhenRampStarted := float32(0.)
	for {
		if temp > (tempTarget + hysteresis) {
			if tempWhenRampStarted < 1. {
				tempWhenRampStarted = temp
			}
			pwmDuty = iMax(iMin(pwmDutyMax, pwmDuty+1), pwmDutyMin)
			if pwmDuty == pwmDutyMax {
				// At the maximum duty cycle currently.
				// Has the temperature increased "substantially" since the ramp-up started?
				if temp > (tempWhenRampStarted + hysteresis) {
					// Give up. The fan does not like the PWM control.
					break
				}
			}
		} else if temp < (tempTarget - hysteresis) {
			pwmDuty = iMax(pwmDuty-1, 0)
			if pwmDuty < pwmDutyMin {
				pwmDuty = 0
				tempWhenRampStarted = 0.
			}
		}
		//log.Println(temp, " ", pwmDuty)
		C.pwmWrite(cPin, C.int(pwmDuty))
		time.Sleep(delaySeconds * time.Second)
	}

	// Default to "ON".
	C.pinMode(cPin, C.OUTPUT)
	C.digitalWrite(cPin, C.HIGH)
}

// Service has embedded daemon
type Service struct {
	daemon.Daemon
}

// Manage by daemon commands or run the daemon
func (service *Service) Manage() (string, error) {

	tempTarget := flag.Float64("temp", defaultTempTarget, "Target CPU Temperature, degrees C")
	pwmDutyMin := flag.Int("minduty", defaultPwmDutyMin, "Minimum PWM duty cycle")
	pin := flag.Int("pin", defaultPin, "PWM pin (wiringPi numbering)")
	flag.Parse()

	usage := "Usage: " + name + " install | remove | start | stop | status"
	// if received any kind of command, do it
	if flag.NArg() > 0 {
		command := os.Args[flag.NFlag()+1]
		switch command {
		case "install":
			return service.Install()
		case "remove":
			return service.Remove()
		case "start":
			return service.Start()
		case "stop":
			return service.Stop()
		case "status":
			return service.Status()
		default:
			return usage, nil
		}
	}

	go fanControl(*pwmDutyMin, *pin, float32(*tempTarget))

	// Set up channel on which to send signal notifications.
	// We must use a buffered channel or risk missing the signal
	// if we're not ready to receive when the signal is sent.
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM)

	// Set up listener for defined host and port
	listener, err := net.Listen("tcp", port)
	if err != nil {
		return "Possibly was a problem with the port binding", err
	}

	// set up channel on which to send accepted connections
	listen := make(chan net.Conn, 100)
	go acceptConnection(listener, listen)

	// loop work cycle with accept connections or interrupt
	// by system signal
	for {
		select {
		case conn := <-listen:
			go handleClient(conn)
		case killSignal := <-interrupt:
			stdlog.Println("Got signal:", killSignal)
			stdlog.Println("Stoping listening on ", listener.Addr())
			listener.Close()
			if killSignal == os.Interrupt {
				return "Daemon was interrupted by system signal", nil
			}
			return "Daemon was killed", nil
		}
	}
}

// Accept a client connection and collect it in a channel
func acceptConnection(listener net.Listener, listen chan<- net.Conn) {
	for {
		conn, err := listener.Accept()
		if err != nil {
			continue
		}
		listen <- conn
	}
}

func handleClient(client net.Conn) {
	for {
		buf := make([]byte, 4096)
		numbytes, err := client.Read(buf)
		if numbytes == 0 || err != nil {
			return
		}
		client.Write(buf[:numbytes])
	}
}

func init() {
	stdlog = log.New(os.Stdout, "", 0)
	errlog = log.New(os.Stderr, "", 0)
}

func main() {
	srv, err := daemon.New(name, description, []string{}...)
	if err != nil {
		errlog.Println("Error: ", err)
		os.Exit(1)
	}
	service := &Service{srv}
	status, err := service.Manage()
	if err != nil {
		errlog.Println(status, "\nError: ", err)
		os.Exit(1)
	}
	fmt.Println(status)
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/backup"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsBackupVault_basic(t *testing.T) {
	var vault backup.DescribeBackupVaultOutput

	rInt := acctest.RandInt()
	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsBackupVaultDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBackupVaultConfig(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
				),
			},
		},
	})
}

func TestAccAwsBackupVault_withKmsKey(t *testing.T) {
	var vault backup.DescribeBackupVaultOutput

	rInt := acctest.RandInt()
	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsBackupVaultDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBackupVaultWithKmsKey(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
					resource.TestCheckResourceAttrPair("aws_backup_vault.test", "kms_key_arn", "aws_kms_key.test", "arn"),
				),
			},
		},
	})
}

func TestAccAwsBackupVault_withTags(t *testing.T) {
	var vault backup.DescribeBackupVaultOutput

	rInt := acctest.RandInt()
	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsBackupVaultDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBackupVaultWithTags(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.up", "down"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.left", "right"),
				),
			},
			{
				Config: testAccBackupVaultWithUpdateTags(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.%", "4"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.up", "downdown"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.left", "rightright"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.foo", "bar"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.fizz", "buzz"),
				),
			},
			{
				Config: testAccBackupVaultWithRemoveTags(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists("aws_backup_vault.test", &vault),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.%", "2"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.foo", "bar"),
					resource.TestCheckResourceAttr("aws_backup_vault.test", "tags.fizz", "buzz"),
				),
			},
		},
	})
}

func testAccCheckAwsBackupVaultDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).backupconn
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_backup_vault" {
			continue
		}

		input := &backup.DescribeBackupVaultInput{
			BackupVaultName: aws.String(rs.Primary.ID),
		}

		resp, err := conn.DescribeBackupVault(input)

		if err == nil {
			if *resp.BackupVaultName == rs.Primary.ID {
				return fmt.Errorf("Vault '%s' was not deleted properly", rs.Primary.ID)
			}
		}
	}

	return nil
}

func testAccCheckAwsBackupVaultExists(name string, vault *backup.DescribeBackupVaultOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		conn := testAccProvider.Meta().(*AWSClient).backupconn
		params := &backup.DescribeBackupVaultInput{
			BackupVaultName: aws.String(rs.Primary.ID),
		}
		resp, err := conn.DescribeBackupVault(params)
		if err != nil {
			return err
		}

		*vault = *resp

		return nil
	}
}

func testAccPreCheckAWSBackup(t *testing.T) {
	conn := testAccProvider.Meta().(*AWSClient).backupconn

	input := &backup.ListBackupVaultsInput{}

	_, err := conn.ListBackupVaults(input)

	if testAccPreCheckSkipError(err) {
		t.Skipf("skipping acceptance testing: %s", err)
	}

	if err != nil {
		t.Fatalf("unexpected PreCheck error: %s", err)
	}
}

func testAccBackupVaultConfig(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"
}
`, randInt)
}

func testAccBackupVaultWithKmsKey(randInt int) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "test" {
  description             = "Test KMS Key for AWS Backup Vault"
  deletion_window_in_days = 10
}

resource "aws_backup_vault" "test" {
  name        = "tf_acc_test_backup_vault_%d"
  kms_key_arn = "${aws_kms_key.test.arn}"
}
`, randInt)
}

func testAccBackupVaultWithTags(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"

  tags = {
    up   = "down"
    left = "right"
  }
}
`, randInt)
}

func testAccBackupVaultWithUpdateTags(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"

  tags = {
    up   = "downdown"
    left = "rightright"
    foo  = "bar"
    fizz = "buzz"
  }
}
`, randInt)
}

func testAccBackupVaultWithRemoveTags(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"

  tags = {
    foo  = "bar"
    fizz = "buzz"
  }
}
`, randInt)
}
<commit_msg>Add acceptance tests for import of resource backup_vault<commit_after>package aws

import (
	"fmt"
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/backup"
	"github.com/hashicorp/terraform/helper/acctest"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
)

func TestAccAwsBackupVault_basic(t *testing.T) {
	var vault backup.DescribeBackupVaultOutput

	rInt := acctest.RandInt()
	resourceName := "aws_backup_vault.test"
	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsBackupVaultDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBackupVaultConfig(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists(resourceName, &vault),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAwsBackupVault_withKmsKey(t *testing.T) {
	var vault backup.DescribeBackupVaultOutput

	rInt := acctest.RandInt()
	resourceName := "aws_backup_vault.test"
	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsBackupVaultDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBackupVaultWithKmsKey(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists(resourceName, &vault),
					resource.TestCheckResourceAttrPair(resourceName, "kms_key_arn", "aws_kms_key.test", "arn"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
		},
	})
}

func TestAccAwsBackupVault_withTags(t *testing.T) {
	var vault backup.DescribeBackupVaultOutput

	rInt := acctest.RandInt()
	resourceName := "aws_backup_vault.test"
	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t); testAccPreCheckAWSBackup(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAwsBackupVaultDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccBackupVaultWithTags(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists(resourceName, &vault),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.up", "down"),
					resource.TestCheckResourceAttr(resourceName, "tags.left", "right"),
				),
			},
			{
				ResourceName:      resourceName,
				ImportState:       true,
				ImportStateVerify: true,
			},
			{
				Config: testAccBackupVaultWithUpdateTags(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists(resourceName, &vault),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "4"),
					resource.TestCheckResourceAttr(resourceName, "tags.up", "downdown"),
					resource.TestCheckResourceAttr(resourceName, "tags.left", "rightright"),
					resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar"),
					resource.TestCheckResourceAttr(resourceName, "tags.fizz", "buzz"),
				),
			},
			{
				Config: testAccBackupVaultWithRemoveTags(rInt),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAwsBackupVaultExists(resourceName, &vault),
					resource.TestCheckResourceAttr(resourceName, "tags.%", "2"),
					resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar"),
					resource.TestCheckResourceAttr(resourceName, "tags.fizz", "buzz"),
				),
			},
		},
	})
}

func testAccCheckAwsBackupVaultDestroy(s *terraform.State) error {
	conn := testAccProvider.Meta().(*AWSClient).backupconn
	for _, rs := range s.RootModule().Resources {
		if rs.Type != "aws_backup_vault" {
			continue
		}

		input := &backup.DescribeBackupVaultInput{
			BackupVaultName: aws.String(rs.Primary.ID),
		}

		resp, err := conn.DescribeBackupVault(input)

		if err == nil {
			if *resp.BackupVaultName == rs.Primary.ID {
				return fmt.Errorf("Vault '%s' was not deleted properly", rs.Primary.ID)
			}
		}
	}

	return nil
}

func testAccCheckAwsBackupVaultExists(name string, vault *backup.DescribeBackupVaultOutput) resource.TestCheckFunc {
	return func(s *terraform.State) error {
		rs, ok := s.RootModule().Resources[name]
		if !ok {
			return fmt.Errorf("Not found: %s", name)
		}

		conn := testAccProvider.Meta().(*AWSClient).backupconn
		params := &backup.DescribeBackupVaultInput{
			BackupVaultName: aws.String(rs.Primary.ID),
		}
		resp, err := conn.DescribeBackupVault(params)
		if err != nil {
			return err
		}

		*vault = *resp

		return nil
	}
}

func testAccPreCheckAWSBackup(t *testing.T) {
	conn := testAccProvider.Meta().(*AWSClient).backupconn

	input := &backup.ListBackupVaultsInput{}

	_, err := conn.ListBackupVaults(input)

	if testAccPreCheckSkipError(err) {
		t.Skipf("skipping acceptance testing: %s", err)
	}

	if err != nil {
		t.Fatalf("unexpected PreCheck error: %s", err)
	}
}

func testAccBackupVaultConfig(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"
}
`, randInt)
}

func testAccBackupVaultWithKmsKey(randInt int) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "test" {
  description             = "Test KMS Key for AWS Backup Vault"
  deletion_window_in_days = 10
}

resource "aws_backup_vault" "test" {
  name        = "tf_acc_test_backup_vault_%d"
  kms_key_arn = "${aws_kms_key.test.arn}"
}
`, randInt)
}

func testAccBackupVaultWithTags(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"

  tags = {
    up   = "down"
    left = "right"
  }
}
`, randInt)
}

func testAccBackupVaultWithUpdateTags(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"

  tags = {
    up   = "downdown"
    left = "rightright"
    foo  = "bar"
    fizz = "buzz"
  }
}
`, randInt)
}

func testAccBackupVaultWithRemoveTags(randInt int) string {
	return fmt.Sprintf(`
resource "aws_backup_vault" "test" {
  name = "tf_acc_test_backup_vault_%d"

  tags = {
    foo  = "bar"
    fizz = "buzz"
  }
}
`, randInt)
}
<|endoftext|>


<commit_before>package libpdb

import (
	"github.com/ryscheng/pdb/common"
	"github.com/ryscheng/pdb/drbg"
	"log"
	"os"
	"sync/atomic"
	"time"
)

//const defaultReadInterval = int64(time.Second)
//const defaultWriteInterval = int64(time.Second)

type RequestManager struct {
	log       *log.Logger
	serverRef *common.TrustDomainRef
	// Protected by `atomic`
	globalConfig *atomic.Value //*common.GlobalConfig
	dead         int32
}

func NewRequestManager(name string, serverRef *common.TrustDomainRef, globalConfig *atomic.Value) *RequestManager {
	rm := &RequestManager{}
	rm.log = log.New(os.Stdout, "[RequestManager:"+name+"] ", log.Ldate|log.Ltime|log.Lshortfile)
	rm.serverRef = serverRef
	rm.globalConfig = globalConfig
	rm.dead = 0

	rm.log.Printf("NewRequestManager \n")
	//go rm.readPeriodic()
	go rm.writePeriodic()
	return rm
}

/** PUBLIC METHODS (threadsafe) **/

func (rm *RequestManager) Kill() {
	atomic.StoreInt32(&rm.dead, 1)
}

/** PRIVATE METHODS **/
func (rm *RequestManager) isDead() bool {
	return atomic.LoadInt32(&rm.dead) != 0
}

func (rm *RequestManager) writePeriodic() {
	seed, _ := drbg.NewSeed()
	rand := drbg.NewHashDrbg(seed)
	for rm.isDead() == false {
		// Load latest config
		globalConfig := rm.globalConfig.Load().(common.GlobalConfig)
		args := &common.WriteArgs{}
		rm.generateRandomWrite(globalConfig, rand, args)
		rm.log.Printf("writePeriodic: Dummy request to %v, %v \n", args.Bucket1, args.Bucket2)
		time.Sleep(globalConfig.WriteInterval)
		//time.Sleep(time.Duration(atomic.LoadInt64(&rm.writeInterval)))
	}
}

func (rm *RequestManager) readPeriodic() {
	seed, _ := drbg.NewSeed()
	rand := drbg.NewHashDrbg(seed)
	for rm.isDead() == false {
		rm.log.Println("readPeriodic: ")
		globalConfig := rm.globalConfig.Load().(common.GlobalConfig)
		args := &common.ReadArgs{}
		rm.generateRandomRead(globalConfig, rand, args)
		rm.log.Printf("readPeriodic: Dummy request \n")
		time.Sleep(globalConfig.ReadInterval)
		//time.Sleep(time.Duration(atomic.LoadInt64(&rm.readInterval)))
	}
}

func (rm *RequestManager) generateRandomWrite(globalConfig common.GlobalConfig, rand *drbg.HashDrbg, args *common.WriteArgs) {
	args.Bucket1 = rand.RandomUint32() % globalConfig.NumBuckets
	args.Bucket2 = rand.RandomUint32() % globalConfig.NumBuckets
	args.Data = make([]byte, globalConfig.DataSize, globalConfig.DataSize)
	rand.FillBytes(&args.Data)
}

func (rm *RequestManager) generateRandomRead(globalConfig common.GlobalConfig, rand *drbg.HashDrbg, args *common.ReadArgs) {
	numBytes := (globalConfig.NumBuckets / uint32(8))
	lastNumBits := (globalConfig.NumBuckets % uint32(8))
	if lastNumBits > 0 {
		numBytes = numBytes + 1
	}
	args.RequestVector = make([]byte, numBytes, numBytes)
	rand.FillBytes(&args.RequestVector)
	//@todo Trim last byte to expected number of bits

}
<commit_msg>read and write queues<commit_after>package libpdb

import (
	"github.com/ryscheng/pdb/common"
	"github.com/ryscheng/pdb/drbg"
	"log"
	"os"
	"sync/atomic"
	"time"
)

//const defaultReadInterval = int64(time.Second)
//const defaultWriteInterval = int64(time.Second)

type RequestManager struct {
	log       *log.Logger
	serverRef *common.TrustDomainRef
	// Protected by `atomic`
	globalConfig *atomic.Value //*common.GlobalConfig
	dead         int32
	// Channels
	writeChan  chan *common.WriteArgs
	writeQueue []*common.WriteArgs
	readChan   chan *common.ReadArgs
	readQueue  []*common.ReadArgs
}

func NewRequestManager(name string, serverRef *common.TrustDomainRef, globalConfig *atomic.Value) *RequestManager {
	rm := &RequestManager{}
	rm.log = log.New(os.Stdout, "[RequestManager:"+name+"] ", log.Ldate|log.Ltime|log.Lshortfile)
	rm.serverRef = serverRef
	rm.globalConfig = globalConfig
	rm.dead = 0

	rm.log.Printf("NewRequestManager \n")
	//go rm.readPeriodic()
	go rm.writePeriodic()
	return rm
}

/** PUBLIC METHODS (threadsafe) **/

func (rm *RequestManager) Kill() {
	atomic.StoreInt32(&rm.dead, 1)
}

func (rm *RequestManager) EnqueueWrite(args *common.WriteArgs) {
	rm.writeChan <- args
}

func (rm *RequestManager) EnqueueRead(args *common.ReadArgs) {
	rm.readChan <- args
}

/** PRIVATE METHODS **/
func (rm *RequestManager) isDead() bool {
	return atomic.LoadInt32(&rm.dead) != 0
}

func (rm *RequestManager) writePeriodic() {
	seed, _ := drbg.NewSeed()
	rand := drbg.NewHashDrbg(seed)
	for rm.isDead() == false {
		select {
		case msg := <-rm.writeChan:
			rm.writeQueue = append(rm.writeQueue, msg)
		default:
			globalConfig := rm.globalConfig.Load().(common.GlobalConfig)
			var args *common.WriteArgs
			if len(rm.writeQueue) > 0 {
				args = rm.writeQueue[0]
				rm.writeQueue = rm.writeQueue[1:]
			} else {
				args = &common.WriteArgs{}
				rm.generateRandomWrite(globalConfig, rand, args)
				rm.log.Printf("writePeriodic: Dummy request to %v, %v \n", args.Bucket1, args.Bucket2)
			}
			//@todo Send request
			time.Sleep(globalConfig.WriteInterval)
			//time.Sleep(time.Duration(atomic.LoadInt64(&rm.writeInterval)))
		}
	}
}

func (rm *RequestManager) readPeriodic() {
	seed, _ := drbg.NewSeed()
	rand := drbg.NewHashDrbg(seed)
	for rm.isDead() == false {
		select {
		case msg := <-rm.readChan:
			rm.readQueue = append(rm.readQueue, msg)
		default:
			globalConfig := rm.globalConfig.Load().(common.GlobalConfig)
			var args *common.ReadArgs
			if len(rm.readQueue) > 0 {
				args = rm.readQueue[0]
				rm.readQueue = rm.readQueue[1:]
			} else {
				args = &common.ReadArgs{}
				rm.generateRandomRead(globalConfig, rand, args)
				rm.log.Printf("readPeriodic: Dummy request \n")
			}
			//@todo Send request
			time.Sleep(globalConfig.ReadInterval)
			//time.Sleep(time.Duration(atomic.LoadInt64(&rm.readInterval)))
		}
	}
}

func (rm *RequestManager) generateRandomWrite(globalConfig common.GlobalConfig, rand *drbg.HashDrbg, args *common.WriteArgs) {
	args.Bucket1 = rand.RandomUint32() % globalConfig.NumBuckets
	args.Bucket2 = rand.RandomUint32() % globalConfig.NumBuckets
	args.Data = make([]byte, globalConfig.DataSize, globalConfig.DataSize)
	rand.FillBytes(&args.Data)
}

func (rm *RequestManager) generateRandomRead(globalConfig common.GlobalConfig, rand *drbg.HashDrbg, args *common.ReadArgs) {
	numBytes := (globalConfig.NumBuckets / uint32(8))
	lastNumBits := (globalConfig.NumBuckets % uint32(8))
	if lastNumBits > 0 {
		numBytes = numBytes + 1
	}
	args.RequestVector = make([]byte, numBytes, numBytes)
	rand.FillBytes(&args.RequestVector)
	//@todo Trim last byte to expected number of bits

}
<|endoftext|>