<commit_before>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	events "github.com/aws/aws-sdk-go/service/cloudwatchevents"
	"github.com/hashicorp/errwrap"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/structure"
)

func resourceAwsCloudWatchEventRule() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCloudWatchEventRuleCreate,
		Read:   resourceAwsCloudWatchEventRuleRead,
		Update: resourceAwsCloudWatchEventRuleUpdate,
		Delete: resourceAwsCloudWatchEventRuleDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
				ValidateFunc:  validateCloudWatchEventRuleName,
			},
			"name_prefix": {
				Type:         schema.TypeString,
				Optional:     true,
				ForceNew:     true,
				ValidateFunc: validateCloudWatchEventRuleName,
			},
			"schedule_expression": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateMaxLength(256),
			},
			"event_pattern": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateEventPatternValue(2048),
				StateFunc: func(v interface{}) string {
					json, _ := structure.NormalizeJsonString(v.(string))
					return json
				},
			},
			"description": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateMaxLength(512),
			},
			"role_arn": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateMaxLength(1600),
			},
			"is_enabled": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

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

	input, err := buildPutRuleInputStruct(d)
	if err != nil {
		return errwrap.Wrapf("Creating CloudWatch Event Rule failed: {{err}}", err)
	}
	log.Printf("[DEBUG] Creating CloudWatch Event Rule: %s", input)

	// IAM Roles take some time to propagate
	var out *events.PutRuleOutput
	err = resource.Retry(30*time.Second, func() *resource.RetryError {
		var err error
		out, err = conn.PutRule(input)
		pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$")
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) {
					log.Printf("[DEBUG] Retrying creation of CloudWatch Event Rule %q", *input.Name)
					return resource.RetryableError(err)
				}
			}
			return resource.NonRetryableError(err)
		}
		return nil
	})
	if err != nil {
		return errwrap.Wrapf("Creating CloudWatch Event Rule failed: {{err}}", err)
	}

	d.Set("arn", out.RuleArn)
	d.SetId(*input.Name)

	log.Printf("[INFO] CloudWatch Event Rule %q created", *out.RuleArn)

	return resourceAwsCloudWatchEventRuleUpdate(d, meta)
}

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

	input := events.DescribeRuleInput{
		Name: aws.String(d.Id()),
	}
	log.Printf("[DEBUG] Reading CloudWatch Event Rule: %s", input)
	out, err := conn.DescribeRule(&input)
	if awsErr, ok := err.(awserr.Error); ok {
		if awsErr.Code() == "ResourceNotFoundException" {
			log.Printf("[WARN] Removing CloudWatch Event Rule %q because it's gone.", d.Id())
			d.SetId("")
			return nil
		}
	}
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] Found Event Rule: %s", out)

	d.Set("arn", out.Arn)
	d.Set("description", out.Description)
	if out.EventPattern != nil {
		pattern, err := structure.NormalizeJsonString(*out.EventPattern)
		if err != nil {
			return errwrap.Wrapf("event pattern contains an invalid JSON: {{err}}", err)
		}
		d.Set("event_pattern", pattern)
	}
	d.Set("name", out.Name)
	d.Set("role_arn", out.RoleArn)
	d.Set("schedule_expression", out.ScheduleExpression)

	boolState, err := getBooleanStateFromString(*out.State)
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] Setting boolean state: %t", boolState)
	d.Set("is_enabled", boolState)

	return nil
}

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

	if d.HasChange("is_enabled") && d.Get("is_enabled").(bool) {
		log.Printf("[DEBUG] Enabling CloudWatch Event Rule %q", d.Id())
		_, err := conn.EnableRule(&events.EnableRuleInput{
			Name: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		log.Printf("[DEBUG] CloudWatch Event Rule (%q) enabled", d.Id())
	}

	input, err := buildPutRuleInputStruct(d)
	if err != nil {
		return errwrap.Wrapf("Updating CloudWatch Event Rule failed: {{err}}", err)
	}
	log.Printf("[DEBUG] Updating CloudWatch Event Rule: %s", input)

	// IAM Roles take some time to propagate
	err = resource.Retry(30*time.Second, func() *resource.RetryError {
		_, err := conn.PutRule(input)
		pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$")
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) {
					log.Printf("[DEBUG] Retrying update of CloudWatch Event Rule %q", *input.Name)
					return resource.RetryableError(err)
				}
			}
			return resource.NonRetryableError(err)
		}
		return nil
	})
	if err != nil {
		return errwrap.Wrapf("Updating CloudWatch Event Rule failed: {{err}}", err)
	}

	if d.HasChange("is_enabled") && !d.Get("is_enabled").(bool) {
		log.Printf("[DEBUG] Disabling CloudWatch Event Rule %q", d.Id())
		_, err := conn.DisableRule(&events.DisableRuleInput{
			Name: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		log.Printf("[DEBUG] CloudWatch Event Rule (%q) disabled", d.Id())
	}

	return resourceAwsCloudWatchEventRuleRead(d, meta)
}

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

	log.Printf("[INFO] Deleting CloudWatch Event Rule: %s", d.Id())
	_, err := conn.DeleteRule(&events.DeleteRuleInput{
		Name: aws.String(d.Id()),
	})
	if err != nil {
		return fmt.Errorf("Error deleting CloudWatch Event Rule: %s", err)
	}
	log.Println("[INFO] CloudWatch Event Rule deleted")

	return nil
}

func buildPutRuleInputStruct(d *schema.ResourceData) (*events.PutRuleInput, error) {
	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	input := events.PutRuleInput{
		Name: aws.String(name),
	}
	if v, ok := d.GetOk("description"); ok {
		input.Description = aws.String(v.(string))
	}
	if v, ok := d.GetOk("event_pattern"); ok {
		pattern, err := structure.NormalizeJsonString(v)
		if err != nil {
			return nil, errwrap.Wrapf("event pattern contains an invalid JSON: {{err}}", err)
		}
		input.EventPattern = aws.String(pattern)
	}
	if v, ok := d.GetOk("role_arn"); ok {
		input.RoleArn = aws.String(v.(string))
	}
	if v, ok := d.GetOk("schedule_expression"); ok {
		input.ScheduleExpression = aws.String(v.(string))
	}

	input.State = aws.String(getStringStateFromBoolean(d.Get("is_enabled").(bool)))

	return &input, nil
}

// State is represented as (ENABLED|DISABLED) in the API
func getBooleanStateFromString(state string) (bool, error) {
	if state == "ENABLED" {
		return true, nil
	} else if state == "DISABLED" {
		return false, nil
	}
	// We don't just blindly trust AWS as they tend to return
	// unexpected values in similar cases (different casing etc.)
	return false, fmt.Errorf("Failed converting state %q into boolean", state)
}

// State is represented as (ENABLED|DISABLED) in the API
func getStringStateFromBoolean(isEnabled bool) string {
	if isEnabled {
		return "ENABLED"
	}
	return "DISABLED"
}

func validateEventPatternValue(length int) schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		json, err := structure.NormalizeJsonString(v)
		if err != nil {
			errors = append(errors, fmt.Errorf("%q contains an invalid JSON: %s", k, err))

			// Invalid JSON? Return immediately,
			// there is no need to collect other
			// errors.
			return
		}

		// Check whether the normalized JSON is within the given length.
		if len(json) > length {
			errors = append(errors, fmt.Errorf(
				"%q cannot be longer than %d characters: %q", k, length, json))
		}
		return
	}
}
<commit_msg>resource/aws_cloudwatch_event_rule: Prevent multiple names on creation<commit_after>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	events "github.com/aws/aws-sdk-go/service/cloudwatchevents"
	"github.com/hashicorp/errwrap"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/structure"
)

func resourceAwsCloudWatchEventRule() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCloudWatchEventRuleCreate,
		Read:   resourceAwsCloudWatchEventRuleRead,
		Update: resourceAwsCloudWatchEventRuleUpdate,
		Delete: resourceAwsCloudWatchEventRuleDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
				ValidateFunc:  validateCloudWatchEventRuleName,
			},
			"name_prefix": {
				Type:         schema.TypeString,
				Optional:     true,
				ForceNew:     true,
				ValidateFunc: validateCloudWatchEventRuleName,
			},
			"schedule_expression": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateMaxLength(256),
			},
			"event_pattern": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateEventPatternValue(2048),
				StateFunc: func(v interface{}) string {
					json, _ := structure.NormalizeJsonString(v.(string))
					return json
				},
			},
			"description": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateMaxLength(512),
			},
			"role_arn": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateMaxLength(1600),
			},
			"is_enabled": {
				Type:     schema.TypeBool,
				Optional: true,
				Default:  true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

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

	var name string
	if v, ok := d.GetOk("name"); ok {
		name = v.(string)
	} else if v, ok := d.GetOk("name_prefix"); ok {
		name = resource.PrefixedUniqueId(v.(string))
	} else {
		name = resource.UniqueId()
	}

	input, err := buildPutRuleInputStruct(d, name)
	if err != nil {
		return errwrap.Wrapf("Creating CloudWatch Event Rule failed: {{err}}", err)
	}
	log.Printf("[DEBUG] Creating CloudWatch Event Rule: %s", input)

	// IAM Roles take some time to propagate
	var out *events.PutRuleOutput
	err = resource.Retry(30*time.Second, func() *resource.RetryError {
		var err error
		out, err = conn.PutRule(input)
		pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$")
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) {
					log.Printf("[DEBUG] Retrying creation of CloudWatch Event Rule %q", *input.Name)
					return resource.RetryableError(err)
				}
			}
			return resource.NonRetryableError(err)
		}
		return nil
	})
	if err != nil {
		return errwrap.Wrapf("Creating CloudWatch Event Rule failed: {{err}}", err)
	}

	d.Set("arn", out.RuleArn)
	d.SetId(*input.Name)

	log.Printf("[INFO] CloudWatch Event Rule %q created", *out.RuleArn)

	return resourceAwsCloudWatchEventRuleUpdate(d, meta)
}

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

	input := events.DescribeRuleInput{
		Name: aws.String(d.Id()),
	}
	log.Printf("[DEBUG] Reading CloudWatch Event Rule: %s", input)
	out, err := conn.DescribeRule(&input)
	if awsErr, ok := err.(awserr.Error); ok {
		if awsErr.Code() == "ResourceNotFoundException" {
			log.Printf("[WARN] Removing CloudWatch Event Rule %q because it's gone.", d.Id())
			d.SetId("")
			return nil
		}
	}
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] Found Event Rule: %s", out)

	d.Set("arn", out.Arn)
	d.Set("description", out.Description)
	if out.EventPattern != nil {
		pattern, err := structure.NormalizeJsonString(*out.EventPattern)
		if err != nil {
			return errwrap.Wrapf("event pattern contains an invalid JSON: {{err}}", err)
		}
		d.Set("event_pattern", pattern)
	}
	d.Set("name", out.Name)
	d.Set("role_arn", out.RoleArn)
	d.Set("schedule_expression", out.ScheduleExpression)

	boolState, err := getBooleanStateFromString(*out.State)
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] Setting boolean state: %t", boolState)
	d.Set("is_enabled", boolState)

	return nil
}

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

	if d.HasChange("is_enabled") && d.Get("is_enabled").(bool) {
		log.Printf("[DEBUG] Enabling CloudWatch Event Rule %q", d.Id())
		_, err := conn.EnableRule(&events.EnableRuleInput{
			Name: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		log.Printf("[DEBUG] CloudWatch Event Rule (%q) enabled", d.Id())
	}

	input, err := buildPutRuleInputStruct(d, d.Id())
	if err != nil {
		return errwrap.Wrapf("Updating CloudWatch Event Rule failed: {{err}}", err)
	}
	log.Printf("[DEBUG] Updating CloudWatch Event Rule: %s", input)

	// IAM Roles take some time to propagate
	err = resource.Retry(30*time.Second, func() *resource.RetryError {
		_, err := conn.PutRule(input)
		pattern := regexp.MustCompile("cannot be assumed by principal '[a-z]+\\.amazonaws\\.com'\\.$")
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok {
				if awsErr.Code() == "ValidationException" && pattern.MatchString(awsErr.Message()) {
					log.Printf("[DEBUG] Retrying update of CloudWatch Event Rule %q", *input.Name)
					return resource.RetryableError(err)
				}
			}
			return resource.NonRetryableError(err)
		}
		return nil
	})
	if err != nil {
		return errwrap.Wrapf("Updating CloudWatch Event Rule failed: {{err}}", err)
	}

	if d.HasChange("is_enabled") && !d.Get("is_enabled").(bool) {
		log.Printf("[DEBUG] Disabling CloudWatch Event Rule %q", d.Id())
		_, err := conn.DisableRule(&events.DisableRuleInput{
			Name: aws.String(d.Id()),
		})
		if err != nil {
			return err
		}
		log.Printf("[DEBUG] CloudWatch Event Rule (%q) disabled", d.Id())
	}

	return resourceAwsCloudWatchEventRuleRead(d, meta)
}

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

	log.Printf("[INFO] Deleting CloudWatch Event Rule: %s", d.Id())
	_, err := conn.DeleteRule(&events.DeleteRuleInput{
		Name: aws.String(d.Id()),
	})
	if err != nil {
		return fmt.Errorf("Error deleting CloudWatch Event Rule: %s", err)
	}
	log.Println("[INFO] CloudWatch Event Rule deleted")

	return nil
}

func buildPutRuleInputStruct(d *schema.ResourceData, name string) (*events.PutRuleInput, error) {
	input := events.PutRuleInput{
		Name: aws.String(name),
	}
	if v, ok := d.GetOk("description"); ok {
		input.Description = aws.String(v.(string))
	}
	if v, ok := d.GetOk("event_pattern"); ok {
		pattern, err := structure.NormalizeJsonString(v)
		if err != nil {
			return nil, errwrap.Wrapf("event pattern contains an invalid JSON: {{err}}", err)
		}
		input.EventPattern = aws.String(pattern)
	}
	if v, ok := d.GetOk("role_arn"); ok {
		input.RoleArn = aws.String(v.(string))
	}
	if v, ok := d.GetOk("schedule_expression"); ok {
		input.ScheduleExpression = aws.String(v.(string))
	}

	input.State = aws.String(getStringStateFromBoolean(d.Get("is_enabled").(bool)))

	return &input, nil
}

// State is represented as (ENABLED|DISABLED) in the API
func getBooleanStateFromString(state string) (bool, error) {
	if state == "ENABLED" {
		return true, nil
	} else if state == "DISABLED" {
		return false, nil
	}
	// We don't just blindly trust AWS as they tend to return
	// unexpected values in similar cases (different casing etc.)
	return false, fmt.Errorf("Failed converting state %q into boolean", state)
}

// State is represented as (ENABLED|DISABLED) in the API
func getStringStateFromBoolean(isEnabled bool) string {
	if isEnabled {
		return "ENABLED"
	}
	return "DISABLED"
}

func validateEventPatternValue(length int) schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		json, err := structure.NormalizeJsonString(v)
		if err != nil {
			errors = append(errors, fmt.Errorf("%q contains an invalid JSON: %s", k, err))

			// Invalid JSON? Return immediately,
			// there is no need to collect other
			// errors.
			return
		}

		// Check whether the normalized JSON is within the given length.
		if len(json) > length {
			errors = append(errors, fmt.Errorf(
				"%q cannot be longer than %d characters: %q", k, length, json))
		}
		return
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"time"
)

func main() {
	keyword, count := args()
	urls := fetchUrls(keyword, count)
	html := generateHtml(urls)
	openHtml(html)
}

func args() (keyword string, count int) {
	flag.StringVar(&keyword, "k", "yuyushiki", "keyword")
	flag.IntVar(&count, "c", 8, "count")
	flag.Parse()

	return keyword, count
}

func fetchUrls(keyword string, count int) (urls []string) {
	page := 1
	var _urls []string
	for len(urls) <= count {
		_urls = search(page, keyword)
		for _, url := range _urls {
			urls = append(urls, url)
		}
		page += 1
	}

	return urls
}

func generateHtml(urls []string) (html string) {
	html = "<!DOCTYPE HTML>"
	for _, url := range urls {
		html = html + ""
	}
	html = html + ""
	return html
}

func openHtml(html string) {
	file, err := ioutil.TempFile(os.TempDir(), "animegif")
	perror(err)
	ioutil.WriteFile(file.Name(), []byte(html), 0644)
	exec.Command("open", file.Name()).Start()
	time.Sleep(time.Second * 1)

	defer os.Remove(file.Name())
}

func perror(err error) {
	if err != nil {
		panic(err)
	}
}

type ResultType struct {
	Url string `json:"url"`
}

type ResponseDataType struct {
	Results []ResultType `json:"results"`
}

type ResponseType struct {
	ResponseData ResponseDataType `json:"responseData"`
}

func search(page int, keyword string) (urls []string) {
	perPage := 8
	base := "http://ajax.googleapis.com/ajax/services/search/images?"
	start := (page-1)*perPage + 1

	params := url.Values{}
	params.Add("q", keyword)
	params.Add("rsz", fmt.Sprint(perPage))
	params.Add("safe", "off")
	params.Add("v", "1.0")
	params.Add("as_filetype", "gif")
	params.Add("imgsz", "large")
	params.Add("start", fmt.Sprint(start))
	params.Add("as_sitesearch", "tumblr.com")

	body := openUrl(base + params.Encode())

	var response ResponseType
	err := json.Unmarshal(body, &response)
	perror(err)
	for _, value := range response.ResponseData.Results {
		urls = append(urls, value.Url)
	}
	return urls
}

func openUrl(req string) (body []byte) {
	res, err := http.Get(req)
	perror(err)
	defer res.Body.Close()

	body, err = ioutil.ReadAll(res.Body)
	perror(err)
	return body
}
<commit_msg>Rename methods<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"time"
)

func main() {
	keyword, count := args()
	urls := fetchUrls(keyword, count)
	html := generateHtml(urls)
	openHtml(html)
}

func args() (keyword string, count int) {
	flag.StringVar(&keyword, "k", "yuyushiki", "keyword")
	flag.IntVar(&count, "c", 8, "count")
	flag.Parse()

	return keyword, count
}

func fetchUrls(keyword string, count int) (urls []string) {
	page := 1
	var _urls []string
	for len(urls) <= count {
		_urls = search(page, keyword)
		for _, url := range _urls {
			urls = append(urls, url)
		}
		page += 1
	}

	return urls
}

func generateHtml(urls []string) (html string) {
	html = "<!DOCTYPE HTML>"
	for _, url := range urls {
		html = html + ""
	}
	html = html + ""
	return html
}

func openHtml(html string) {
	file, err := ioutil.TempFile(os.TempDir(), "animegif")
	printError(err)
	ioutil.WriteFile(file.Name(), []byte(html), 0644)
	exec.Command("open", file.Name()).Start()
	time.Sleep(time.Second * 1)

	defer os.Remove(file.Name())
}

func printError(err error) {
	if err != nil {
		panic(err)
	}
}

type ResultType struct {
	Url string `json:"url"`
}

type ResponseDataType struct {
	Results []ResultType `json:"results"`
}

type ResponseType struct {
	ResponseData ResponseDataType `json:"responseData"`
}

func search(page int, keyword string) (urls []string) {
	perPage := 8
	base := "http://ajax.googleapis.com/ajax/services/search/images?"
	start := (page-1)*perPage + 1

	params := url.Values{}
	params.Add("q", keyword)
	params.Add("rsz", fmt.Sprint(perPage))
	params.Add("safe", "off")
	params.Add("v", "1.0")
	params.Add("as_filetype", "gif")
	params.Add("imgsz", "large")
	params.Add("start", fmt.Sprint(start))
	params.Add("as_sitesearch", "tumblr.com")

	body := openUrl(base + params.Encode())

	var response ResponseType
	err := json.Unmarshal(body, &response)
	printError(err)
	for _, value := range response.ResponseData.Results {
		urls = append(urls, value.Url)
	}
	return urls
}

func openUrl(req string) (body []byte) {
	res, err := http.Get(req)
	printError(err)
	defer res.Body.Close()

	body, err = ioutil.ReadAll(res.Body)
	printError(err)
	return body
}
<|endoftext|>


<commit_before>package ethchain

import (
	"bytes"
	"fmt"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/obscuren/secp256k1-go"
	"math/big"
)

var ContractAddr = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

type Transaction struct {
	Nonce     uint64
	Recipient []byte
	Value     *big.Int
	Gas       *big.Int
	Gasprice  *big.Int
	Data      []string
	v         byte
	r, s      []byte

	// Indicates whether this tx is a contract creation transaction
	contractCreation bool
}

func NewContractCreationTx(value, gasprice *big.Int, data []string) *Transaction {
	return &Transaction{Value: value, Gasprice: gasprice, Data: data, contractCreation: true}
}

func NewTransactionMessage(to []byte, value, gasprice, gas *big.Int, data []string) *Transaction {
	return &Transaction{Recipient: to, Value: value, Gasprice: gasprice, Gas: gas, Data: data}
}

func NewTransactionFromBytes(data []byte) *Transaction {
	tx := &Transaction{}
	tx.RlpDecode(data)

	return tx
}

func NewTransactionFromValue(val *ethutil.Value) *Transaction {
	tx := &Transaction{}
	tx.RlpValueDecode(val)

	return tx
}

func (tx *Transaction) Hash() []byte {
	data := make([]interface{}, len(tx.Data))
	for i, val := range tx.Data {
		data[i] = val
	}

	preEnc := []interface{}{
		tx.Nonce,
		tx.Recipient,
		tx.Value,
		data,
	}

	return ethutil.Sha3Bin(ethutil.Encode(preEnc))
}

func (tx *Transaction) IsContract() bool {
	return bytes.Compare(tx.Recipient, ContractAddr) == 0
}

func (tx *Transaction) Signature(key []byte) []byte {
	hash := tx.Hash()

	sig, _ := secp256k1.Sign(hash, key)

	return sig
}

func (tx *Transaction) PublicKey() []byte {
	hash := tx.Hash()

	// If we don't make a copy we will overwrite the existing underlying array
	dst := make([]byte, len(tx.r))
	copy(dst, tx.r)

	sig := append(dst, tx.s...)
	sig = append(sig, tx.v-27)

	pubkey, _ := secp256k1.RecoverPubkey(hash, sig)

	return pubkey
}

func (tx *Transaction) Sender() []byte {
	pubkey := tx.PublicKey()

	// Validate the returned key.
	// Return nil if public key isn't in full format
	if pubkey[0] != 4 {
		return nil
	}

	return ethutil.Sha3Bin(pubkey[1:])[12:]
}

func (tx *Transaction) Sign(privk []byte) error {

	sig := tx.Signature(privk)

	tx.r = sig[:32]
	tx.s = sig[32:64]
	tx.v = sig[64] + 27

	return nil
}

func (tx *Transaction) RlpData() interface{} {
	data := []interface{}{tx.Nonce, tx.Value, tx.Gasprice}

	if !tx.contractCreation {
		data = append(data, tx.Recipient, tx.Gas)
	}

	return append(data, ethutil.NewSliceValue(tx.Data).Slice(), tx.v, tx.r, tx.s)
}

func (tx *Transaction) RlpValue() *ethutil.Value {
	return ethutil.NewValue(tx.RlpData())
}

func (tx *Transaction) RlpEncode() []byte {
	return tx.RlpValue().Encode()
}

func (tx *Transaction) RlpDecode(data []byte) {
	tx.RlpValueDecode(ethutil.NewValueFromBytes(data))
}

//   [ NONCE, VALUE, GASPRICE, TO, GAS, DATA, V, R, S ]
//["" "\x03\xe8" "" "\xaa" "\x03\xe8" [] '\x1c' "\x10C\x15\xfc\xe5\xd0\t\xe4\r\xe7\xefa\xf5aE\xd6\x14\xaed\xb5.\xf5\x18\xa1S_j\xe0A\xdc5U" "dQ\nqy\xf8\x17+\xbf\xd7Jx\xda-\xcb\xd7\xcfQ\x1bI\xb8_9\b\x80\xea듎i|\x1f"]
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
	fmt.Println(decoder)
	tx.Nonce = decoder.Get(0).Uint()
	tx.Value = decoder.Get(1).BigInt()
	tx.Gasprice = decoder.Get(2).BigInt()

	// If the 4th item is a list(slice) this tx
	// is a contract creation tx
	if decoder.Get(3).IsList() {
		d := decoder.Get(3)
		tx.Data = make([]string, d.Len())
		for i := 0; i < d.Len(); i++ {
			tx.Data[i] = d.Get(i).Str()
		}

		tx.v = byte(decoder.Get(4).Uint())
		tx.r = decoder.Get(5).Bytes()
		tx.s = decoder.Get(6).Bytes()

		tx.contractCreation = true
	} else {
		tx.Recipient = decoder.Get(3).Bytes()
		tx.Gas = decoder.Get(4).BigInt()

		d := decoder.Get(5)
		tx.Data = make([]string, d.Len())
		for i := 0; i < d.Len(); i++ {
			tx.Data[i] = d.Get(i).Str()
		}

		tx.v = byte(decoder.Get(6).Uint())
		tx.r = decoder.Get(7).Bytes()
		tx.s = decoder.Get(8).Bytes()
	}
	/*
		tx.Nonce = decoder.Get(0).Uint()
		tx.Recipient = decoder.Get(1).Bytes()
		tx.Value = decoder.Get(2).BigInt()

		d := decoder.Get(3)
		tx.Data = make([]string, d.Len())
		for i := 0; i < d.Len(); i++ {
			tx.Data[i] = d.Get(i).Str()
		}

		tx.v = byte(decoder.Get(4).Uint())
		tx.r = decoder.Get(5).Bytes()
		tx.s = decoder.Get(6).Bytes()
	*/
}
<commit_msg>Removed debug and comments<commit_after>package ethchain

import (
	"bytes"
	"github.com/ethereum/eth-go/ethutil"
	"github.com/obscuren/secp256k1-go"
	"math/big"
)

var ContractAddr = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

type Transaction struct {
	Nonce     uint64
	Recipient []byte
	Value     *big.Int
	Gas       *big.Int
	Gasprice  *big.Int
	Data      []string
	v         byte
	r, s      []byte

	// Indicates whether this tx is a contract creation transaction
	contractCreation bool
}

func NewContractCreationTx(value, gasprice *big.Int, data []string) *Transaction {
	return &Transaction{Value: value, Gasprice: gasprice, Data: data, contractCreation: true}
}

func NewTransactionMessage(to []byte, value, gasprice, gas *big.Int, data []string) *Transaction {
	return &Transaction{Recipient: to, Value: value, Gasprice: gasprice, Gas: gas, Data: data}
}

func NewTransactionFromBytes(data []byte) *Transaction {
	tx := &Transaction{}
	tx.RlpDecode(data)

	return tx
}

func NewTransactionFromValue(val *ethutil.Value) *Transaction {
	tx := &Transaction{}
	tx.RlpValueDecode(val)

	return tx
}

func (tx *Transaction) Hash() []byte {
	data := make([]interface{}, len(tx.Data))
	for i, val := range tx.Data {
		data[i] = val
	}

	preEnc := []interface{}{
		tx.Nonce,
		tx.Recipient,
		tx.Value,
		data,
	}

	return ethutil.Sha3Bin(ethutil.Encode(preEnc))
}

func (tx *Transaction) IsContract() bool {
	return bytes.Compare(tx.Recipient, ContractAddr) == 0
}

func (tx *Transaction) Signature(key []byte) []byte {
	hash := tx.Hash()

	sig, _ := secp256k1.Sign(hash, key)

	return sig
}

func (tx *Transaction) PublicKey() []byte {
	hash := tx.Hash()

	// If we don't make a copy we will overwrite the existing underlying array
	dst := make([]byte, len(tx.r))
	copy(dst, tx.r)

	sig := append(dst, tx.s...)
	sig = append(sig, tx.v-27)

	pubkey, _ := secp256k1.RecoverPubkey(hash, sig)

	return pubkey
}

func (tx *Transaction) Sender() []byte {
	pubkey := tx.PublicKey()

	// Validate the returned key.
	// Return nil if public key isn't in full format
	if pubkey[0] != 4 {
		return nil
	}

	return ethutil.Sha3Bin(pubkey[1:])[12:]
}

func (tx *Transaction) Sign(privk []byte) error {

	sig := tx.Signature(privk)

	tx.r = sig[:32]
	tx.s = sig[32:64]
	tx.v = sig[64] + 27

	return nil
}

func (tx *Transaction) RlpData() interface{} {
	data := []interface{}{tx.Nonce, tx.Value, tx.Gasprice}

	if !tx.contractCreation {
		data = append(data, tx.Recipient, tx.Gas)
	}

	return append(data, ethutil.NewSliceValue(tx.Data).Slice(), tx.v, tx.r, tx.s)
}

func (tx *Transaction) RlpValue() *ethutil.Value {
	return ethutil.NewValue(tx.RlpData())
}

func (tx *Transaction) RlpEncode() []byte {
	return tx.RlpValue().Encode()
}

func (tx *Transaction) RlpDecode(data []byte) {
	tx.RlpValueDecode(ethutil.NewValueFromBytes(data))
}

func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
	tx.Nonce = decoder.Get(0).Uint()
	tx.Value = decoder.Get(1).BigInt()
	tx.Gasprice = decoder.Get(2).BigInt()

	// If the 4th item is a list(slice) this tx
	// is a contract creation tx
	if decoder.Get(3).IsList() {
		d := decoder.Get(3)
		tx.Data = make([]string, d.Len())
		for i := 0; i < d.Len(); i++ {
			tx.Data[i] = d.Get(i).Str()
		}

		tx.v = byte(decoder.Get(4).Uint())
		tx.r = decoder.Get(5).Bytes()
		tx.s = decoder.Get(6).Bytes()

		tx.contractCreation = true
	} else {
		tx.Recipient = decoder.Get(3).Bytes()
		tx.Gas = decoder.Get(4).BigInt()

		d := decoder.Get(5)
		tx.Data = make([]string, d.Len())
		for i := 0; i < d.Len(); i++ {
			tx.Data[i] = d.Get(i).Str()
		}

		tx.v = byte(decoder.Get(6).Uint())
		tx.r = decoder.Get(7).Bytes()
		tx.s = decoder.Get(8).Bytes()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

func main() {

} // main<commit_msg>Final edit Palindrome<commit_after>package main

import (
	"bytes"
	"container/list"
	"fmt"
)

func main() {
	input := ""

	fmt.Print("Please enter a word: ")
	fmt.Scanln(&input)

	fmt.Printf("Is %s palindrome: %t\n\n", input, palindrome(input))

} // main

func palindrome(testString string) bool {
	// I didn't find a native, out of the box implementation of a stack in Go
	// So, let's use a linked list a stack
	aStack := list.New()

	var stringBuilder bytes.Buffer

	// Push 'testString' into 'aStack'
	for i := 0; i < len(testString); i++ {
		// Convert 'string' characters into 'runes' because Go is so cool. Wow!
		aStack.PushBack(rune(testString[i]))
	}

	// Debug
	// fmt.Print("Debug: palindrome(): ")
	// for e := aStack.Front(); e != nil; e = e.Next() {
	// 	fmt.Printf("%c", e.Value.(rune))
	// }
	// fmt.Print("\n")

	// Pops out the stack into a 'bytes.Buffer' (like Java's StringBuilder)
	for e := aStack.Back(); e != nil; e = e.Prev() {
		// Saw this in StackOverflow https://stackoverflow.com/questions/1760757/how-to-efficiently-concatenate-strings-in-go
		stringBuilder.WriteRune(e.Value.(rune))
	}

	// Debug
	// fmt.Println("Debug: palindrome(): stringBuilder: ", string(stringBuilder.String()))

	if testString == stringBuilder.String() {
		return true
	}

	return false
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/corywalker/expreduce/expreduce"
	"gopkg.in/readline.v1"
	"log"
	"os"
	"runtime/pprof"
)

var debug = flag.Bool("debug", false, "Debug mode. No initial definitions.")
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")

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

	rl, err := readline.NewEx(&readline.Config{
		HistoryFile:         "/tmp/readline.tmp",
		ForceUseInteractive: true,
	})
	if err != nil {
		panic(err)
	}
	defer rl.Close()

	es := expreduce.NewEvalState()
	if *debug {
		es.NoInit = true
		es.ClearAll()
	}

	fmt.Printf("Welcome to Expreduce!\n\n")
	promptNum := 1
	for {
		rl.SetPrompt(fmt.Sprintf("In[%d]:= ", promptNum))
		line, err := rl.Readline()
		if err != nil { // io.EOF, readline.ErrInterrupt
			break
		}
		if line == "" {
			continue
		}
		fmt.Printf("\n")

		exp := expreduce.Interp(line, es)
		res := exp.Eval(es)
		res = es.ProcessTopLevelResult(res)

		isNull := false
		asSym, isSym := res.(*expreduce.Symbol)
		if isSym {
			if asSym.Name == "System`Null" {
				isNull = true
			}
		}

		if !isNull {
			// Print formatted result
			context, contextPath := expreduce.ActualStringFormArgs(es)
			specialForms := []string{
				"System`FullForm",
				"System`OutputForm",
			}
			wasSpecialForm := false
			for _, specialForm := range specialForms {
				asSpecialForm, isSpecialForm := expreduce.HeadAssertion(
					res, specialForm)
				if !isSpecialForm {
					continue
				}
				if len(asSpecialForm.Parts) != 2 {
					continue
				}
				fmt.Printf(
					"Out[%d]//%s= %s\n\n",
					promptNum,
					specialForm[7:],
					asSpecialForm.Parts[1].StringForm(
						specialForm[7:], context, contextPath),
				)
				wasSpecialForm = true
			}
			if !wasSpecialForm {
				fmt.Printf("Out[%d]= %s\n\n", promptNum, res.StringForm(
					"InputForm", context, contextPath))
			}
		}

		promptNum += 1
	}
}
<commit_msg>netprofile.<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/corywalker/expreduce/expreduce"
	"gopkg.in/readline.v1"
	"log"
	"os"
	"runtime/pprof"
	"net/http"
	_ "net/http/pprof"
)

var debug = flag.Bool("debug", false, "Debug mode. No initial definitions.")
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
var netprofile = flag.Bool("netprofile", false, "Enable live profiling at http://localhost:8080/debug/pprof/")

func main() {
	flag.Parse()
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}
	if *netprofile {
		go http.ListenAndServe(":8080", nil)
	}

	rl, err := readline.NewEx(&readline.Config{
		HistoryFile:         "/tmp/readline.tmp",
		ForceUseInteractive: true,
	})
	if err != nil {
		panic(err)
	}
	defer rl.Close()

	es := expreduce.NewEvalState()
	if *debug {
		es.NoInit = true
		es.ClearAll()
	}

	fmt.Printf("Welcome to Expreduce!\n\n")
	promptNum := 1
	for {
		rl.SetPrompt(fmt.Sprintf("In[%d]:= ", promptNum))
		line, err := rl.Readline()
		if err != nil { // io.EOF, readline.ErrInterrupt
			break
		}
		if line == "" {
			continue
		}
		fmt.Printf("\n")

		exp := expreduce.Interp(line, es)
		res := exp.Eval(es)
		res = es.ProcessTopLevelResult(res)

		isNull := false
		asSym, isSym := res.(*expreduce.Symbol)
		if isSym {
			if asSym.Name == "System`Null" {
				isNull = true
			}
		}

		if !isNull {
			// Print formatted result
			context, contextPath := expreduce.ActualStringFormArgs(es)
			specialForms := []string{
				"System`FullForm",
				"System`OutputForm",
			}
			wasSpecialForm := false
			for _, specialForm := range specialForms {
				asSpecialForm, isSpecialForm := expreduce.HeadAssertion(
					res, specialForm)
				if !isSpecialForm {
					continue
				}
				if len(asSpecialForm.Parts) != 2 {
					continue
				}
				fmt.Printf(
					"Out[%d]//%s= %s\n\n",
					promptNum,
					specialForm[7:],
					asSpecialForm.Parts[1].StringForm(
						specialForm[7:], context, contextPath),
				)
				wasSpecialForm = true
			}
			if !wasSpecialForm {
				fmt.Printf("Out[%d]= %s\n\n", promptNum, res.StringForm(
					"InputForm", context, contextPath))
			}
		}

		promptNum += 1
	}
}
<|endoftext|>


<commit_before>package gcppubsub

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"sync"
	"time"

	"cloud.google.com/go/pubsub"
	"github.com/RichardKnop/machinery/v1/brokers/iface"
	"github.com/RichardKnop/machinery/v1/common"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/tasks"
)

// Broker represents an Google Cloud Pub/Sub broker
type Broker struct {
	common.Broker

	service          *pubsub.Client
	subscriptionName string
	MaxExtension     time.Duration

	processingWG sync.WaitGroup
}

// New creates new Broker instance
func New(cnf *config.Config, projectID, subscriptionName string) (iface.Broker, error) {
	b := &Broker{Broker: common.NewBroker(cnf)}
	b.subscriptionName = subscriptionName

	ctx := context.Background()

	if cnf.GCPPubSub != nil {
		b.MaxExtension = cnf.GCPPubSub.MaxExtension
	}

	if cnf.GCPPubSub != nil && cnf.GCPPubSub.Client != nil {
		b.service = cnf.GCPPubSub.Client
	} else {
		pubsubClient, err := pubsub.NewClient(ctx, projectID)
		if err != nil {
			return nil, err
		}
		b.service = pubsubClient
		cnf.GCPPubSub = &config.GCPPubSubConfig{
			Client: pubsubClient,
		}
	}

	// Validate topic exists
	defaultQueue := b.GetConfig().DefaultQueue
	topic := b.service.Topic(defaultQueue)
	defer topic.Stop()

	topicExists, err := topic.Exists(ctx)
	if err != nil {
		return nil, err
	}
	if !topicExists {
		return nil, fmt.Errorf("topic does not exist, instead got %s", defaultQueue)
	}

	// Validate subscription exists
	sub := b.service.Subscription(b.subscriptionName)

	if b.MaxExtension != 0 {
		sub.ReceiveSettings.MaxExtension = b.MaxExtension
	}

	subscriptionExists, err := sub.Exists(ctx)
	if err != nil {
		return nil, err
	}
	if !subscriptionExists {
		return nil, fmt.Errorf("subscription does not exist, instead got %s", b.subscriptionName)
	}

	return b, nil
}

// StartConsuming enters a loop and waits for incoming messages
func (b *Broker) StartConsuming(consumerTag string, concurrency int, taskProcessor iface.TaskProcessor) (bool, error) {
	b.Broker.StartConsuming(consumerTag, concurrency, taskProcessor)
	deliveries := make(chan *pubsub.Message)

	sub := b.service.Subscription(b.subscriptionName)

	if b.MaxExtension != 0 {
		sub.ReceiveSettings.MaxExtension = b.MaxExtension
		sub.ReceiveSettings.NumGoroutines = concurrency
	}

	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		log.INFO.Print("[*] Waiting for messages. To exit press CTRL+C")

		for {
			select {
			// A way to stop this goroutine from b.StopConsuming
			case <-b.GetStopChan():
				cancel()
				return
			default:
				err := sub.Receive(ctx, func(_ctx context.Context, msg *pubsub.Message) {
					deliveries <- msg
				})

				if err != nil {
					log.ERROR.Printf("Error when receiving messages. Error: %v", err)
					continue
				}
			}
		}
	}()

	if err := b.consume(deliveries, concurrency, taskProcessor); err != nil {
		return b.GetRetry(), err
	}

	return b.GetRetry(), nil
}

// StopConsuming quits the loop
func (b *Broker) StopConsuming() {
	b.Broker.StopConsuming()

	// Waiting for any tasks being processed to finish
	b.processingWG.Wait()
}

// Publish places a new message on the default queue
func (b *Broker) Publish(ctx context.Context, signature *tasks.Signature) error {
	// Adjust routing key (this decides which queue the message will be published to)
	b.AdjustRoutingKey(signature)

	msg, err := json.Marshal(signature)
	if err != nil {
		return fmt.Errorf("JSON marshal error: %s", err)
	}

	defaultQueue := b.GetConfig().DefaultQueue
	topic := b.service.Topic(defaultQueue)
	defer topic.Stop()

	// Check the ETA signature field, if it is set and it is in the future,
	// delay the task
	if signature.ETA != nil {
		now := time.Now().UTC()

		if signature.ETA.After(now) {
			topic.PublishSettings.DelayThreshold = signature.ETA.Sub(now)
		}
	}

	result := topic.Publish(ctx, &pubsub.Message{
		Data: msg,
	})

	id, err := result.Get(ctx)
	if err != nil {
		log.ERROR.Printf("Error when sending a message: %v", err)
		return err
	}

	log.INFO.Printf("Sending a message successfully, server-generated message ID %v", id)
	return nil
}

// consume takes delivered messages from the channel and manages a worker pool
// to process tasks concurrently
func (b *Broker) consume(deliveries <-chan *pubsub.Message, concurrency int, taskProcessor iface.TaskProcessor) error {
	pool := make(chan struct{}, concurrency)

	// initialize worker pool with maxWorkers workers
	go func() {
		for i := 0; i < concurrency; i++ {
			pool <- struct{}{}
		}
	}()

	errorsChan := make(chan error)

	for {
		select {
		case err := <-errorsChan:
			return err
		case d := <-deliveries:
			if concurrency > 0 {
				// get worker from pool (blocks until one is available)
				<-pool
			}

			b.processingWG.Add(1)

			// Consume the task inside a gotourine so multiple tasks
			// can be processed concurrently
			go func() {
				if err := b.consumeOne(d, taskProcessor); err != nil {
					errorsChan <- err
				}

				b.processingWG.Done()

				if concurrency > 0 {
					// give worker back to pool
					pool <- struct{}{}
				}
			}()
		case <-b.GetStopChan():
			return nil
		}
	}
}

// consumeOne processes a single message using TaskProcessor
func (b *Broker) consumeOne(delivery *pubsub.Message, taskProcessor iface.TaskProcessor) error {
	if len(delivery.Data) == 0 {
		delivery.Nack()
		log.ERROR.Printf("received an empty message, the delivery was %v", delivery)
		return errors.New("Received an empty message")
	}

	sig := new(tasks.Signature)
	decoder := json.NewDecoder(bytes.NewBuffer(delivery.Data))
	decoder.UseNumber()
	if err := decoder.Decode(sig); err != nil {
		delivery.Nack()
		log.ERROR.Printf("unmarshal error. the delivery is %v", delivery)
		return err
	}

	// If the task is not registered return an error
	// and leave the message in the queue
	if !b.IsTaskRegistered(sig.Name) {
		delivery.Nack()
		return fmt.Errorf("task %s is not registered", sig.Name)
	}

	err := taskProcessor.Process(sig)
	if err != nil {
		delivery.Nack()
		return err
	}

	// Call Ack() after successfully consuming and processing the message
	delivery.Ack()

	return err
}
<commit_msg>Fix pubsub termination<commit_after>package gcppubsub

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"time"

	"cloud.google.com/go/pubsub"
	"github.com/RichardKnop/machinery/v1/brokers/iface"
	"github.com/RichardKnop/machinery/v1/common"
	"github.com/RichardKnop/machinery/v1/config"
	"github.com/RichardKnop/machinery/v1/log"
	"github.com/RichardKnop/machinery/v1/tasks"
)

// Broker represents an Google Cloud Pub/Sub broker
type Broker struct {
	common.Broker

	service          *pubsub.Client
	subscriptionName string
	MaxExtension     time.Duration

	stopDone chan struct{}
}

// New creates new Broker instance
func New(cnf *config.Config, projectID, subscriptionName string) (iface.Broker, error) {
	b := &Broker{Broker: common.NewBroker(cnf), stopDone: make(chan struct{})}
	b.subscriptionName = subscriptionName

	ctx := context.Background()

	if cnf.GCPPubSub != nil {
		b.MaxExtension = cnf.GCPPubSub.MaxExtension
	}

	if cnf.GCPPubSub != nil && cnf.GCPPubSub.Client != nil {
		b.service = cnf.GCPPubSub.Client
	} else {
		pubsubClient, err := pubsub.NewClient(ctx, projectID)
		if err != nil {
			return nil, err
		}
		b.service = pubsubClient
		cnf.GCPPubSub = &config.GCPPubSubConfig{
			Client: pubsubClient,
		}
	}

	// Validate topic exists
	defaultQueue := b.GetConfig().DefaultQueue
	topic := b.service.Topic(defaultQueue)
	defer topic.Stop()

	topicExists, err := topic.Exists(ctx)
	if err != nil {
		return nil, err
	}
	if !topicExists {
		return nil, fmt.Errorf("topic does not exist, instead got %s", defaultQueue)
	}

	// Validate subscription exists
	sub := b.service.Subscription(b.subscriptionName)

	if b.MaxExtension != 0 {
		sub.ReceiveSettings.MaxExtension = b.MaxExtension
	}

	subscriptionExists, err := sub.Exists(ctx)
	if err != nil {
		return nil, err
	}
	if !subscriptionExists {
		return nil, fmt.Errorf("subscription does not exist, instead got %s", b.subscriptionName)
	}

	return b, nil
}

// StartConsuming enters a loop and waits for incoming messages
func (b *Broker) StartConsuming(consumerTag string, concurrency int, taskProcessor iface.TaskProcessor) (bool, error) {
	b.Broker.StartConsuming(consumerTag, concurrency, taskProcessor)

	sub := b.service.Subscription(b.subscriptionName)

	if b.MaxExtension != 0 {
		sub.ReceiveSettings.MaxExtension = b.MaxExtension
	}

	sub.ReceiveSettings.NumGoroutines = concurrency
	log.INFO.Print("[*] Waiting for messages. To exit press CTRL+C")

	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		<-b.GetStopChan()
		cancel()
	}()

	for {
		err := sub.Receive(ctx, func(_ctx context.Context, msg *pubsub.Message) {
			b.consumeOne(msg, taskProcessor)
		})
		if err == nil {
			break
		}

		log.ERROR.Printf("Error when receiving messages. Error: %v", err)
		continue
	}

	close(b.stopDone)

	return b.GetRetry(), nil
}

// StopConsuming quits the loop
func (b *Broker) StopConsuming() {
	b.Broker.StopConsuming()

	// Waiting for any tasks being processed to finish
	<-b.stopDone
}

// Publish places a new message on the default queue
func (b *Broker) Publish(ctx context.Context, signature *tasks.Signature) error {
	// Adjust routing key (this decides which queue the message will be published to)
	b.AdjustRoutingKey(signature)

	msg, err := json.Marshal(signature)
	if err != nil {
		return fmt.Errorf("JSON marshal error: %s", err)
	}

	defaultQueue := b.GetConfig().DefaultQueue
	topic := b.service.Topic(defaultQueue)
	defer topic.Stop()

	// Check the ETA signature field, if it is set and it is in the future,
	// delay the task
	if signature.ETA != nil {
		now := time.Now().UTC()

		if signature.ETA.After(now) {
			topic.PublishSettings.DelayThreshold = signature.ETA.Sub(now)
		}
	}

	result := topic.Publish(ctx, &pubsub.Message{
		Data: msg,
	})

	id, err := result.Get(ctx)
	if err != nil {
		log.ERROR.Printf("Error when sending a message: %v", err)
		return err
	}

	log.INFO.Printf("Sending a message successfully, server-generated message ID %v", id)
	return nil
}

// consumeOne processes a single message using TaskProcessor
func (b *Broker) consumeOne(delivery *pubsub.Message, taskProcessor iface.TaskProcessor) {
	if len(delivery.Data) == 0 {
		delivery.Nack()
		log.ERROR.Printf("received an empty message, the delivery was %v", delivery)
	}

	sig := new(tasks.Signature)
	decoder := json.NewDecoder(bytes.NewBuffer(delivery.Data))
	decoder.UseNumber()
	if err := decoder.Decode(sig); err != nil {
		delivery.Nack()
		log.ERROR.Printf("unmarshal error. the delivery is %v", delivery)
	}

	// If the task is not registered return an error
	// and leave the message in the queue
	if !b.IsTaskRegistered(sig.Name) {
		delivery.Nack()
		log.ERROR.Printf("task %s is not registered", sig.Name)
	}

	err := taskProcessor.Process(sig)
	if err != nil {
		delivery.Nack()
		log.ERROR.Printf("Failed process of task", err)
	}

	// Call Ack() after successfully consuming and processing the message
	delivery.Ack()
}
<|endoftext|>


<commit_before>// +build performance

/*
Copyright 2018 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package performance

import (
	"fmt"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"testing"
	"time"

	"github.com/pkg/errors"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"

	"github.com/knative/test-infra/shared/junit"
	perf "github.com/knative/test-infra/shared/performance"
	"github.com/knative/test-infra/shared/testgrid"
	"golang.org/x/sync/errgroup"
	pkgTest "knative.dev/pkg/test"
	"knative.dev/pkg/test/spoof"
	rsNames "knative.dev/serving/pkg/reconciler/revision/resources/names"
	"knative.dev/serving/test"
	"knative.dev/serving/test/e2e"
	v1a1test "knative.dev/serving/test/v1alpha1"
)

// generateTraffic loads the given endpoint with the given concurrency for the given duration.
// All responses are forwarded to a channel, if given.
func generateTraffic(t *testing.T, client *spoof.SpoofingClient, url string, concurrency int, duration time.Duration, resChannel chan *spoof.Response) error {
	var group errgroup.Group
	// Notify the consumer about the end of the data stream.
	defer close(resChannel)

	for i := 0; i < concurrency; i++ {
		group.Go(func() error {
			done := time.After(duration)
			req, err := http.NewRequest(http.MethodGet, url, nil)
			if err != nil {
				return fmt.Errorf("error creating http request: %v", err)
			}
			for {
				select {
				case <-done:
					return nil
				default:
					res, err := client.Do(req)
					if err != nil {
						t.Logf("Error sending request: %v", err)
					}
					resChannel <- res
				}
			}
		})
	}

	if err := group.Wait(); err != nil {
		return fmt.Errorf("error making requests for scale up: %v", err)
	}
	return nil
}

// event represents the start or end of a request
type event struct {
	concurrencyModifier int
	timestamp           time.Time
}

// parseResponse parses a string of the form TimeInNano,TimeInNano into the respective
// start and end event
func parseResponse(body string) (*event, *event, error) {
	body = strings.TrimSpace(body)
	parts := strings.Split(body, ",")

	if len(parts) < 2 {
		return nil, nil, fmt.Errorf("not enough parts in body, got %q", body)
	}

	start, err := strconv.ParseInt(parts[0], 10, 64)
	if err != nil {
		return nil, nil, errors.Wrapf(err, "failed to parse start timestamp, body %q", body)
	}

	end, err := strconv.ParseInt(parts[1], 10, 64)
	if err != nil {
		return nil, nil, errors.Wrapf(err, "failed to parse end timestamp, body %q", body)
	}

	startEvent := &event{1, time.Unix(0, int64(start))}
	endEvent := &event{-1, time.Unix(0, int64(end))}

	return startEvent, endEvent, nil
}

// timeToScale calculates the time it took to scale to a given scale, starting from a given
// time. Returns an error if that scale was never reached.
func timeToScale(events []*event, start time.Time, desiredScale int) (time.Duration, error) {
	var currentConcurrency int
	for _, event := range events {
		currentConcurrency += event.concurrencyModifier
		if currentConcurrency == desiredScale {
			return event.timestamp.Sub(start), nil
		}
	}

	return 0, fmt.Errorf("desired scale of %d was never reached", desiredScale)
}

func TestObservedConcurrency(t *testing.T) {
	var tc []junit.TestCase
	tests := []int{5, 10} //going beyond 10 currently causes "overload" responses
	for _, clients := range tests {
		t.Run(fmt.Sprintf("scale-%02d", clients), func(t *testing.T) {
			tc = append(tc, testConcurrencyN(t, clients)...)
		})
	}
	if err := testgrid.CreateXMLOutput(tc, t.Name()); err != nil {
		t.Fatalf("Cannot create output xml: %v", err)
	}
}

func testConcurrencyN(t *testing.T, concurrency int) []junit.TestCase {
	perfClients, err := Setup(t)
	if err != nil {
		t.Fatalf("Cannot initialize performance client: %v", err)
	}

	names := test.ResourceNames{
		Service: test.ObjectNameForTest(t),
		Image:   "observed-concurrency",
	}
	clients := perfClients.E2EClients

	defer TearDown(perfClients, names, t.Logf)
	test.CleanupOnInterrupt(func() { TearDown(perfClients, names, t.Logf) })

	t.Log("Creating a new Service")
	objs, err := v1a1test.CreateRunLatestServiceReady(t, clients, &names, &v1a1test.Options{
		ContainerConcurrency: 1,
		ContainerResources: corev1.ResourceRequirements{
			Requests: corev1.ResourceList{
				corev1.ResourceCPU:    resource.MustParse("10m"),
				corev1.ResourceMemory: resource.MustParse("20Mi"),
			},
		},
	})
	if err != nil {
		t.Fatalf("Failed to create Service: %v", err)
	}

	t.Logf("%02d: waiting for deployment to scale to zero.", concurrency)
	deploymentName := rsNames.Deployment(objs.Revision)
	if err := e2e.WaitForScaleToZero(t, deploymentName, clients); err != nil {
		t.Fatalf("%02d: failed waiting for deployment to scale to zero: %v", concurrency, err)
	}

	domain := objs.Route.Status.URL.Host
	url := fmt.Sprintf("http://%s/?timeout=1000", domain)
	client, err := pkgTest.NewSpoofingClient(clients.KubeClient, t.Logf, domain, test.ServingFlags.ResolvableDomain)
	if err != nil {
		t.Fatalf("Error creating spoofing client: %v", err)
	}

	// This just helps with preallocation.
	const presumedSize = 1000

	eg := errgroup.Group{}
	trafficStart := time.Now()
	responseChannel := make(chan *spoof.Response, presumedSize)
	events := make([]*event, 0, presumedSize)
	failedRequests := 0

	t.Logf("Running %d concurrent requests for %v", concurrency, duration)
	eg.Go(func() error {
		return generateTraffic(t, client, url, concurrency, duration, responseChannel)
	})
	eg.Go(func() error {
		for response := range responseChannel {
			if response == nil {
				failedRequests++
				continue
			}
			start, end, err := parseResponse(string(response.Body))
			if err != nil {
				t.Logf("Failed to parse the body: %v", err)
				failedRequests++
				continue
			}
			events = append(events, start, end)
		}
		// Sort all events by their timestamp.
		sort.Slice(events, func(i, j int) bool {
			return events[i].timestamp.Before(events[j].timestamp)
		})
		return nil
	})

	if err := eg.Wait(); err != nil {
		t.Fatalf("Failed to generate traffic and process responses: %v", err)
	}
	t.Logf("Generated %d requests with %d failed", len(events)+failedRequests, failedRequests)

	var tc []junit.TestCase
	for i := 1; i <= concurrency; i++ {
		toConcurrency, err := timeToScale(events, trafficStart, i)
		if err != nil {
			t.Logf("Never scaled to %d", i)
		} else {
			t.Logf("Took %v to scale to %d", toConcurrency, i)
			tc = append(tc, perf.CreatePerfTestCase(float32(toConcurrency/time.Millisecond), fmt.Sprintf("to%d(ms)", i), t.Name()))
		}
	}
	tc = append(tc, perf.CreatePerfTestCase(float32(failedRequests), "failed requests", t.Name()))

	return tc
}
<commit_msg>Use the time from the pods to calculate time to scale (#4722)<commit_after>// +build performance

/*
Copyright 2018 The Knative Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package performance

import (
	"fmt"
	"net/http"
	"sort"
	"strconv"
	"strings"
	"testing"
	"time"

	"github.com/pkg/errors"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"

	"github.com/knative/test-infra/shared/junit"
	perf "github.com/knative/test-infra/shared/performance"
	"github.com/knative/test-infra/shared/testgrid"
	"golang.org/x/sync/errgroup"
	pkgTest "knative.dev/pkg/test"
	"knative.dev/pkg/test/spoof"
	"knative.dev/serving/test"
	v1a1test "knative.dev/serving/test/v1alpha1"
)

// generateTraffic loads the given endpoint with the given concurrency for the given duration.
// All responses are forwarded to a channel, if given.
func generateTraffic(t *testing.T, client *spoof.SpoofingClient, url string, concurrency int, duration time.Duration, resChannel chan *spoof.Response) error {
	var group errgroup.Group
	// Notify the consumer about the end of the data stream.
	defer close(resChannel)

	for i := 0; i < concurrency; i++ {
		group.Go(func() error {
			done := time.After(duration)
			req, err := http.NewRequest(http.MethodGet, url, nil)
			if err != nil {
				return fmt.Errorf("error creating http request: %v", err)
			}
			for {
				select {
				case <-done:
					return nil
				default:
					res, err := client.Do(req)
					if err != nil {
						t.Logf("Error sending request: %v", err)
					}
					resChannel <- res
				}
			}
		})
	}

	if err := group.Wait(); err != nil {
		return fmt.Errorf("error making requests for scale up: %v", err)
	}
	return nil
}

// event represents the start or end of a request
type event struct {
	concurrencyModifier int
	timestamp           time.Time
}

// parseResponse parses a string of the form TimeInNano,TimeInNano into the respective
// start and end event
func parseResponse(body string) (*event, *event, error) {
	body = strings.TrimSpace(body)
	parts := strings.Split(body, ",")

	if len(parts) < 2 {
		return nil, nil, fmt.Errorf("not enough parts in body, got %q", body)
	}

	start, err := strconv.ParseInt(parts[0], 10, 64)
	if err != nil {
		return nil, nil, errors.Wrapf(err, "failed to parse start timestamp, body %q", body)
	}

	end, err := strconv.ParseInt(parts[1], 10, 64)
	if err != nil {
		return nil, nil, errors.Wrapf(err, "failed to parse end timestamp, body %q", body)
	}

	startEvent := &event{1, time.Unix(0, int64(start))}
	endEvent := &event{-1, time.Unix(0, int64(end))}

	return startEvent, endEvent, nil
}

// timeToScale calculates the time it took to scale to a given scale, starting from a given
// time. Returns an error if that scale was never reached.
func timeToScale(events []*event, desiredScale int) (time.Duration, error) {
	var currentConcurrency int
	start := events[0].timestamp
	for _, event := range events {
		currentConcurrency += event.concurrencyModifier
		if currentConcurrency == desiredScale {
			return event.timestamp.Sub(start), nil
		}
	}

	return 0, fmt.Errorf("desired scale of %d was never reached", desiredScale)
}

func TestObservedConcurrency(t *testing.T) {
	var tc []junit.TestCase
	tests := []int{5, 10, 15} //going beyond 15 currently causes "overload" responses
	for _, clients := range tests {
		t.Run(fmt.Sprintf("scale-%02d", clients), func(t *testing.T) {
			tc = append(tc, testConcurrencyN(t, clients)...)
		})
	}
	if err := testgrid.CreateXMLOutput(tc, t.Name()); err != nil {
		t.Fatalf("Cannot create output xml: %v", err)
	}
}

func testConcurrencyN(t *testing.T, concurrency int) []junit.TestCase {
	perfClients, err := Setup(t)
	if err != nil {
		t.Fatalf("Cannot initialize performance client: %v", err)
	}

	names := test.ResourceNames{
		Service: test.ObjectNameForTest(t),
		Image:   "observed-concurrency",
	}
	clients := perfClients.E2EClients

	defer TearDown(perfClients, names, t.Logf)
	test.CleanupOnInterrupt(func() { TearDown(perfClients, names, t.Logf) })

	t.Log("Creating a new Service")
	objs, err := v1a1test.CreateRunLatestServiceReady(t, clients, &names, &v1a1test.Options{
		ContainerConcurrency: 1,
		ContainerResources: corev1.ResourceRequirements{
			Requests: corev1.ResourceList{
				corev1.ResourceCPU:    resource.MustParse("10m"),
				corev1.ResourceMemory: resource.MustParse("20Mi"),
			},
		},
	})
	if err != nil {
		t.Fatalf("Failed to create Service: %v", err)
	}

	domain := objs.Route.Status.URL.Host
	url := fmt.Sprintf("http://%s/?timeout=1000", domain)
	client, err := pkgTest.NewSpoofingClient(clients.KubeClient, t.Logf, domain, test.ServingFlags.ResolvableDomain)
	if err != nil {
		t.Fatalf("Error creating spoofing client: %v", err)
	}

	// This just helps with preallocation.
	const presumedSize = 1000

	eg := errgroup.Group{}
	responseChannel := make(chan *spoof.Response, presumedSize)
	events := make([]*event, 0, presumedSize)
	failedRequests := 0

	t.Logf("Running %d concurrent requests for %v", concurrency, duration)
	eg.Go(func() error {
		return generateTraffic(t, client, url, concurrency, duration, responseChannel)
	})
	eg.Go(func() error {
		for response := range responseChannel {
			if response == nil {
				failedRequests++
				continue
			}
			start, end, err := parseResponse(string(response.Body))
			if err != nil {
				t.Logf("Failed to parse the body: %v", err)
				failedRequests++
				continue
			}
			events = append(events, start, end)
		}
		// Sort all events by their timestamp.
		sort.Slice(events, func(i, j int) bool {
			return events[i].timestamp.Before(events[j].timestamp)
		})
		return nil
	})

	if err := eg.Wait(); err != nil {
		t.Fatalf("Failed to generate traffic and process responses: %v", err)
	}
	t.Logf("Generated %d requests with %d failed", len(events)+failedRequests, failedRequests)

	var tc []junit.TestCase
	for i := 2; i <= concurrency; i++ {
		toConcurrency, err := timeToScale(events, i)
		if err != nil {
			t.Logf("Never scaled to %d", i)
		} else {
			t.Logf("Took %v to scale to %d", toConcurrency, i)
			tc = append(tc, perf.CreatePerfTestCase(float32(toConcurrency/time.Millisecond), fmt.Sprintf("to%d(ms)", i), t.Name()))
		}
	}
	tc = append(tc, perf.CreatePerfTestCase(float32(failedRequests), "failed requests", t.Name()))

	return tc
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 Pagoda Box Inc.
//
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.

package api

import (
	"fmt"
	"io"
	"net/http"
	"strconv"
	"sync"
	"time"

	"github.com/nanobox-io/nanobox-server/config"
	"github.com/nanobox-io/nanobox-server/util"
	"github.com/nanobox-io/nanobox-server/util/docker"
	"github.com/nanobox-io/nanobox-server/util/fs"
)

var execWait = sync.WaitGroup{}

var execKeys = map[string]string{}

func (api *API) LibDirs(rw http.ResponseWriter, req *http.Request) {
	writeBody(fs.LibDirs(), rw, http.StatusOK)
}

func (api *API) FileChange(rw http.ResponseWriter, req *http.Request) {
	<- time.After(time.Second)
	fs.Touch(req.FormValue("filename"))
	writeBody(nil, rw, http.StatusOK)
}

// func (api *API) KillRun(rw http.ResponseWriter, req *http.Request) {
// 	fmt.Printf("signal recieved: %s\n", req.FormValue("signal"))
// 	err := docker.KillContainer("exec1", req.FormValue("signal"))
// 	fmt.Println(err)
// }

// func (api *API) ResizeRun(rw http.ResponseWriter, req *http.Request) {
// 	if req.FormValue("container") != "" {
// 		api.ResizeExec(rw, req)
// 		return
// 	}
// 	h, _ := strconv.Atoi(req.FormValue("h"))
// 	w, _ := strconv.Atoi(req.FormValue("w"))
// 	if h == 0 || w == 0 {
// 		return
// 	}
// 	err := docker.ResizeContainerTTY("exec1", h, w)
// 	fmt.Println(err)
// }

// proxy an exec request to docker. This allows us to have the same
// exec power but with added security.
func (api *API) Exec(rw http.ResponseWriter, req *http.Request) {
	execWait.Add(1)
	util.Lock()
	defer execWait.Done()
	defer util.Unlock()
	name := req.FormValue("container")
	// if name == "" {
	// 	name = "dev1"
	// }

	conn, br, err := rw.(http.Hijacker).Hijack()
	if err != nil {
		config.Log.Debug("exec hijack error: %s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		rw.Write([]byte(err.Error()))
		return
	}
	defer conn.Close()

	cmd := []string{"/bin/bash"}
	if additionalCmd := req.FormValue("cmd"); additionalCmd != "" {
		cmd = append(cmd, "-c", additionalCmd)
	}

	container, err := docker.GetContainer(name)
	if err != nil {
		config.Log.Debug("exec get container: %s", err.Error())
		conn.Write([]byte(err.Error()))
		return
	}

	// Flush the options to make sure the client sets the raw mode
	conn.Write([]byte{})

	exec, err := docker.CreateExec(container.ID, cmd, true, true, true)
	if err == nil {
		pid := req.FormValue("pid")
		execKeys[pid] = exec.ID
		defer delete(execKeys, pid)
		docker.RunExec(exec, io.MultiReader(br, conn), conn, conn)
	}
}

// necessary for anything using a windowing system through the exec.
func (api *API) ResizeExec(rw http.ResponseWriter, req *http.Request) {
	pid := req.FormValue("pid")
	if execKeys[pid] == "" {
		time.Sleep(1 * time.Second)
	}
	if pid == "" || execKeys[pid] == "" {
		rw.WriteHeader(http.StatusNotFound)
		return
	}

	h, _ := strconv.Atoi(req.FormValue("h"))
	w, _ := strconv.Atoi(req.FormValue("w"))
	if h == 0 || w == 0 {
		return
	}

	err := docker.ResizeExecTTY(execKeys[pid], h, w)
	fmt.Println(err)
}
<commit_msg>do the touching in the background<commit_after>// Copyright (c) 2014 Pagoda Box Inc.
//
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.

package api

import (
	"fmt"
	"io"
	"net/http"
	"strconv"
	"sync"
	"time"

	"github.com/nanobox-io/nanobox-server/config"
	"github.com/nanobox-io/nanobox-server/util"
	"github.com/nanobox-io/nanobox-server/util/docker"
	"github.com/nanobox-io/nanobox-server/util/fs"
)

var execWait = sync.WaitGroup{}

var execKeys = map[string]string{}

func (api *API) LibDirs(rw http.ResponseWriter, req *http.Request) {
	writeBody(fs.LibDirs(), rw, http.StatusOK)
}

func (api *API) FileChange(rw http.ResponseWriter, req *http.Request) {
	file := req.FormValue("filename")
	go func(file string) {
		<- time.After(time.Second)
		fs.Touch(file)
	}(file)
	writeBody(nil, rw, http.StatusOK)
}

// func (api *API) KillRun(rw http.ResponseWriter, req *http.Request) {
// 	fmt.Printf("signal recieved: %s\n", req.FormValue("signal"))
// 	err := docker.KillContainer("exec1", req.FormValue("signal"))
// 	fmt.Println(err)
// }

// func (api *API) ResizeRun(rw http.ResponseWriter, req *http.Request) {
// 	if req.FormValue("container") != "" {
// 		api.ResizeExec(rw, req)
// 		return
// 	}
// 	h, _ := strconv.Atoi(req.FormValue("h"))
// 	w, _ := strconv.Atoi(req.FormValue("w"))
// 	if h == 0 || w == 0 {
// 		return
// 	}
// 	err := docker.ResizeContainerTTY("exec1", h, w)
// 	fmt.Println(err)
// }

// proxy an exec request to docker. This allows us to have the same
// exec power but with added security.
func (api *API) Exec(rw http.ResponseWriter, req *http.Request) {
	execWait.Add(1)
	util.Lock()
	defer execWait.Done()
	defer util.Unlock()
	name := req.FormValue("container")
	// if name == "" {
	// 	name = "dev1"
	// }

	conn, br, err := rw.(http.Hijacker).Hijack()
	if err != nil {
		config.Log.Debug("exec hijack error: %s", err.Error())
		rw.WriteHeader(http.StatusInternalServerError)
		rw.Write([]byte(err.Error()))
		return
	}
	defer conn.Close()

	cmd := []string{"/bin/bash"}
	if additionalCmd := req.FormValue("cmd"); additionalCmd != "" {
		cmd = append(cmd, "-c", additionalCmd)
	}

	container, err := docker.GetContainer(name)
	if err != nil {
		config.Log.Debug("exec get container: %s", err.Error())
		conn.Write([]byte(err.Error()))
		return
	}

	// Flush the options to make sure the client sets the raw mode
	conn.Write([]byte{})

	exec, err := docker.CreateExec(container.ID, cmd, true, true, true)
	if err == nil {
		pid := req.FormValue("pid")
		execKeys[pid] = exec.ID
		defer delete(execKeys, pid)
		docker.RunExec(exec, io.MultiReader(br, conn), conn, conn)
	}
}

// necessary for anything using a windowing system through the exec.
func (api *API) ResizeExec(rw http.ResponseWriter, req *http.Request) {
	pid := req.FormValue("pid")
	if execKeys[pid] == "" {
		time.Sleep(1 * time.Second)
	}
	if pid == "" || execKeys[pid] == "" {
		rw.WriteHeader(http.StatusNotFound)
		return
	}

	h, _ := strconv.Atoi(req.FormValue("h"))
	w, _ := strconv.Atoi(req.FormValue("w"))
	if h == 0 || w == 0 {
		return
	}

	err := docker.ResizeExecTTY(execKeys[pid], h, w)
	fmt.Println(err)
}
<|endoftext|>


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

package ebiten_test

import (
	. "."
	"image"
	"image/color"
	_ "image/png"
	"os"
	"testing"
)

func openImage(path string) (*Image, image.Image, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, nil, err
	}
	defer file.Close()

	img, _, err := image.Decode(file)
	if err != nil {
		return nil, nil, err
	}

	eimg, err := NewImageFromImage(img, FilterNearest)
	if err != nil {
		return nil, nil, err
	}
	return eimg, img, nil
}

func diff(x, y uint8) uint8 {
	if x <= y {
		return y - x
	}
	return x - y
}

func TestImagePixels(t *testing.T) {
	eimg, img, err := openImage("testdata/ebiten.png")
	if err != nil {
		t.Fatal(err)
		return
	}

	if got := eimg.Bounds().Size(); got != img.Bounds().Size() {
		t.Errorf("img size: got %d; want %d", got, img.Bounds().Size())
	}

	for j := 0; j < eimg.Bounds().Size().Y; j++ {
		for i := 0; i < eimg.Bounds().Size().X; i++ {
			got := eimg.At(i, j)
			want := color.RGBAModel.Convert(img.At(i, j))
			if got != want {
				t.Errorf("img At(%d, %d): got %#v; want %#v", i, j, got, want)
			}
		}
	}
}

func TestImageComposition(t *testing.T) {
	img2Color := color.NRGBA{0x24, 0x3f, 0x6a, 0x88}
	img3Color := color.NRGBA{0x85, 0xa3, 0x08, 0xd3}

	img1, _, err := openImage("testdata/ebiten.png")
	if err != nil {
		t.Fatal(err)
		return
	}

	w, h := img1.Bounds().Size().X, img1.Bounds().Size().Y

	img2, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}

	img3, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}

	img2.Fill(img2Color)
	img3.Fill(img3Color)
	img_12_3, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}
	img2.DrawImage(img1, nil)
	img3.DrawImage(img2, nil)
	img_12_3.DrawImage(img3, nil)

	img2.Fill(img2Color)
	img3.Fill(img3Color)
	img_1_23, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}
	img3.DrawImage(img2, nil)
	img3.DrawImage(img1, nil)
	img_1_23.DrawImage(img3, nil)

	for j := 0; j < h; j++ {
		for i := 0; i < w; i++ {
			c1 := img_12_3.At(i, j).(color.RGBA)
			c2 := img_1_23.At(i, j).(color.RGBA)
			if 1 < diff(c1.R, c2.R) || 1 < diff(c1.G, c2.G) || 1 < diff(c1.B, c2.B) || 1 < diff(c1.A, c2.A) {
				t.Errorf("img_12_3.At(%d, %d) = %#v; img_1_23.At(%[1]d, %[2]d) = %#[4]v", i, j, c1, c2)
			}
			if c1.A == 0 {
				t.Fatalf("img_12_3.At(%d, %d).A = 0; nothing is rendered?", i, j)
			}
			if c2.A == 0 {
				t.Fatalf("img_1_23.At(%d, %d).A = 0; nothing is rendered?", i, j)
			}
		}
	}
}

func TestImageSelf(t *testing.T) {
	img, _, err := openImage("testdata/ebiten.png")
	if err != nil {
		t.Fatal(err)
		return
	}
	if err := img.DrawImage(img, nil); err == nil {
		t.Fatalf("img.DrawImage(img, nil) doesn't return error; an error should be return")
	}
}

// TODO: Add more tests (e.g. DrawImage with color matrix)
<commit_msg>Fix spelling miss<commit_after>// Copyright 2014 Hajime Hoshi
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ebiten_test

import (
	. "."
	"image"
	"image/color"
	_ "image/png"
	"os"
	"testing"
)

func openImage(path string) (*Image, image.Image, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, nil, err
	}
	defer file.Close()

	img, _, err := image.Decode(file)
	if err != nil {
		return nil, nil, err
	}

	eimg, err := NewImageFromImage(img, FilterNearest)
	if err != nil {
		return nil, nil, err
	}
	return eimg, img, nil
}

func diff(x, y uint8) uint8 {
	if x <= y {
		return y - x
	}
	return x - y
}

func TestImagePixels(t *testing.T) {
	eimg, img, err := openImage("testdata/ebiten.png")
	if err != nil {
		t.Fatal(err)
		return
	}

	if got := eimg.Bounds().Size(); got != img.Bounds().Size() {
		t.Errorf("img size: got %d; want %d", got, img.Bounds().Size())
	}

	for j := 0; j < eimg.Bounds().Size().Y; j++ {
		for i := 0; i < eimg.Bounds().Size().X; i++ {
			got := eimg.At(i, j)
			want := color.RGBAModel.Convert(img.At(i, j))
			if got != want {
				t.Errorf("img At(%d, %d): got %#v; want %#v", i, j, got, want)
			}
		}
	}
}

func TestImageComposition(t *testing.T) {
	img2Color := color.NRGBA{0x24, 0x3f, 0x6a, 0x88}
	img3Color := color.NRGBA{0x85, 0xa3, 0x08, 0xd3}

	img1, _, err := openImage("testdata/ebiten.png")
	if err != nil {
		t.Fatal(err)
		return
	}

	w, h := img1.Bounds().Size().X, img1.Bounds().Size().Y

	img2, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}

	img3, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}

	img2.Fill(img2Color)
	img3.Fill(img3Color)
	img_12_3, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}
	img2.DrawImage(img1, nil)
	img3.DrawImage(img2, nil)
	img_12_3.DrawImage(img3, nil)

	img2.Fill(img2Color)
	img3.Fill(img3Color)
	img_1_23, err := NewImage(w, h, FilterNearest)
	if err != nil {
		t.Fatal(err)
		return
	}
	img3.DrawImage(img2, nil)
	img3.DrawImage(img1, nil)
	img_1_23.DrawImage(img3, nil)

	for j := 0; j < h; j++ {
		for i := 0; i < w; i++ {
			c1 := img_12_3.At(i, j).(color.RGBA)
			c2 := img_1_23.At(i, j).(color.RGBA)
			if 1 < diff(c1.R, c2.R) || 1 < diff(c1.G, c2.G) || 1 < diff(c1.B, c2.B) || 1 < diff(c1.A, c2.A) {
				t.Errorf("img_12_3.At(%d, %d) = %#v; img_1_23.At(%[1]d, %[2]d) = %#[4]v", i, j, c1, c2)
			}
			if c1.A == 0 {
				t.Fatalf("img_12_3.At(%d, %d).A = 0; nothing is rendered?", i, j)
			}
			if c2.A == 0 {
				t.Fatalf("img_1_23.At(%d, %d).A = 0; nothing is rendered?", i, j)
			}
		}
	}
}

func TestImageSelf(t *testing.T) {
	img, _, err := openImage("testdata/ebiten.png")
	if err != nil {
		t.Fatal(err)
		return
	}
	if err := img.DrawImage(img, nil); err == nil {
		t.Fatalf("img.DrawImage(img, nil) doesn't return error; an error should be returned")
	}
}

// TODO: Add more tests (e.g. DrawImage with color matrix)
<|endoftext|>


<commit_before>package api

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

	"golang.org/x/net/context"

	"chain/errors"
	"chain/log"
)

// ErrBadInputJSON indicates the user supplied malformed JSON input,
// possibly including a datatype that doesn't match what we expected.
var ErrBadInputJSON = errors.New("api: bad input json")

// readJSON decodes a single JSON text from r into v.
// The only error it returns is ErrBadInputJSON
// (wrapped with the original error message as context).
func readJSON(r io.Reader, v interface{}) error {
	err := json.NewDecoder(r).Decode(v)
	if err != nil {
		return errors.Wrap(ErrBadInputJSON, err.Error())
	}
	return nil
}

func writeJSON(ctx context.Context, w http.ResponseWriter, status int, v interface{}) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.WriteHeader(status)

	// Make sure to render nil slices as "[]", rather than "null"
	if tv := reflect.TypeOf(v); tv.Kind() == reflect.Slice {
		if vv := reflect.ValueOf(v); vv.IsNil() {
			v = []struct{}{}
		}
	}

	err := json.NewEncoder(w).Encode(v)
	if err != nil {
		log.Error(ctx, err)
	}
}

func writeHTTPError(ctx context.Context, w http.ResponseWriter, err error) {
	info := errInfo(err)
	//metrics.Counter("status." + strconv.Itoa(info.HTTPStatus)).Add()
	//metrics.Counter("error." + info.ChainCode).Add()

	keyvals := []interface{}{
		"status", info.HTTPStatus,
		"chaincode", info.ChainCode,
		log.KeyError, err,
	}
	if info.HTTPStatus == 500 {
		keyvals = append(keyvals, log.KeyStack, errors.Stack(err))
	}
	log.Write(ctx, keyvals...)

	var v interface{} = info
	if s := errors.Detail(err); s != "" {
		v = struct {
			errorInfo
			Detail string `json:"detail"`
		}{info, s}
	}
	writeJSON(ctx, w, info.HTTPStatus, v)
}
<commit_msg>api: reduce nesting in nil slice check<commit_after>package api

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

	"golang.org/x/net/context"

	"chain/errors"
	"chain/log"
)

// ErrBadInputJSON indicates the user supplied malformed JSON input,
// possibly including a datatype that doesn't match what we expected.
var ErrBadInputJSON = errors.New("api: bad input json")

// readJSON decodes a single JSON text from r into v.
// The only error it returns is ErrBadInputJSON
// (wrapped with the original error message as context).
func readJSON(r io.Reader, v interface{}) error {
	err := json.NewDecoder(r).Decode(v)
	if err != nil {
		return errors.Wrap(ErrBadInputJSON, err.Error())
	}
	return nil
}

func writeJSON(ctx context.Context, w http.ResponseWriter, status int, v interface{}) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.WriteHeader(status)

	// Make sure to render nil slices as "[]", rather than "null"
	if reflect.TypeOf(v).Kind() == reflect.Slice && reflect.ValueOf(v).IsNil() {
		v = []struct{}{}
	}

	err := json.NewEncoder(w).Encode(v)
	if err != nil {
		log.Error(ctx, err)
	}
}

func writeHTTPError(ctx context.Context, w http.ResponseWriter, err error) {
	info := errInfo(err)
	//metrics.Counter("status." + strconv.Itoa(info.HTTPStatus)).Add()
	//metrics.Counter("error." + info.ChainCode).Add()

	keyvals := []interface{}{
		"status", info.HTTPStatus,
		"chaincode", info.ChainCode,
		log.KeyError, err,
	}
	if info.HTTPStatus == 500 {
		keyvals = append(keyvals, log.KeyStack, errors.Stack(err))
	}
	log.Write(ctx, keyvals...)

	var v interface{} = info
	if s := errors.Detail(err); s != "" {
		v = struct {
			errorInfo
			Detail string `json:"detail"`
		}{info, s}
	}
	writeJSON(ctx, w, info.HTTPStatus, v)
}
<|endoftext|>


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

package api

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

	"github.com/ajg/form"
	"github.com/tsuru/tsuru/auth"
	"github.com/tsuru/tsuru/errors"
	"github.com/tsuru/tsuru/event"
	"github.com/tsuru/tsuru/iaas"
	"github.com/tsuru/tsuru/permission"
	"gopkg.in/mgo.v2"
)

// title: machine list
// path: /iaas/machines
// method: GET
// produce: application/json
// responses:
//   200: OK
//   401: Unauthorized
func machinesList(w http.ResponseWriter, r *http.Request, token auth.Token) error {
	machines, err := iaas.ListMachines()
	if err != nil {
		return err
	}
	contexts := permission.ContextsForPermission(token, permission.PermMachineRead)
	allowedIaaS := map[string]struct{}{}
	for _, c := range contexts {
		if c.CtxType == permission.CtxGlobal {
			allowedIaaS = nil
			break
		}
		if c.CtxType == permission.CtxIaaS {
			allowedIaaS[c.Value] = struct{}{}
		}
	}
	for i := 0; allowedIaaS != nil && i < len(machines); i++ {
		if _, ok := allowedIaaS[machines[i].Iaas]; !ok {
			machines = append(machines[:i], machines[i+1:]...)
			i--
		}
	}
	w.Header().Add("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(machines)
}

// title: machine destroy
// path: /iaas/machines/{machine_id}
// method: DELETE
// responses:
//   200: OK
//   400: Invalid data
//   401: Unauthorized
//   404: Not found
func machineDestroy(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	r.ParseForm()
	machineID := r.URL.Query().Get(":machine_id")
	if machineID == "" {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: "machine id is required"}
	}
	m, err := iaas.FindMachineById(machineID)
	if err != nil {
		if err == mgo.ErrNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: "machine not found"}
		}
		return err
	}
	iaasCtx := permission.Context(permission.CtxIaaS, m.Iaas)
	allowed := permission.Check(token, permission.PermMachineDelete, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: m.Iaas},
		Kind:       permission.PermMachineDelete,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	return m.Destroy()
}

// title: machine template list
// path: /iaas/templates
// method: GET
// produce: application/json
// responses:
//   200: OK
//   401: Unauthorized
func templatesList(w http.ResponseWriter, r *http.Request, token auth.Token) error {
	templates, err := iaas.ListTemplates()
	if err != nil {
		return err
	}
	contexts := permission.ContextsForPermission(token, permission.PermMachineTemplateRead)
	allowedIaaS := map[string]struct{}{}
	for _, c := range contexts {
		if c.CtxType == permission.CtxGlobal {
			allowedIaaS = nil
			break
		}
		if c.CtxType == permission.CtxIaaS {
			allowedIaaS[c.Value] = struct{}{}
		}
	}
	for i := 0; allowedIaaS != nil && i < len(templates); i++ {
		if _, ok := allowedIaaS[templates[i].IaaSName]; !ok {
			templates = append(templates[:i], templates[i+1:]...)
			i--
		}
	}
	w.Header().Add("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(templates)
}

// title: template create
// path: /iaas/templates
// method: POST
// consume: application/x-www-form-urlencoded
// responses:
//   201: Template created
//   400: Invalid data
//   401: Unauthorized
func templateCreate(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	err = r.ParseForm()
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	var paramTemplate iaas.Template
	dec := form.NewDecoder(nil)
	dec.IgnoreUnknownKeys(true)
	err = dec.DecodeValues(&paramTemplate, r.Form)
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	iaasCtx := permission.Context(permission.CtxIaaS, paramTemplate.IaaSName)
	allowed := permission.Check(token, permission.PermMachineTemplateCreate, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: paramTemplate.IaaSName},
		Kind:       permission.PermMachineTemplateCreate,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	err = paramTemplate.Save()
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusCreated)
	return nil
}

// title: template destroy
// path: /iaas/templates/{template_name}
// method: DELETE
// responses:
//   200: OK
//   401: Unauthorized
//   404: Not found
func templateDestroy(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	r.ParseForm()
	templateName := r.URL.Query().Get(":template_name")
	t, err := iaas.FindTemplate(templateName)
	if err != nil {
		if err == mgo.ErrNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: "template not found"}
		}
		return err
	}
	iaasCtx := permission.Context(permission.CtxIaaS, t.IaaSName)
	allowed := permission.Check(token, permission.PermMachineTemplateDelete, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: t.IaaSName},
		Kind:       permission.PermMachineTemplateDelete,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	return iaas.DestroyTemplate(templateName)
}

// title: template update
// path: /iaas/templates/{template_name}
// method: PUT
// consume: application/x-www-form-urlencoded
// responses:
//   200: OK
//   400: Invalid data
//   401: Unauthorized
//   404: Not found
func templateUpdate(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	err = r.ParseForm()
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	var paramTemplate iaas.Template
	dec := form.NewDecoder(nil)
	dec.IgnoreUnknownKeys(true)
	err = dec.DecodeValues(&paramTemplate, r.Form)
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	templateName := r.URL.Query().Get(":template_name")
	dbTpl, err := iaas.FindTemplate(templateName)
	if err != nil {
		if err == mgo.ErrNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: "template not found"}
		}
		return err
	}
	iaasCtx := permission.Context(permission.CtxIaaS, dbTpl.IaaSName)
	allowed := permission.Check(token, permission.PermMachineTemplateUpdate, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: dbTpl.IaaSName},
		Kind:       permission.PermMachineTemplateUpdate,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	return dbTpl.Update(&paramTemplate)
}
<commit_msg>add iaasName<commit_after>// Copyright 2014 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package api

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

	"github.com/ajg/form"
	"github.com/tsuru/tsuru/auth"
	"github.com/tsuru/tsuru/errors"
	"github.com/tsuru/tsuru/event"
	"github.com/tsuru/tsuru/iaas"
	"github.com/tsuru/tsuru/permission"
	"gopkg.in/mgo.v2"
)

// title: machine list
// path: /iaas/machines
// method: GET
// produce: application/json
// responses:
//   200: OK
//   401: Unauthorized
func machinesList(w http.ResponseWriter, r *http.Request, token auth.Token) error {
	machines, err := iaas.ListMachines()
	if err != nil {
		return err
	}
	contexts := permission.ContextsForPermission(token, permission.PermMachineRead)
	allowedIaaS := map[string]struct{}{}
	for _, c := range contexts {
		if c.CtxType == permission.CtxGlobal {
			allowedIaaS = nil
			break
		}
		if c.CtxType == permission.CtxIaaS {
			allowedIaaS[c.Value] = struct{}{}
		}
	}
	for i := 0; allowedIaaS != nil && i < len(machines); i++ {
		if _, ok := allowedIaaS[machines[i].Iaas]; !ok {
			machines = append(machines[:i], machines[i+1:]...)
			i--
		}
	}
	w.Header().Add("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(machines)
}

// title: machine destroy
// path: /iaas/machines/{machine_id}
// method: DELETE
// responses:
//   200: OK
//   400: Invalid data
//   401: Unauthorized
//   404: Not found
func machineDestroy(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	r.ParseForm()
	machineID := r.URL.Query().Get(":machine_id")
	if machineID == "" {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: "machine id is required"}
	}
	m, err := iaas.FindMachineById(machineID)
	if err != nil {
		if err == mgo.ErrNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: "machine not found"}
		}
		return err
	}
	iaasCtx := permission.Context(permission.CtxIaaS, m.Iaas)
	allowed := permission.Check(token, permission.PermMachineDelete, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: m.Iaas},
		Kind:       permission.PermMachineDelete,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	return m.Destroy()
}

// title: machine template list
// path: /iaas/templates
// method: GET
// produce: application/json
// responses:
//   200: OK
//   401: Unauthorized
func templatesList(w http.ResponseWriter, r *http.Request, token auth.Token) error {
	templates, err := iaas.ListTemplates()
	if err != nil {
		return err
	}
	contexts := permission.ContextsForPermission(token, permission.PermMachineTemplateRead)
	allowedIaaS := map[string]struct{}{}
	for _, c := range contexts {
		if c.CtxType == permission.CtxGlobal {
			allowedIaaS = nil
			break
		}
		if c.CtxType == permission.CtxIaaS {
			allowedIaaS[c.Value] = struct{}{}
		}
	}
	for i := 0; allowedIaaS != nil && i < len(templates); i++ {
		if _, ok := allowedIaaS[templates[i].IaaSName]; !ok {
			templates = append(templates[:i], templates[i+1:]...)
			i--
		}
	}
	w.Header().Add("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(templates)
}

// title: template create
// path: /iaas/templates
// method: POST
// consume: application/x-www-form-urlencoded
// responses:
//   201: Template created
//   400: Invalid data
//   401: Unauthorized
func templateCreate(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	err = r.ParseForm()
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	var paramTemplate iaas.Template
	dec := form.NewDecoder(nil)
	dec.IgnoreUnknownKeys(true)
	err = dec.DecodeValues(&paramTemplate, r.Form)
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	iaasCtx := permission.Context(permission.CtxIaaS, paramTemplate.IaaSName)
	allowed := permission.Check(token, permission.PermMachineTemplateCreate, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: paramTemplate.IaaSName},
		Kind:       permission.PermMachineTemplateCreate,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	err = paramTemplate.Save()
	if err != nil {
		return err
	}
	w.WriteHeader(http.StatusCreated)
	return nil
}

// title: template destroy
// path: /iaas/templates/{template_name}
// method: DELETE
// responses:
//   200: OK
//   401: Unauthorized
//   404: Not found
func templateDestroy(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	r.ParseForm()
	templateName := r.URL.Query().Get(":template_name")
	t, err := iaas.FindTemplate(templateName)
	if err != nil {
		if err == mgo.ErrNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: "template not found"}
		}
		return err
	}
	iaasCtx := permission.Context(permission.CtxIaaS, t.IaaSName)
	allowed := permission.Check(token, permission.PermMachineTemplateDelete, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: t.IaaSName},
		Kind:       permission.PermMachineTemplateDelete,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	return iaas.DestroyTemplate(templateName)
}

// title: template update
// path: /iaas/templates/{template_name}
// method: PUT
// consume: application/x-www-form-urlencoded
// responses:
//   200: OK
//   400: Invalid data
//   401: Unauthorized
//   404: Not found
func templateUpdate(w http.ResponseWriter, r *http.Request, token auth.Token) (err error) {
	err = r.ParseForm()
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	var paramTemplate iaas.Template
	dec := form.NewDecoder(nil)
	dec.IgnoreUnknownKeys(true)
	err = dec.DecodeValues(&paramTemplate, r.Form)
	if err != nil {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	templateName := r.URL.Query().Get(":template_name")
	iaasName := r.URL.Query().Get(":template_iaasname")
	fmt.Println(iaasName, r.URL)
	dbTpl, err := iaas.FindTemplate(templateName)
	if err != nil {
		if err == mgo.ErrNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: "template not found"}
		}
		return err
	}
	iaasCtx := permission.Context(permission.CtxIaaS, dbTpl.IaaSName)
	allowed := permission.Check(token, permission.PermMachineTemplateUpdate, iaasCtx)
	if !allowed {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeIaas, Value: dbTpl.IaaSName},
		Kind:       permission.PermMachineTemplateUpdate,
		Owner:      token,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermMachineReadEvents, iaasCtx),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	return dbTpl.Update(&paramTemplate)
}
<|endoftext|>


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

package api

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

func info(w http.ResponseWriter, r *http.Request) error {
	data := map[string]string{}
	data["version"] = Version
	w.Header().Set("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(data)
}
<commit_msg>api/info: add comments to describe info<commit_after>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package api

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

// title: api info
// path: /info
// method: GET
// produce: application/json
// responses:
//   200: OK
func info(w http.ResponseWriter, r *http.Request) error {
	data := map[string]string{}
	data["version"] = Version
	w.Header().Set("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(data)
}
<|endoftext|>